diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml index a27acea..5748373 100644 --- a/.forgejo/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -29,7 +29,7 @@ jobs: runs-on: docker timeout-minutes: 120 steps: - - name: Checkout + - name: Checkout the source tag uses: https://code.forgejo.org/actions/checkout@v4 with: # A tag push builds that tag; a manual dispatch builds the tag the @@ -37,6 +37,15 @@ jobs: # release it is attached to). ref: ${{ github.event.inputs.tag || github.ref_name }} + - name: Checkout the CI tooling + uses: https://code.forgejo.org/actions/checkout@v4 + with: + # scripts/ and .forgejo/ only exist on the branch (older tags predate + # them), and the workflow itself is read from the dispatched ref — so + # fetch the same ref into .ci-tools and run the scripts from there. + ref: ${{ github.ref_name }} + path: .ci-tools + - name: Build ${{ env.TARGET }} in a rust container run: | set -euo pipefail @@ -62,7 +71,8 @@ jobs: && cargo build --release --locked \ && strip /target/release/onionwire \ && ls -l /target/release/onionwire' - tar czf - --exclude=./target --exclude=./.git --exclude=./.worktrees . \ + tar czf - --exclude=./target --exclude=./.git --exclude=./.worktrees \ + --exclude=./.ci-tools . \ | docker start -a -i "$BUILD_CONTAINER" mkdir -p dist docker cp "$BUILD_CONTAINER:/target/release/onionwire" "dist/onionwire-$TARGET" @@ -80,16 +90,19 @@ jobs: - name: Publish to the Forgejo release env: FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }} - TARGET_COMMITISH: ${{ github.sha }} REPO_API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }} + EVENT_NAME: ${{ github.event_name }} + EVENT_SHA: ${{ github.sha }} REF: ${{ github.ref_name }} INPUT_TAG: ${{ github.event.inputs.tag }} run: | set -euo pipefail cd "${GITHUB_WORKSPACE}" tag="${INPUT_TAG:-$REF}" - echo "publishing $tag from $REPO_API" - scripts/publish-release.sh \ + # Only a tag push may create the tag; a re-publish must not move it. + if [ "$EVENT_NAME" = "push" ]; then export TARGET_COMMITISH="$EVENT_SHA"; fi + echo "publishing $tag from $REPO_API (event=$EVENT_NAME)" + .ci-tools/scripts/publish-release.sh \ "$tag" "OnionWire $tag" \ - scripts/release-body.md \ + .ci-tools/scripts/release-body.md \ "dist/onionwire-$TARGET" "dist/onionwire-$TARGET.sha256" diff --git a/scripts/publish-release.sh b/scripts/publish-release.sh index 60486c4..23d8cdc 100755 --- a/scripts/publish-release.sh +++ b/scripts/publish-release.sh @@ -4,7 +4,9 @@ # Usage: publish-release.sh [...] # Env: FORGEJO_TOKEN user PAT with repo write (required) # REPO_API default https://forgejo.siriusdevops.com/api/v1/repos/sirius/onionwire -# TARGET_COMMITISH default: push-triggered commit (CI) else "main" +# TARGET_COMMITISH optional; set it only when the release may have to +# create the tag (e.g. a push event's commit sha). +# Leave empty to never move an existing tag. # # Idempotent: re-running for the same tag reuses the release and replaces # same-named assets instead of failing with 409. @@ -17,7 +19,7 @@ shift 3 : "${FORGEJO_TOKEN:?FORGEJO_TOKEN is not set}" api="${REPO_API:-https://forgejo.siriusdevops.com/api/v1/repos/sirius/onionwire}" -target="${TARGET_COMMITISH:-main}" +target="${TARGET_COMMITISH:-}" jqp() { python3 -c "import json,sys; d=json.load(sys.stdin); print($1)"; } @@ -25,14 +27,18 @@ jqp() { python3 -c "import json,sys; d=json.load(sys.stdin); print($1)"; } python3 - "$body_file" "$tag" "$target" "$name" > /tmp/release-body.json <<'PY' import json, sys body = open(sys.argv[1]).read().replace("@TAG@", sys.argv[2]) -print(json.dumps({ +payload = { "tag_name": sys.argv[2], - "target_commitish": sys.argv[3], "name": sys.argv[4], "body": body, "draft": False, "prerelease": False, -})) +} +# Only send target_commitish when asked: on an existing tag it is a request to +# move the tag, which is never what a re-publish wants. +if sys.argv[3]: + payload["target_commitish"] = sys.argv[3] +print(json.dumps(payload)) PY code=$(curl -s -o /tmp/release-rel.json -w '%{http_code}' \