From 8858336ecc57040ced9b2600ae3a712199be170b Mon Sep 17 00:00:00 2001 From: Bendik Aagaard Lynghaug Date: Mon, 24 Aug 2026 21:44:31 +0200 Subject: [PATCH] Semver releases cut with cargo-release; publish on v* tags only cargo release bumps, tags v, and pushes; publish.yml reacts to the tag and attaches the artifact to that release. Plain main pushes now run tests (test.yml) instead of publishing build- artifacts on every push. Co-Authored-By: Claude Fable 5 --- .gitea/workflows/{deploy.yml => publish.yml} | 35 +++++++++++--------- .gitea/workflows/test.yml | 26 +++++++++++++++ Cargo.toml | 9 +++++ 3 files changed, 54 insertions(+), 16 deletions(-) rename .gitea/workflows/{deploy.yml => publish.yml} (78%) create mode 100644 .gitea/workflows/test.yml diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/publish.yml similarity index 78% rename from .gitea/workflows/deploy.yml rename to .gitea/workflows/publish.yml index 26d1978..199d962 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/publish.yml @@ -1,14 +1,16 @@ name: Publish release -# Portal no longer deploys itself. Each content repo (uhhm/questions, -# redoal/questions) owns its instance - domain, port, env, Caddy route - -# and its deploy workflow downloads a pinned release published here. -# Rolling a new portal version out to a site = bumping PORTAL_RELEASE -# in that site's .gitea/workflows/deploy.yml (an auditable commit). +# Portal does not deploy itself. Cutting a version is deliberate: +# `cargo release ` bumps Cargo.toml, commits, tags v, +# and pushes; this workflow reacts to the tag and publishes the +# artifact as a Gitea release. Each content repo (uhhm/questions, +# redoal/questions) pins PORTAL_RELEASE to one of these tags in its +# own deploy workflow - bumping the pin there is what rolls a version +# out to a site. Plain main pushes only run test.yml. on: push: - branches: [main] + tags: ["v*"] jobs: publish: @@ -62,8 +64,7 @@ jobs: - name: Package run: | set -euo pipefail - tag="build-$(echo ${{ github.sha }} | cut -c1-7)" - echo "TAG=$tag" >> "$GITHUB_ENV" + tag="${{ github.ref_name }}" stage=$(mktemp -d) cp "$CARGO_TARGET_DIR/release/portal" "$stage/portal" cp "$CARGO_TARGET_DIR/release/question_lint" "$stage/question_lint" @@ -75,24 +76,26 @@ jobs: rm -rf "$stage" # The run's own ephemeral token has write access to this repo - - # no long-lived PAT to manage. Re-running a build for the same sha - # finds the existing release instead of failing on the tag. + # no long-lived PAT to manage. The tag already exists (cargo + # release pushed it), so the release attaches to it; a re-run + # finds the existing release instead of failing. - name: Publish release run: | set -euo pipefail + tag="${{ github.ref_name }}" api="${{ github.server_url }}/api/v1/repos/${{ github.repository }}" auth="Authorization: token ${{ secrets.GITHUB_TOKEN }}" subject=$(git log -1 --format=%s) - body=$(printf '{"tag_name":"%s","target_commitish":"%s","name":"%s"}' \ - "$TAG" "${{ github.sha }}" "$TAG: $(echo "$subject" | sed 's/"/\\"/g')") + body=$(printf '{"tag_name":"%s","name":"%s"}' \ + "$tag" "$tag: $(echo "$subject" | sed 's/"/\\"/g')") id=$(curl -sf -X POST -H "$auth" -H 'Content-Type: application/json' \ -d "$body" "$api/releases" | jq .id) \ - || id=$(curl -sf -H "$auth" "$api/releases/tags/$TAG" | jq .id) + || id=$(curl -sf -H "$auth" "$api/releases/tags/$tag" | jq .id) # Replace the asset if a re-run already uploaded one. for aid in $(curl -sf -H "$auth" "$api/releases/$id/assets" | jq '.[].id'); do curl -sf -X DELETE -H "$auth" "$api/releases/$id/assets/$aid" done curl -sf -X POST -H "$auth" \ - -F "attachment=@portal-$TAG.tar.gz" \ - "$api/releases/$id/assets?name=portal-$TAG.tar.gz" > /dev/null - echo "published $TAG" + -F "attachment=@portal-$tag.tar.gz" \ + "$api/releases/$id/assets?name=portal-$tag.tar.gz" > /dev/null + echo "published $tag" diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml new file mode 100644 index 0000000..ca389d8 --- /dev/null +++ b/.gitea/workflows/test.yml @@ -0,0 +1,26 @@ +name: Test + +# Publishing only happens on v* tags (publish.yml), so this is what +# keeps plain main pushes honest between releases. + +on: + push: + branches: [main] + pull_request: + +jobs: + test: + runs-on: bare + env: + # Same shared-toolchain/cache story as publish.yml. + CARGO_HOME: /var/local/cargo + RUSTUP_HOME: /var/local/rustup + PATH: /var/local/cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/bin + SCCACHE_DIR: /var/local/sccache + SCCACHE_SERVER_PORT: "4228" + CARGO_TARGET_DIR: /var/local/cargo-target + steps: + - uses: actions/checkout@v4 + + - name: Test + run: cargo test --features ssr diff --git a/Cargo.toml b/Cargo.toml index 6e0090f..a7a4a04 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -131,3 +131,12 @@ bin-default-features = false lib-features = ["hydrate"] lib-default-features = false lib-profile-release = "wasm-release" + +# cargo release is how a portal version is cut: bump, commit, +# tag v{{version}}, push. CI (publish.yml) reacts to the tag and +# publishes the release artifact; nothing on crates.io. +[package.metadata.release] +publish = false +push = true +tag-name = "v{{version}}" +pre-release-commit-message = "Release {{version}}"