diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 0e157c2..ad0c109 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -192,27 +192,35 @@ jobs: env: GITEA_TOKEN: ${{ secrets.REGISTRY_TOKEN }} REPO: ${{ github.repository }} - VERSION: ${{ steps.version.outputs.version }} - IMAGE: ${{ steps.version.outputs.image }} DIGEST: ${{ steps.push.outputs.digest }} + IMAGE: ${{ steps.version.outputs.image }} run: | set -eu API="https://${REGISTRY}/api/v1" TAG="${{ github.ref_name }}" + # Read the version from the checked-out commit rather than from a + # previous step's output. The tag points at this commit, so the two + # agree by construction, and this avoids the release quietly falling + # back to generic notes if the output ever arrives empty. + VERSION=$(grep -m1 '^version' Cargo.toml | sed 's/.*"\(.*\)".*/\1/') + echo "publishing release for ${VERSION} (tag ${TAG})" + # Hand-written notes when they exist, because the interesting part of # a release here is what the operator has to do, not which commits - # landed. Falls back to a short factual note. + # landed. Falls back to a short factual note, and says which it used. if [ -f "docs/releases/${VERSION}.md" ]; then NOTES=$(cat "docs/releases/${VERSION}.md") + echo "using docs/releases/${VERSION}.md (${#NOTES} bytes)" else NOTES=$(printf 'Release %s.\n\nSee the repository README for deployment instructions.' "$VERSION") + echo "::warning::docs/releases/${VERSION}.md is missing; writing a placeholder" fi - BODY=$(NOTES="$NOTES" node -e ' + VERSION="$VERSION" NOTES="$NOTES" node -e ' const { NOTES, VERSION, IMAGE, DIGEST, REGISTRY } = process.env; const ref = REGISTRY + "/" + IMAGE + ":" + VERSION; - process.stdout.write(JSON.stringify({ + require("fs").writeFileSync("/tmp/release.json", JSON.stringify({ body: NOTES + "\n\n---\n\n" + "**Image:** `" + ref + "`\n\n" + @@ -222,28 +230,28 @@ jobs: tag_name: "v" + VERSION, draft: false, prerelease: false, - }));') + }));' # A re-run of the same tag updates the release in place rather than # failing on the duplicate. curl -s -H "Authorization: token ${GITEA_TOKEN}" \ - "${API}/repos/${REPO}/releases/tags/v${VERSION}" > /tmp/release.json || echo '{}' > /tmp/release.json + "${API}/repos/${REPO}/releases/tags/${TAG}" > /tmp/existing.json || echo '{}' > /tmp/existing.json EXISTING=$(node -e ' const fs = require("fs"); try { - const r = JSON.parse(fs.readFileSync("/tmp/release.json", "utf8")); + const r = JSON.parse(fs.readFileSync("/tmp/existing.json", "utf8")); process.stdout.write(r && r.id ? String(r.id) : ""); } catch { process.stdout.write(""); } ') if [ -n "$EXISTING" ]; then curl -sf -X PATCH -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" -d "$BODY" \ + -H "Content-Type: application/json" --data-binary @/tmp/release.json \ "${API}/repos/${REPO}/releases/${EXISTING}" > /dev/null - echo "updated release v${VERSION}" + echo "updated release ${TAG}" else curl -sf -X POST -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" -d "$BODY" \ + -H "Content-Type: application/json" --data-binary @/tmp/release.json \ "${API}/repos/${REPO}/releases" > /dev/null - echo "created release v${VERSION}" + echo "created release ${TAG}" fi