ANW-32 CI: switch release.yml to the IT-86 Forgejo->GitHub pipeline

Tag-triggered (v* on the Forgejo mirror) instead of a hand-made GitHub
release. Adds an aarch64-linux leg; a single publish job creates the GitHub
release and mirrors every binary back onto the matching Forgejo release via
FORGEJO_RELEASE_TOKEN. Keeps the hurl HTTP contract harness on x86_64-linux.

Assumed v* tags are the release trigger and the contract tests run once on the
deploy target (x86_64-linux); flag if either is wrong.
This commit is contained in:
Andreas Brenner 2026-06-24 17:54:48 +03:00
parent 04a6165867
commit 408fae4154

View file

@ -1,27 +1,38 @@
# Release builds for anwesen ([ANW-29]). # Release builds for anwesen ([ANW-32], pattern from IT-86).
# #
# GitHub is a secondary remote that aav pushes to by hand; the primary home # Forgejo (carvers/anwesen on ap) is canonical for both code and releases.
# is the operator's forge. aav creates and publishes a GitHub Release in the # GitHub is only the build farm -- it has the macOS runners. Publishing is a
# UI (the release carries its own tag). This workflow reacts to that publish: # single act on Forgejo: create a `v*` tag (or release) there, it mirrors to
# for each target it runs the tests, builds the release binary, and uploads # the GitHub mirror, and that pushed tag triggers this workflow. For each
# it as a target-named asset on the triggering release. It never creates the # target the build job tests and builds the binary; a final publish job creates
# tag or the release. # the GitHub release with every binary, then mirrors them back onto the
# matching Forgejo release. No manual "new release" step on GitHub.
name: release name: release
on: on:
release: push:
types: [published] tags: ['v*']
workflow_dispatch:
inputs:
tag:
description: Existing tag to (re)build
required: true
# The build jobs attach binaries to the triggering release. # The publish job attaches binaries to the GitHub release it creates.
permissions: permissions:
contents: write contents: write
env:
# The Forgejo repo that receives the release assets (owner/name on ap).
FORGEJO_REPO: carvers/anwesen
FORGEJO_API: https://forge.crvrs.org/api/v1
jobs: jobs:
build: build:
name: ${{ matrix.label }} name: ${{ matrix.label }}
runs-on: ${{ matrix.runner }} runs-on: ${{ matrix.runner }}
strategy: strategy:
# One target's failure should not cancel the other's build. # One target's failure should not cancel the others' builds.
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
@ -29,6 +40,10 @@ jobs:
- runner: ubuntu-latest - runner: ubuntu-latest
label: x86_64-linux label: x86_64-linux
os: linux os: linux
# arm64 Linux -- Graviton / Pi / ARM servers. Built natively.
- runner: ubuntu-24.04-arm
label: aarch64-linux
os: linux
# arm macOS -- aav's local machine. Built natively on Apple Silicon. # arm macOS -- aav's local machine. Built natively on Apple Silicon.
- runner: macos-14 - runner: macos-14
label: aarch64-macos label: aarch64-macos
@ -37,7 +52,7 @@ jobs:
- name: Check out the release tag - name: Check out the release tag
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
ref: ${{ github.event.release.tag_name }} ref: ${{ github.event.inputs.tag || github.ref_name }}
# Stable channel; edition 2024 needs >= 1.85, and Cargo.toml pins the # Stable channel; edition 2024 needs >= 1.85, and Cargo.toml pins the
# MSRV at 1.95. Pin an explicit version here if a frozen release # MSRV at 1.95. Pin an explicit version here if a frozen release
@ -49,13 +64,12 @@ jobs:
uses: Swatinem/rust-cache@v2 uses: Swatinem/rust-cache@v2
# The HTTP contract harness (tests/run-hurl.sh, per ADR-008) boots # The HTTP contract harness (tests/run-hurl.sh, per ADR-008) boots
# `anwesen serve` and runs hurl against it -- headless, so it runs in CI. # `anwesen serve` and runs hurl against it. The contract is
# The HTTP contract is arch-independent, so it runs once on Linux; the # arch-independent, so it runs once on the deploy target; the macOS
# macOS runner's stock bash is 3.2 and the harness needs bash 4+ # runner's stock bash is 3.2 and the harness needs bash 4+
# (`shopt -s globstar`), which would only add fragility for no extra # (`shopt -s globstar`), which would only add fragility for no coverage.
# coverage.
- name: Install hurl - name: Install hurl
if: matrix.os == 'linux' if: matrix.label == 'x86_64-linux'
run: | run: |
curl -fsSL -o /tmp/hurl.deb \ curl -fsSL -o /tmp/hurl.deb \
https://github.com/Orange-OpenSource/hurl/releases/download/8.0.0/hurl_8.0.0_amd64.deb https://github.com/Orange-OpenSource/hurl/releases/download/8.0.0/hurl_8.0.0_amd64.deb
@ -67,7 +81,7 @@ jobs:
run: cargo test --locked run: cargo test --locked
- name: Run the HTTP contract tests - name: Run the HTTP contract tests
if: matrix.os == 'linux' if: matrix.label == 'x86_64-linux'
run: tests/run-hurl.sh run: tests/run-hurl.sh
- name: Build the release binary - name: Build the release binary
@ -78,9 +92,53 @@ jobs:
- name: Name the asset for its target - name: Name the asset for its target
run: | run: |
install -m 0755 target/release/anwesen \ install -m 0755 target/release/anwesen \
"anwesen-${{ github.event.release.tag_name }}-${{ matrix.label }}" "anwesen-${{ github.event.inputs.tag || github.ref_name }}-${{ matrix.label }}"
- name: Upload the binary to the release - name: Stash the binary for the publish job
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.label }}
path: anwesen-*-${{ matrix.label }}
if-no-files-found: error
publish:
needs: build
runs-on: ubuntu-latest
steps:
- name: Collect every target's binary
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: Create the GitHub release with all binaries
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v2
with: with:
files: anwesen-${{ github.event.release.tag_name }}-${{ matrix.label }} tag_name: ${{ github.event.inputs.tag || github.ref_name }}
files: dist/*
# Forgejo is canonical: push the same binaries onto the matching Forgejo
# release. Find the release by tag; create it if the tag has no release
# object yet; then upload each binary as an asset.
- name: Mirror binaries to the Forgejo release
env:
TAG: ${{ github.event.inputs.tag || github.ref_name }}
TOKEN: ${{ secrets.FORGEJO_RELEASE_TOKEN }}
run: |
set -euo pipefail
auth="Authorization: token $TOKEN"
base="$FORGEJO_API/repos/$FORGEJO_REPO/releases"
id=$(curl -fsS -H "$auth" "$base/tags/$TAG" | jq -r '.id // empty')
if [ -z "$id" ]; then
id=$(curl -fsS -H "$auth" -H 'Content-Type: application/json' \
-X POST "$base" \
-d "{\"tag_name\":\"$TAG\",\"name\":\"$TAG\"}" | jq -r '.id')
fi
for f in dist/*; do
curl -fsS -H "$auth" \
-F "attachment=@$f;filename=$(basename "$f")" \
"$base/$id/assets?name=$(basename "$f")" >/dev/null
echo "uploaded $(basename "$f")"
done