Files
rdbms-playground/.gitea/workflows/release.yaml
T
claude@clouddev1 bd5be5ecc7
ci / gate (push) Successful in 3m12s
release / test (push) Successful in 2m44s
release / build (aarch64-pc-windows-gnullvm) (push) Successful in 3m56s
release / build (aarch64-unknown-linux-musl) (push) Successful in 4m18s
release / build (x86_64-pc-windows-gnu) (push) Successful in 4m39s
release / build (x86_64-unknown-linux-musl) (push) Successful in 3m50s
fix(ci): read release version from Cargo.toml, not cargo metadata (ADR-0054)
The ADR-0054 version guard piped `nix develop -c cargo metadata` to node,
but the flake devShell prints a banner to stdout — corrupting the JSON
pipe, so the guard aborted under `set -e` and the v0.2.0 release failed
there (before building anything). Replace it with a toolchain-free
`grep -m1 '^version = ' Cargo.toml` (the anchor excludes dependency
`version =` keys). No real version mismatch occurred — the tagged commit
has version 0.2.0.
2026-06-17 21:58:32 +00:00

118 lines
4.9 KiB
YAML

# Release: on a version tag, build the cross-platform binaries and publish them
# to a Gitea release with checksums. Runs in the prebuilt CI image, so the
# pinned toolchain + the release targets + cargo-zigbuild/zig are already warm.
#
# Matrix (D1, cross-built from Linux x86_64 via cargo-zigbuild):
# x86_64-unknown-linux-musl aarch64-unknown-linux-musl (static, D2)
# x86_64-pc-windows-gnu aarch64-pc-windows-gnullvm (standalone .exe)
# The two macOS targets are built separately by the dispatched
# release-macos.yaml (native Tart runner; ADR-ci-003 amendment), uploading to
# the same release. D3 package-manager manifests layer on later.
#
# Tests run once (host) before the matrix, so a tag can never publish untested
# code, even one pointing at a commit that was never gated on a branch. The
# version guard (ADR-0054) refuses to publish a tag whose vX.Y.Z disagrees with
# Cargo.toml's version, keeping `--version`, the release name, and the asset in
# lockstep.
name: release
on:
push:
tags:
- 'v*'
jobs:
test:
runs-on: ci-public
container:
image: git.lazyeval.net/oli/rdbms-playground-ci:latest
steps:
- uses: actions/checkout@v4
- name: version guard — tag must equal Cargo.toml version (ADR-0054)
shell: bash
env:
TAG: ${{ github.ref_name }}
run: |
set -euo pipefail
# Read the [package] version straight from Cargo.toml — toolchain-free
# and robust. (An earlier `nix develop -c cargo metadata | node` version
# broke: the flake devShell prints a banner to stdout, corrupting the
# JSON pipe.) `^version = ` is anchored, so it matches only the package
# version, never the `version = ` inside dependency inline tables.
VER=$(grep -m1 '^version = ' Cargo.toml | sed -E 's/^version = "(.*)"/\1/')
echo "tag=$TAG cargo=v$VER"
if [ -z "$VER" ]; then
echo "ERROR: could not read the package version from Cargo.toml" >&2
exit 1
fi
if [ "$TAG" != "v$VER" ]; then
echo "ERROR: release tag '$TAG' != 'v$VER' (Cargo.toml). Bump Cargo.toml to the release version, commit, then retag (ADR-0054)." >&2
exit 1
fi
- name: test
run: nix develop -c cargo test --no-fail-fast
build:
needs: test
runs-on: ci-public
container:
image: git.lazyeval.net/oli/rdbms-playground-ci:latest
strategy:
fail-fast: false
matrix:
target:
- x86_64-unknown-linux-musl
- aarch64-unknown-linux-musl
- x86_64-pc-windows-gnu
- aarch64-pc-windows-gnullvm
steps:
- uses: actions/checkout@v4
- name: build
run: nix develop -c cargo zigbuild --release --target ${{ matrix.target }}
- name: package + publish
# Pin bash: the runner defaults scripted steps to dash, which rejects
# `set -o pipefail`. bash is in the CI image.
shell: bash
env:
TARGET: ${{ matrix.target }}
# GITEA_TOKEN is auto-provided with repo write (release) scope.
TOKEN: ${{ secrets.GITEA_TOKEN }}
API: ${{ github.server_url }}/api/v1
REPO: ${{ github.repository }}
TAG: ${{ github.ref_name }}
run: |
set -euo pipefail
# Windows targets produce a .exe; the rest a bare binary.
case "$TARGET" in *windows*) EXT=.exe ;; *) EXT= ;; esac
BIN="target/$TARGET/release/rdbms-playground$EXT"
OUT="rdbms-playground-$TAG-$TARGET$EXT"
mkdir -p dist
cp "$BIN" "dist/$OUT"
( cd dist && sha256sum "$OUT" > "$OUT.sha256" )
ls -l dist
# Create the release for this tag; if a sibling matrix job already
# created it, look it up instead (idempotent + race-tolerant).
created=$(curl -sS -X POST "$API/repos/$REPO/releases" \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"tag_name\":\"$TAG\",\"name\":\"$TAG\",\"body\":\"Automated release for $TAG.\"}")
id=$(printf '%s' "$created" | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{try{const o=JSON.parse(s);process.stdout.write(String(o.id||""))}catch(e){}})')
if [ -z "$id" ]; then
id=$(curl -sS "$API/repos/$REPO/releases/tags/$TAG" \
-H "Authorization: token $TOKEN" \
| node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{process.stdout.write(String(JSON.parse(s).id))})')
fi
echo "release id: $id"
for f in dist/*; do
name=$(basename "$f")
echo "uploading $name"
curl -sS -X POST "$API/repos/$REPO/releases/$id/assets?name=$name" \
-H "Authorization: token $TOKEN" \
-F "attachment=@$f" > /dev/null
done
echo "published $TARGET assets for $TAG"