fix(release): tooling checkout so old tags can publish; never move a tag
The dispatched build of v0.1.1 kept failing at publish with 'scripts/publish-release.sh: No such file or directory' — the workflow is read from the dispatch ref (main) but the workspace was the v0.1.1 tag, whose tree predates scripts/ and .forgejo/. - second checkout of the workflow's own ref into .ci-tools; publish runs .ci-tools/scripts/publish-release.sh (and .ci-tools/scripts/release-body.md) - exclude ./.ci-tools from the build context tar - target_commitish is now opt-in in publish-release.sh and only set for a push event, so a re-publish can never move an existing tag Verified locally end-to-end against a throwaway tag: create, idempotent re-run (stale assets deleted + replaced), public download, sha256sum -c, --version. Test release and tag deleted afterwards.
This commit is contained in:
parent
154bed7823
commit
9441bccf58
2 changed files with 30 additions and 11 deletions
|
|
@ -29,7 +29,7 @@ jobs:
|
||||||
runs-on: docker
|
runs-on: docker
|
||||||
timeout-minutes: 120
|
timeout-minutes: 120
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout the source tag
|
||||||
uses: https://code.forgejo.org/actions/checkout@v4
|
uses: https://code.forgejo.org/actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
# A tag push builds that tag; a manual dispatch builds the tag the
|
# A tag push builds that tag; a manual dispatch builds the tag the
|
||||||
|
|
@ -37,6 +37,15 @@ jobs:
|
||||||
# release it is attached to).
|
# release it is attached to).
|
||||||
ref: ${{ github.event.inputs.tag || github.ref_name }}
|
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
|
- name: Build ${{ env.TARGET }} in a rust container
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
@ -62,7 +71,8 @@ jobs:
|
||||||
&& cargo build --release --locked \
|
&& cargo build --release --locked \
|
||||||
&& strip /target/release/onionwire \
|
&& strip /target/release/onionwire \
|
||||||
&& ls -l /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"
|
| docker start -a -i "$BUILD_CONTAINER"
|
||||||
mkdir -p dist
|
mkdir -p dist
|
||||||
docker cp "$BUILD_CONTAINER:/target/release/onionwire" "dist/onionwire-$TARGET"
|
docker cp "$BUILD_CONTAINER:/target/release/onionwire" "dist/onionwire-$TARGET"
|
||||||
|
|
@ -80,16 +90,19 @@ jobs:
|
||||||
- name: Publish to the Forgejo release
|
- name: Publish to the Forgejo release
|
||||||
env:
|
env:
|
||||||
FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }}
|
FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }}
|
||||||
TARGET_COMMITISH: ${{ github.sha }}
|
|
||||||
REPO_API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
REPO_API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||||
|
EVENT_NAME: ${{ github.event_name }}
|
||||||
|
EVENT_SHA: ${{ github.sha }}
|
||||||
REF: ${{ github.ref_name }}
|
REF: ${{ github.ref_name }}
|
||||||
INPUT_TAG: ${{ github.event.inputs.tag }}
|
INPUT_TAG: ${{ github.event.inputs.tag }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cd "${GITHUB_WORKSPACE}"
|
cd "${GITHUB_WORKSPACE}"
|
||||||
tag="${INPUT_TAG:-$REF}"
|
tag="${INPUT_TAG:-$REF}"
|
||||||
echo "publishing $tag from $REPO_API"
|
# Only a tag push may create the tag; a re-publish must not move it.
|
||||||
scripts/publish-release.sh \
|
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" \
|
"$tag" "OnionWire $tag" \
|
||||||
scripts/release-body.md \
|
.ci-tools/scripts/release-body.md \
|
||||||
"dist/onionwire-$TARGET" "dist/onionwire-$TARGET.sha256"
|
"dist/onionwire-$TARGET" "dist/onionwire-$TARGET.sha256"
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@
|
||||||
# Usage: publish-release.sh <tag> <release-name> <body-file> <asset> [<asset>...]
|
# Usage: publish-release.sh <tag> <release-name> <body-file> <asset> [<asset>...]
|
||||||
# Env: FORGEJO_TOKEN user PAT with repo write (required)
|
# Env: FORGEJO_TOKEN user PAT with repo write (required)
|
||||||
# REPO_API default https://forgejo.siriusdevops.com/api/v1/repos/sirius/onionwire
|
# 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
|
# Idempotent: re-running for the same tag reuses the release and replaces
|
||||||
# same-named assets instead of failing with 409.
|
# same-named assets instead of failing with 409.
|
||||||
|
|
@ -17,7 +19,7 @@ shift 3
|
||||||
|
|
||||||
: "${FORGEJO_TOKEN:?FORGEJO_TOKEN is not set}"
|
: "${FORGEJO_TOKEN:?FORGEJO_TOKEN is not set}"
|
||||||
api="${REPO_API:-https://forgejo.siriusdevops.com/api/v1/repos/sirius/onionwire}"
|
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)"; }
|
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'
|
python3 - "$body_file" "$tag" "$target" "$name" > /tmp/release-body.json <<'PY'
|
||||||
import json, sys
|
import json, sys
|
||||||
body = open(sys.argv[1]).read().replace("@TAG@", sys.argv[2])
|
body = open(sys.argv[1]).read().replace("@TAG@", sys.argv[2])
|
||||||
print(json.dumps({
|
payload = {
|
||||||
"tag_name": sys.argv[2],
|
"tag_name": sys.argv[2],
|
||||||
"target_commitish": sys.argv[3],
|
|
||||||
"name": sys.argv[4],
|
"name": sys.argv[4],
|
||||||
"body": body,
|
"body": body,
|
||||||
"draft": False,
|
"draft": False,
|
||||||
"prerelease": 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
|
PY
|
||||||
|
|
||||||
code=$(curl -s -o /tmp/release-rel.json -w '%{http_code}' \
|
code=$(curl -s -o /tmp/release-rel.json -w '%{http_code}' \
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue