From 625d217047bde7e0ac29782191604637b8687047 Mon Sep 17 00:00:00 2001 From: Coy Geek <65363919+coygeek@users.noreply.github.com> Date: Sat, 20 Jun 2026 21:41:29 -0700 Subject: [PATCH] fix: harden workflow_run coordinator wakes Restrict privileged workflow_run wakeups to recognized completed conclusions from the same repository and default branch while documenting release-branch adaptation. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- examples/github-workflow.yml | 18 ++++++++++++++++++ tests/test_skill.py | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/examples/github-workflow.yml b/examples/github-workflow.yml index 953e62e..26a3432 100644 --- a/examples/github-workflow.yml +++ b/examples/github-workflow.yml @@ -30,6 +30,8 @@ concurrency: jobs: react: + # If CI intentionally hands off from a protected release branch, replace + # the default-branch guard below with that exact branch name. if: >- ( github.event_name != 'pull_request_target' || @@ -45,6 +47,22 @@ jobs: github.event.pull_request.head.repo.full_name == github.repository ) ) && + ( + github.event_name != 'workflow_run' || + ( + contains( + fromJSON( + '["action_required","cancelled","failure","neutral","skipped","stale","startup_failure","success","timed_out"]' + ), + github.event.workflow_run.conclusion + ) && + github.event.workflow_run.event != 'pull_request' && + github.event.workflow_run.event != 'pull_request_target' && + github.event.workflow_run.head_repository.full_name == github.repository && + github.event.workflow_run.head_branch == + github.event.repository.default_branch + ) + ) && ( github.event_name != 'check_suite' || ( diff --git a/tests/test_skill.py b/tests/test_skill.py index 389b4fe..35357f6 100644 --- a/tests/test_skill.py +++ b/tests/test_skill.py @@ -150,6 +150,22 @@ def test_github_workflow_wakes_after_named_ci_finishes(self) -> None: self.assertIn('cron: "*/5 * * * *"', workflow) self.assertIn("workflows: [CI]", workflow) self.assertIn("github.event.repository.default_branch", workflow) + self.assertNotIn("branches: [main]", workflow) + self.assertIn("fromJSON(", workflow) + self.assertIn("github.event.workflow_run.conclusion", workflow) + self.assertIn('"success"', workflow) + self.assertIn('"stale"', workflow) + self.assertIn('"startup_failure"', workflow) + self.assertIn('"timed_out"', workflow) + self.assertIn("github.event.workflow_run.event != 'pull_request'", workflow) + self.assertIn( + "github.event.workflow_run.event != 'pull_request_target'", workflow + ) + self.assertIn("github.event.workflow_run.head_repository.full_name", workflow) + self.assertIn("github.event.workflow_run.head_branch", workflow) + self.assertIn("protected release", workflow) + condition = workflow.split(" if: >-\n", 1)[1].split(" runs-on:", 1)[0] + self.assertNotIn("#", condition) self.assertIn( "github.event.pull_request.head.repo.full_name == github.repository", workflow,