From 2a8872d77ec4befe46cacfc76400057c12f7beff Mon Sep 17 00:00:00 2001 From: Hisku Date: Tue, 19 May 2026 17:31:37 +0100 Subject: [PATCH 1/2] fix(ci): use PAT in release-please so tag push triggers release.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default GITHUB_TOKEN deliberately suppresses downstream workflow triggers — so when release-please-action created the v1.7.0 tag after PR #41 merged, the `Build and Release` workflow (push: tags: v*) never observed it. The release sat empty. Pass a fine-grained PAT (RELEASE_PAT) with Contents: read/write so the tag push looks like a normal user push, which DOES fire downstream workflows. Add RELEASE_PAT as a repo secret before this lands. For v1.7.0 itself, manually re-push the existing tag once to backfill its assets: git fetch --tags git push origin :refs/tags/v1.7.0 git tag -d v1.7.0 git tag v1.7.0 origin/main git push origin v1.7.0 Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/release-please.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 15b1e18..6df2d9c 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -18,7 +18,17 @@ jobs: # When the Release PR is merged, this action creates the git tag (vX.Y.Z) # and the GitHub Release. The release.yml workflow then triggers on that # tag to attach prebuilt asset bundles. + # + # `token` must be a Personal Access Token (RELEASE_PAT), NOT the + # default GITHUB_TOKEN. GitHub deliberately doesn't fire downstream + # workflows from pushes made with the default token — including the + # tag push release-please-action makes when the Release PR merges. + # That left v1.7.0 sitting in Releases with zero assets because the + # tagged-release `Build and Release` workflow never observed the tag. + # A PAT with `Contents: read/write` makes the tag push look like a + # normal user push, which DOES fire downstream workflows. - uses: googleapis/release-please-action@v4 with: + token: ${{ secrets.RELEASE_PAT }} config-file: .release-please-config.json manifest-file: .release-please-manifest.json From 950d4feed9e7f0bb8accefd9a85921b775f0fe5f Mon Sep 17 00:00:00 2001 From: Hisku Date: Tue, 19 May 2026 17:40:18 +0100 Subject: [PATCH 2/2] fix(ci): swap PAT for workflow_dispatch fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PAT approach in the previous commit needs org-level approval on StackOneHQ to issue a fine-grained token, which is delaying things. Instead, add a manual `workflow_dispatch` entry point to release.yml so any release-please-created tag (whose original push doesn't fire downstream workflows due to GitHub's anti-loop guard on GITHUB_TOKEN) can be picked up via Actions → "Run workflow" → enter tag name. Factored via TARGET_TAG env var so the auto path (push: tags: v*) keeps working unchanged for tags pushed by a user account. Revert the release-please.yml PAT change — back to the default GITHUB_TOKEN, with a comment explaining the manual fallback. For v1.7.0 itself: once this lands, dispatch against v1.7.0 from Actions and the existing release page gets its artifacts. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/release-please.yml | 16 ++++----------- .github/workflows/release.yml | 29 ++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 6df2d9c..79ded8b 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -16,19 +16,11 @@ jobs: # Watches conventional commits on main, opens (and updates) a Release PR # that bumps .release-please-manifest.json + regenerates CHANGELOG.md. # When the Release PR is merged, this action creates the git tag (vX.Y.Z) - # and the GitHub Release. The release.yml workflow then triggers on that - # tag to attach prebuilt asset bundles. - # - # `token` must be a Personal Access Token (RELEASE_PAT), NOT the - # default GITHUB_TOKEN. GitHub deliberately doesn't fire downstream - # workflows from pushes made with the default token — including the - # tag push release-please-action makes when the Release PR merges. - # That left v1.7.0 sitting in Releases with zero assets because the - # tagged-release `Build and Release` workflow never observed the tag. - # A PAT with `Contents: read/write` makes the tag push look like a - # normal user push, which DOES fire downstream workflows. + # and the GitHub Release. release.yml then attaches signed/notarized + # artifacts — either automatically when the next tag is created OR via + # its manual `workflow_dispatch` trigger as a fallback when the tag push + # didn't cascade (default GITHUB_TOKEN suppresses downstream triggers). - uses: googleapis/release-please-action@v4 with: - token: ${{ secrets.RELEASE_PAT }} config-file: .release-please-config.json manifest-file: .release-please-manifest.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index be72d75..05ff2b5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,9 +10,21 @@ name: Build and Release # trouble than two separate artifacts. on: + # Auto-fire when a vX.Y.Z tag is pushed by a user account. push: tags: - 'v*' + # Manual fallback for tags pushed by release-please-action — the default + # GITHUB_TOKEN deliberately suppresses downstream workflow triggers, so + # release-please-created tags don't auto-fire the `push: tags: v*` path + # above. Re-running this workflow from Actions → "Run workflow" picks up + # any existing tag and attaches its artifacts to the matching release. + workflow_dispatch: + inputs: + tag: + description: 'Tag to build (e.g. v1.7.0). Must already exist as a Release.' + required: true + type: string jobs: release: @@ -30,9 +42,18 @@ jobs: # Resources/venv/. Local dev iteration leaves this unset for speed. STACKNUDGE_BUNDLE_VENV: "1" KEYCHAIN: build-stack-nudge.keychain + # Tag we're operating on, regardless of trigger source. For push + # events this resolves to the tag that fired the workflow; for + # workflow_dispatch it's the input the user typed in the UI. + TARGET_TAG: ${{ inputs.tag || github.ref_name }} steps: - uses: actions/checkout@v6 + with: + # Check out the actual tag's commit rather than the workflow's + # ref, so workflow_dispatch builds the same source the original + # tag pointed at (not whatever HEAD on main looks like now). + ref: ${{ inputs.tag || github.ref }} # Stamp the tag's version into Info.plist so the bundled app # advertises the right version regardless of what's checked into @@ -40,7 +61,7 @@ jobs: # sync too, but stamping at build time is belt-and-braces. - name: Stamp version from tag run: | - VERSION="${GITHUB_REF_NAME#v}" + VERSION="${TARGET_TAG#v}" /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $VERSION" panel/Info.plist /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $VERSION" panel/Info.plist @@ -118,7 +139,7 @@ jobs: - name: Package ${{ matrix.arch }} run: | set -euo pipefail - VERSION="${GITHUB_REF_NAME#v}" + VERSION="${TARGET_TAG#v}" ARTIFACT="stack-nudge-${VERSION}-macos-${{ matrix.arch }}.tar.gz" # Tarball wraps just the .app — it's now self-contained # (Bootstrap.swift owns the install side on first launch). @@ -130,8 +151,12 @@ jobs: # release-please creates the GitHub Release before this workflow # runs, so action-gh-release attaches assets to the existing # release rather than creating a duplicate. + # tag_name explicit so workflow_dispatch attaches to the right release + # — without it action-gh-release uses github.ref which is "main"-ish + # for manual dispatches and fails to find a matching release. - uses: softprops/action-gh-release@v3 with: + tag_name: ${{ env.TARGET_TAG }} files: | stack-nudge-*-macos-${{ matrix.arch }}.tar.gz stack-nudge-*-macos-${{ matrix.arch }}.tar.gz.sha256