# 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) # macOS is deferred — its arboard/AppKit link needs Apple's SDK (see ADR-ci-001). # 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. 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: 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"