From 9c309407766448daa277597dcd2bc8816d4dec70 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 16:57:46 +0000 Subject: [PATCH 1/2] pages.yml: also re-trigger deploy on Release workflow completion v1.0.5 and v1.0.6 both hit the same failure: publishing a release fires `release: released` (and Build's workflow_run) before release.yml's own job finishes uploading that tag's binaries, so the deploy job's `gh release download ` finds no assets and fails. Re-entering once Release completes is race-free: gh release view still skips a release left in draft, so this doesn't expose anything before it's published. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01FHBCMHmvCZtH45K9CX8mF6 --- .github/workflows/pages.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 09ca65e..e06231e 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -16,7 +16,17 @@ on: release: types: [released] workflow_run: - workflows: ["Build"] + # "Build" catches dev-latest updates. "Release" is the fix for a race + # observed on both v1.0.5 and v1.0.6: publishing a release (whether via + # release.yml's draft or by hand, tag+publish together) fires + # `release: released` immediately, but release.yml's own job -- which + # uploads that tag's binaries -- can still be running for ~2 more + # minutes. The deploy job below downloads by tag and fails with "no + # assets to download" if it runs first. Re-entering once Release + # finishes is racefree by construction: `gh release view` still skips a + # release left in draft, so this doesn't expose anything early -- it + # only ever re-checks a release that could plausibly be published by now. + workflows: ["Build", "Release"] types: [completed] workflow_dispatch: From b7b2b076f37048f3db81fc346068f7963f17aa15 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 17:05:09 +0000 Subject: [PATCH 2/2] release.yml: dispatch pages deploy via needs:, not a raced event Replaces the reactive workflow_run(Release) trigger added earlier this session with a needs:-gated dispatch-deploy job in release.yml itself, following the build->assemble->deploy dependency pattern used by OpenMANET-XIAO-Gateway's build-firmware.yml. needs: orders this after the asset-upload step by construction, so there's no window where the dispatched pages.yml run can find the tag's assets missing -- unlike an event reacting to workflow completion, which raced that same upload in both v1.0.5 and v1.0.6. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01FHBCMHmvCZtH45K9CX8mF6 --- .github/workflows/pages.yml | 30 +++++++++++++----------------- .github/workflows/release.yml | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index e06231e..950e354 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -4,29 +4,25 @@ name: Deploy web flasher # whenever there's a new binary to offer: # - `release: released` fires when a release is published (a maintainer # manually publishing a v1.0.0-style draft — see release.yml — or the -# first-ever creation of the dev-latest prerelease). +# first-ever creation of the dev-latest prerelease). By the time this +# fires, release.yml's own job (which built the draft) has long since +# finished, so its assets are already attached — safe. # - `workflow_run` on Build catches every later dev-latest *update*: that # release already exists after its first publish, so re-uploading -# assets to it is an edit, not a new "released" event. -# Deliberately does NOT trigger on release.yml's own workflow_run — that -# would expose a vX.Y.Z build's binaries through the flasher while the -# release itself is still a draft, defeating the point of drafting it -# (docs/ROADMAP.md: tagging is "a separate, deliberate step"). +# assets to it is an edit, not a new "released" event. Also safe: Build +# uploads dev-latest's assets as a step within its own job, before the +# job (and so the whole workflow) completes, so this can't fire early. +# Deliberately does NOT react to release.yml's workflow_run: a v1.0.5/v1.0.6 +# run once showed that racing an event against release.yml's own ~2-minute +# asset-upload step (rather than something gated on it) fails with "no +# assets to download" if this fires first. release.yml now dispatches this +# workflow itself, via `needs:` on the job that uploads those assets, which +# is ordered by construction instead of raced — see its dispatch-deploy job. on: release: types: [released] workflow_run: - # "Build" catches dev-latest updates. "Release" is the fix for a race - # observed on both v1.0.5 and v1.0.6: publishing a release (whether via - # release.yml's draft or by hand, tag+publish together) fires - # `release: released` immediately, but release.yml's own job -- which - # uploads that tag's binaries -- can still be running for ~2 more - # minutes. The deploy job below downloads by tag and fails with "no - # assets to download" if it runs first. Re-entering once Release - # finishes is racefree by construction: `gh release view` still skips a - # release left in draft, so this doesn't expose anything early -- it - # only ever re-checks a release that could plausibly be published by now. - workflows: ["Build", "Release"] + workflows: ["Build"] types: [completed] workflow_dispatch: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3e8b13c..4285479 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -139,3 +139,21 @@ jobs: draft: ${{ github.event_name != 'workflow_dispatch' }} body_path: ${{ github.event_name == 'push' && 'release-body.md' || '' }} generate_release_notes: false + + # Runs once the job above has finished uploading this tag's assets -- + # `needs:` orders that by construction, unlike pages.yml's old approach of + # reacting to this workflow's completion as an event, which could still + # arrive before the upload step actually finished. A draft release (the + # normal push-triggered case) is invisible to pages.yml's `gh release + # view` regardless, so dispatching here doesn't leak it early; it only + # ever surfaces a release once it's actually published, same as before. + dispatch-deploy: + needs: release + runs-on: ubuntu-latest + permissions: + actions: write + steps: + - name: Re-trigger the web flasher deploy now that assets are attached + run: gh workflow run pages.yml --ref main -R "$GITHUB_REPOSITORY" + env: + GH_TOKEN: ${{ github.token }}