From 380f2d7acf38449118020125e58a63c5ed7b039a Mon Sep 17 00:00:00 2001 From: anandhu-eng Date: Thu, 24 Sep 2026 01:05:58 +0530 Subject: [PATCH 1/2] Skip the tag-push run started by a manual release; pin the App token action A manual release pushes its tag with the mlc-automations App token, and App-token pushes start workflows, so the same release was built and uploaded a second time by a tag-push run. Skip push events whose actor is mlc-automations[bot]; tags pushed by people and all workflow_dispatch runs (including tag retries) are unaffected. Also pin actions/create-github-app-token to a commit SHA (v3.2.0), like the other actions in this workflow, and test that every action is pinned. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/build_wheels.yml | 8 ++++++-- tests/test_build_wheels_workflow.py | 21 ++++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index 0bf3b8cff..a1d1903bc 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -33,7 +33,11 @@ concurrency: jobs: build_wheels: - if: github.repository_owner == 'mlcommons' + # A manual release pushes its tag with the App token, which starts this + # workflow again; that run would rebuild and re-upload the same release. + if: >- + github.repository_owner == 'mlcommons' + && !(github.event_name == 'push' && github.actor == 'mlc-automations[bot]') name: Build wheel runs-on: ubuntu-latest environment: release @@ -47,7 +51,7 @@ jobs: steps: - name: Generate GitHub App token id: app-token - uses: actions/create-github-app-token@v1 + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 with: app-id: ${{ secrets.MLC_AUTOMATIONS_APP_ID }} private-key: ${{ secrets.MLC_AUTOMATIONS_PRIVATE_KEY }} diff --git a/tests/test_build_wheels_workflow.py b/tests/test_build_wheels_workflow.py index 7e5383fa4..738357285 100644 --- a/tests/test_build_wheels_workflow.py +++ b/tests/test_build_wheels_workflow.py @@ -56,9 +56,8 @@ def test_checkout_uses_app_token_for_protected_branch_pushes(self): step for step in self.steps if step.get("uses", "").startswith("actions/checkout@") ) - self.assertEqual( - token_step["uses"], - "actions/create-github-app-token@v1") + self.assertTrue( + token_step["uses"].startswith("actions/create-github-app-token@")) self.assertEqual( token_step["with"]["app-id"], "${{ secrets.MLC_AUTOMATIONS_APP_ID }}", @@ -116,6 +115,22 @@ def test_release_step_uses_app_token_for_github_release_mutations(self): "${{ steps.app-token.outputs.token }}", ) + def test_tag_push_from_app_token_does_not_start_second_release(self): + job_condition = self.workflow["jobs"]["build_wheels"]["if"] + + self.assertIn("github.repository_owner == 'mlcommons'", job_condition) + self.assertIn( + "!(github.event_name == 'push' && github.actor == 'mlc-automations[bot]')", + job_condition, + ) + + def test_actions_are_pinned_to_commit_shas(self): + for step in self.steps: + uses = step.get("uses") + if uses: + ref = uses.split("@", 1)[1] + self.assertRegex(ref, r"^[0-9a-f]{40}$", uses) + def test_workflow_serializes_release_runs(self): concurrency = self.workflow["concurrency"] From c119ba503791379867764a90a651a245894fda5d Mon Sep 17 00:00:00 2001 From: ANANDHU S <71482562+anandhu-eng@users.noreply.github.com> Date: Thu, 24 Sep 2026 01:10:51 +0530 Subject: [PATCH 2/2] Update build_wheels.yml --- .github/workflows/build_wheels.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index a1d1903bc..9dfb2002b 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -34,7 +34,8 @@ concurrency: jobs: build_wheels: # A manual release pushes its tag with the App token, which starts this - # workflow again; that run would rebuild and re-upload the same release. + # workflow again; that run would rebuild and re-upload the same release. The + # below check ensures that does not happen if: >- github.repository_owner == 'mlcommons' && !(github.event_name == 'push' && github.actor == 'mlc-automations[bot]')