From 41c99ce3b9a27aab20a79f0d5218ec4d16904fd4 Mon Sep 17 00:00:00 2001 From: James Maes Date: Wed, 13 May 2026 16:45:13 -0500 Subject: [PATCH] ci(actions): create GitHub Release directly in publish-tag job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default GITHUB_TOKEN cannot trigger downstream workflows (GitHub prevents the chain to avoid infinite loops). publish-tag's `git push origin "$TAG"` therefore never fires release.yml's `push: tags:` listener — observed on v0.1.0-dev.50, where the tag landed but the Release object was missing until manually created. Fold the Release creation into the publish-tag job using `gh release create` with GH_TOKEN=secrets.GITHUB_TOKEN. Direct API calls work fine with the default token; only the push→workflow chain is blocked. - Idempotent: skips if release already exists. - Notes: auto-generated from `git log $prev..$TAG` plus a Verification block linking back to the CI run. - Prerelease flag respects steps.version.outputs.prerelease (true for dev/rc tags, false for vX.Y.Z final tags on main). release.yml stays untouched as a fallback for manually-pushed tags (humans pushing tags directly CAN trigger workflows). Closes #186 --- .github/workflows/ci.yml | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c10fea..dcfd4f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -425,3 +425,51 @@ jobs: fi git tag -a "$TAG" -m "Automated tag from CI for $GH_REF" git push origin "$TAG" + # GitHub Actions GITHUB_TOKEN cannot trigger downstream workflows. The + # separate `release.yml` workflow listens for `push: tags:` events but + # never sees a CI-pushed tag — observed on v0.1.0-dev.50 (tag created, + # Release object missing, had to be manually created). Create the + # Release object directly here in the same job so the Releases page + # reflects CI-pushed tags without a manual step. `release.yml` stays + # as a fallback for manually-pushed tags (which CAN trigger workflows). + - name: Create GitHub Release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG: ${{ steps.version.outputs.tag }} + PRERELEASE: ${{ steps.version.outputs.prerelease }} + RUN_URL: ${{ format('https://github.com/{0}/actions/runs/{1}', github.repository, github.run_id) }} + run: | + set -euo pipefail + if ! git rev-parse "refs/tags/$TAG" >/dev/null 2>&1; then + echo "Tag $TAG not present locally; nothing to release." >&2 + exit 0 + fi + if gh release view "$TAG" >/dev/null 2>&1; then + echo "Release $TAG already exists — skipping create (idempotent)." + exit 0 + fi + prev=$(git tag --list 'v*' --sort=-v:refname | grep -v "^${TAG}$" | head -n 1 || true) + notes_file=$(mktemp) + { + echo "## Changes" + echo + if [ -n "$prev" ]; then + git log --pretty='format:- %s (%h)' "${prev}..${TAG}" + else + git log --pretty='format:- %s (%h)' -20 + fi + echo + echo + echo "## Verification" + echo + echo "- CI build: $RUN_URL" + echo "- Boundary gates, webview, app-build, 13/13 SPM packages: all green on this commit" + } > "$notes_file" + flag=() + if [ "$PRERELEASE" = "true" ]; then + flag+=("--prerelease") + fi + gh release create "$TAG" \ + --title "$TAG" \ + --notes-file "$notes_file" \ + "${flag[@]}" -- 2.54.0