From 8fc104f4142b3c294ffae27ddfc98c1594f29108 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Aug 2026 02:14:07 +0000 Subject: [PATCH 1/3] Add stacked PR filtering for pull_request_review events Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/ai-moderator.lock.yml | 7 +- .github/workflows/changeset.lock.yml | 10 +- .../workflows/design-decision-gate.lock.yml | 10 +- .github/workflows/firewall-escape.lock.yml | 10 +- .../impeccable-skills-reviewer.lock.yml | 6 +- .../mattpocock-skills-reviewer.lock.yml | 6 +- .../pr-code-quality-reviewer.lock.yml | 6 +- .../workflows/pr-description-caveman.lock.yml | 8 +- .github/workflows/refiner.lock.yml | 10 +- .../workflows/smoke-agent-all-merged.lock.yml | 10 +- .../workflows/smoke-agent-all-none.lock.yml | 10 +- .../smoke-agent-public-approved.lock.yml | 10 +- .../smoke-agent-public-none.lock.yml | 10 +- .../smoke-agent-scoped-approved.lock.yml | 10 +- .github/workflows/smoke-antigravity.lock.yml | 10 +- .../workflows/smoke-call-workflow.lock.yml | 10 +- .github/workflows/smoke-ci.lock.yml | 6 +- .github/workflows/smoke-claude.lock.yml | 10 +- .github/workflows/smoke-codex.lock.yml | 10 +- .github/workflows/smoke-copilot-arm.lock.yml | 10 +- .../smoke-create-cross-repo-pr.lock.yml | 10 +- .github/workflows/smoke-gemini.lock.yml | 10 +- .github/workflows/smoke-multi-pr.lock.yml | 10 +- .github/workflows/smoke-opencode.lock.yml | 10 +- .github/workflows/smoke-pi.lock.yml | 10 +- .github/workflows/smoke-project.lock.yml | 10 +- .github/workflows/smoke-temporary-id.lock.yml | 10 +- .github/workflows/smoke-test-tools.lock.yml | 10 +- .../smoke-update-cross-repo-pr.lock.yml | 10 +- .../workflows/test-quality-sentinel.lock.yml | 6 +- .../visual-regression-checker.lock.yml | 6 +- docs/src/content/docs/reference/triggers.md | 13 ++- pkg/parser/schema_location_test.go | 64 +++++++++++++ pkg/parser/schemas/main_workflow_schema.json | 15 +++ pkg/workflow/compiler_draft_test.go | 12 +++ pkg/workflow/filters.go | 94 ++++++++++++------- .../filters_stack_integration_test.go | 52 ++++++++++ pkg/workflow/filters_stack_test.go | 53 +++++++++++ .../frontmatter_on_section_cleanup.go | 9 +- 39 files changed, 442 insertions(+), 151 deletions(-) diff --git a/.github/workflows/ai-moderator.lock.yml b/.github/workflows/ai-moderator.lock.yml index bb494a8d969..b721500b09e 100644 --- a/.github/workflows/ai-moderator.lock.yml +++ b/.github/workflows/ai-moderator.lock.yml @@ -121,8 +121,8 @@ jobs: activation: needs: pre_activation if: > - needs.pre_activation.outputs.activated == 'true' && (github.event_name != 'pull_request' || github.event.pull_request.stack == null || - github.event.pull_request.stack.position == github.event.pull_request.stack.size) + needs.pre_activation.outputs.activated == 'true' && ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || + github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size) runs-on: ubuntu-slim permissions: actions: read @@ -1682,7 +1682,8 @@ jobs: ((!(github.event_name == 'issue_comment') || !contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) && (!(github.event_name == 'issues') || !contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.issue.author_association)) && (!(github.event_name == 'pull_request') || !contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.pull_request.author_association))) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size) runs-on: ubuntu-slim permissions: actions: read diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index 3de899e51d1..0ce45c8209c 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -101,9 +101,9 @@ jobs: if: > needs.pre_activation.outputs.activated == 'true' && ((((github.event.pull_request.base.ref == github.event.repository.default_branch) && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id)) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'changeset' || - github.event.label.name == 'smoke')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'changeset' || github.event.label.name == 'smoke')) runs-on: ubuntu-slim permissions: actions: read @@ -1935,8 +1935,8 @@ jobs: pre_activation: if: > (((github.event.pull_request.base.ref == github.event.repository.default_branch) && (github.event_name != 'pull_request' || - github.event.pull_request.head.repo.id == github.repository_id)) && (github.event_name != 'pull_request' || - github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && + github.event.pull_request.head.repo.id == github.repository_id)) && ((github.event_name != 'pull_request' && + github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'changeset' || github.event.label.name == 'smoke') runs-on: ubuntu-slim diff --git a/.github/workflows/design-decision-gate.lock.yml b/.github/workflows/design-decision-gate.lock.yml index 571b25c87cb..70faee99b89 100644 --- a/.github/workflows/design-decision-gate.lock.yml +++ b/.github/workflows/design-decision-gate.lock.yml @@ -113,8 +113,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'implementation')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'implementation')) runs-on: ubuntu-slim permissions: actions: read @@ -1989,8 +1990,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'implementation') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'implementation') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/firewall-escape.lock.yml b/.github/workflows/firewall-escape.lock.yml index 066e55dcffc..48d954d03a5 100644 --- a/.github/workflows/firewall-escape.lock.yml +++ b/.github/workflows/firewall-escape.lock.yml @@ -96,8 +96,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'firewall-escape-test')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'firewall-escape-test')) runs-on: ubuntu-slim permissions: actions: read @@ -1710,8 +1711,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'firewall-escape-test') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'firewall-escape-test') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/impeccable-skills-reviewer.lock.yml b/.github/workflows/impeccable-skills-reviewer.lock.yml index 829abd5c6d0..8490198211f 100644 --- a/.github/workflows/impeccable-skills-reviewer.lock.yml +++ b/.github/workflows/impeccable-skills-reviewer.lock.yml @@ -105,7 +105,8 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) runs-on: ubuntu-slim permissions: actions: read @@ -1651,7 +1652,8 @@ jobs: pre_activation: if: > (github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size) runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/mattpocock-skills-reviewer.lock.yml b/.github/workflows/mattpocock-skills-reviewer.lock.yml index 470ebd7f25a..069682f6449 100644 --- a/.github/workflows/mattpocock-skills-reviewer.lock.yml +++ b/.github/workflows/mattpocock-skills-reviewer.lock.yml @@ -103,7 +103,8 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) runs-on: ubuntu-slim permissions: actions: read @@ -1823,7 +1824,8 @@ jobs: pre_activation: if: > (github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size) runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/pr-code-quality-reviewer.lock.yml b/.github/workflows/pr-code-quality-reviewer.lock.yml index 42345370812..a049ac995ae 100644 --- a/.github/workflows/pr-code-quality-reviewer.lock.yml +++ b/.github/workflows/pr-code-quality-reviewer.lock.yml @@ -104,7 +104,8 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) runs-on: ubuntu-slim permissions: actions: read @@ -1962,7 +1963,8 @@ jobs: pre_activation: if: > (github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size) runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/pr-description-caveman.lock.yml b/.github/workflows/pr-description-caveman.lock.yml index fac08b5fac1..53c1be3d83b 100644 --- a/.github/workflows/pr-description-caveman.lock.yml +++ b/.github/workflows/pr-description-caveman.lock.yml @@ -73,8 +73,8 @@ jobs: if: > needs.pre_activation.outputs.activated == 'true' && (((github.event.pull_request.merged == true && !startsWith(github.event.pull_request.head.ref, 'signed/jsweep/') && !startsWith(github.event.pull_request.head.ref, 'copilot/')) && (github.event_name != 'pull_request' || - github.event.pull_request.head.repo.id == github.repository_id)) && (github.event_name != 'pull_request' || - github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) + github.event.pull_request.head.repo.id == github.repository_id)) && ((github.event_name != 'pull_request' && + github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) runs-on: ubuntu-slim permissions: actions: read @@ -1550,8 +1550,8 @@ jobs: if: > ((github.event.pull_request.merged == true && !startsWith(github.event.pull_request.head.ref, 'signed/jsweep/') && !startsWith(github.event.pull_request.head.ref, 'copilot/')) && (github.event_name != 'pull_request' || - github.event.pull_request.head.repo.id == github.repository_id)) && (github.event_name != 'pull_request' || - github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size) + github.event.pull_request.head.repo.id == github.repository_id)) && ((github.event_name != 'pull_request' && + github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size) runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/refiner.lock.yml b/.github/workflows/refiner.lock.yml index fd2691a9d73..77c6a0ade13 100644 --- a/.github/workflows/refiner.lock.yml +++ b/.github/workflows/refiner.lock.yml @@ -103,8 +103,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'refine')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'refine')) runs-on: ubuntu-slim permissions: actions: read @@ -1933,8 +1934,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'refine') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'refine') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-agent-all-merged.lock.yml b/.github/workflows/smoke-agent-all-merged.lock.yml index ff519f402f5..d46f8587bde 100644 --- a/.github/workflows/smoke-agent-all-merged.lock.yml +++ b/.github/workflows/smoke-agent-all-merged.lock.yml @@ -93,8 +93,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'metal')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'metal')) runs-on: ubuntu-slim permissions: actions: read @@ -1692,8 +1693,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'metal') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'metal') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-agent-all-none.lock.yml b/.github/workflows/smoke-agent-all-none.lock.yml index 0cdceabee31..28e51ed365e 100644 --- a/.github/workflows/smoke-agent-all-none.lock.yml +++ b/.github/workflows/smoke-agent-all-none.lock.yml @@ -93,8 +93,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'metal')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'metal')) runs-on: ubuntu-slim permissions: actions: read @@ -1692,8 +1693,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'metal') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'metal') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-agent-public-approved.lock.yml b/.github/workflows/smoke-agent-public-approved.lock.yml index 427eedcd4a0..c772ceb9fba 100644 --- a/.github/workflows/smoke-agent-public-approved.lock.yml +++ b/.github/workflows/smoke-agent-public-approved.lock.yml @@ -95,8 +95,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'metal')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'metal')) runs-on: ubuntu-slim permissions: actions: read @@ -1744,8 +1745,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'metal') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'metal') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-agent-public-none.lock.yml b/.github/workflows/smoke-agent-public-none.lock.yml index 63ff9248437..bec33835b62 100644 --- a/.github/workflows/smoke-agent-public-none.lock.yml +++ b/.github/workflows/smoke-agent-public-none.lock.yml @@ -93,8 +93,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'metal')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'metal')) runs-on: ubuntu-slim permissions: actions: read @@ -1692,8 +1693,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'metal') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'metal') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-agent-scoped-approved.lock.yml b/.github/workflows/smoke-agent-scoped-approved.lock.yml index 8a6a4c1814e..a1d14d8839a 100644 --- a/.github/workflows/smoke-agent-scoped-approved.lock.yml +++ b/.github/workflows/smoke-agent-scoped-approved.lock.yml @@ -94,8 +94,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'metal')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'metal')) runs-on: ubuntu-slim permissions: actions: read @@ -1699,8 +1700,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'metal') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'metal') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-antigravity.lock.yml b/.github/workflows/smoke-antigravity.lock.yml index f00ff4f98a3..2a171365e6b 100644 --- a/.github/workflows/smoke-antigravity.lock.yml +++ b/.github/workflows/smoke-antigravity.lock.yml @@ -96,8 +96,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke')) runs-on: ubuntu-slim permissions: actions: read @@ -1956,8 +1957,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-call-workflow.lock.yml b/.github/workflows/smoke-call-workflow.lock.yml index 31e3afc8199..e3adea093f5 100644 --- a/.github/workflows/smoke-call-workflow.lock.yml +++ b/.github/workflows/smoke-call-workflow.lock.yml @@ -94,8 +94,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'water')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'water')) runs-on: ubuntu-slim permissions: actions: read @@ -1740,8 +1741,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'water') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'water') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-ci.lock.yml b/.github/workflows/smoke-ci.lock.yml index 184b3333e53..b3ebb826e27 100644 --- a/.github/workflows/smoke-ci.lock.yml +++ b/.github/workflows/smoke-ci.lock.yml @@ -110,7 +110,8 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) runs-on: ubuntu-slim permissions: actions: read @@ -1586,7 +1587,8 @@ jobs: pre_activation: if: > (github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size) runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 568b18604d5..b0599a95933 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -106,8 +106,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke')) runs-on: ubuntu-slim permissions: actions: read @@ -2586,8 +2587,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index e11fba5da82..dce60a8ffe9 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -106,8 +106,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke')) runs-on: ubuntu-slim permissions: actions: read @@ -2199,8 +2200,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-copilot-arm.lock.yml b/.github/workflows/smoke-copilot-arm.lock.yml index e17b2691f86..d1f1f3fc09b 100644 --- a/.github/workflows/smoke-copilot-arm.lock.yml +++ b/.github/workflows/smoke-copilot-arm.lock.yml @@ -103,8 +103,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'water')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'water')) runs-on: ubuntu-slim permissions: actions: read @@ -2617,8 +2618,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'water') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'water') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-create-cross-repo-pr.lock.yml b/.github/workflows/smoke-create-cross-repo-pr.lock.yml index f8cb896b487..1ca5cfb3223 100644 --- a/.github/workflows/smoke-create-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-create-cross-repo-pr.lock.yml @@ -94,8 +94,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke-create-cross-repo-pr')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke-create-cross-repo-pr')) runs-on: ubuntu-slim permissions: actions: read @@ -1746,8 +1747,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke-create-cross-repo-pr') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke-create-cross-repo-pr') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-gemini.lock.yml b/.github/workflows/smoke-gemini.lock.yml index e71354cac8c..f9788c80438 100644 --- a/.github/workflows/smoke-gemini.lock.yml +++ b/.github/workflows/smoke-gemini.lock.yml @@ -98,8 +98,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke')) runs-on: ubuntu-slim permissions: actions: read @@ -2037,8 +2038,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-multi-pr.lock.yml b/.github/workflows/smoke-multi-pr.lock.yml index d0d0be3522d..d0746b0c674 100644 --- a/.github/workflows/smoke-multi-pr.lock.yml +++ b/.github/workflows/smoke-multi-pr.lock.yml @@ -93,8 +93,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke-multi-pr')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke-multi-pr')) runs-on: ubuntu-slim permissions: actions: read @@ -1698,8 +1699,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke-multi-pr') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke-multi-pr') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-opencode.lock.yml b/.github/workflows/smoke-opencode.lock.yml index 506e70d51f6..71c6b18a743 100644 --- a/.github/workflows/smoke-opencode.lock.yml +++ b/.github/workflows/smoke-opencode.lock.yml @@ -96,8 +96,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'water')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'water')) runs-on: ubuntu-slim permissions: actions: read @@ -1754,8 +1755,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'water') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'water') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-pi.lock.yml b/.github/workflows/smoke-pi.lock.yml index 4f98ac19931..f246d8a5aae 100644 --- a/.github/workflows/smoke-pi.lock.yml +++ b/.github/workflows/smoke-pi.lock.yml @@ -96,8 +96,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke')) runs-on: ubuntu-slim permissions: actions: read @@ -1698,8 +1699,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index edfd909fae9..35139abda18 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -95,8 +95,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'water')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'water')) runs-on: ubuntu-slim permissions: actions: read @@ -2178,8 +2179,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'water') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'water') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-temporary-id.lock.yml b/.github/workflows/smoke-temporary-id.lock.yml index f57ed77b23b..951910cd759 100644 --- a/.github/workflows/smoke-temporary-id.lock.yml +++ b/.github/workflows/smoke-temporary-id.lock.yml @@ -93,8 +93,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'water')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'water')) runs-on: ubuntu-slim permissions: actions: read @@ -2026,8 +2027,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'water') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'water') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-test-tools.lock.yml b/.github/workflows/smoke-test-tools.lock.yml index c80c22e1b36..035bdfeeaa2 100644 --- a/.github/workflows/smoke-test-tools.lock.yml +++ b/.github/workflows/smoke-test-tools.lock.yml @@ -97,8 +97,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke')) runs-on: ubuntu-slim permissions: actions: read @@ -1721,8 +1722,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/smoke-update-cross-repo-pr.lock.yml b/.github/workflows/smoke-update-cross-repo-pr.lock.yml index 38c04c34d5c..db00aa6215a 100644 --- a/.github/workflows/smoke-update-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-update-cross-repo-pr.lock.yml @@ -94,8 +94,9 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && (((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke-update-cross-repo-pr')) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke-update-cross-repo-pr')) runs-on: ubuntu-slim permissions: actions: read @@ -1780,8 +1781,9 @@ jobs: pre_activation: if: > ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke-update-cross-repo-pr') + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) && (github.event_name != 'pull_request' || + github.event.action != 'labeled' || github.event.label.name == 'smoke-update-cross-repo-pr') runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/test-quality-sentinel.lock.yml b/.github/workflows/test-quality-sentinel.lock.yml index 65395826d9a..77391236a2d 100644 --- a/.github/workflows/test-quality-sentinel.lock.yml +++ b/.github/workflows/test-quality-sentinel.lock.yml @@ -94,7 +94,8 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) runs-on: ubuntu-slim permissions: actions: read @@ -1944,7 +1945,8 @@ jobs: pre_activation: if: > (github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size) runs-on: ubuntu-slim permissions: contents: read diff --git a/.github/workflows/visual-regression-checker.lock.yml b/.github/workflows/visual-regression-checker.lock.yml index c76674e4932..62abb3a21b0 100644 --- a/.github/workflows/visual-regression-checker.lock.yml +++ b/.github/workflows/visual-regression-checker.lock.yml @@ -92,7 +92,8 @@ jobs: needs: pre_activation if: > needs.pre_activation.outputs.activated == 'true' && ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size)) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size)) runs-on: ubuntu-slim permissions: actions: read @@ -1643,7 +1644,8 @@ jobs: pre_activation: if: > (github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size) + ((github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || + github.event.pull_request.stack.position == github.event.pull_request.stack.size) runs-on: ubuntu-slim permissions: contents: read diff --git a/docs/src/content/docs/reference/triggers.md b/docs/src/content/docs/reference/triggers.md index 2defda6d0a4..8b3bf8268ba 100644 --- a/docs/src/content/docs/reference/triggers.md +++ b/docs/src/content/docs/reference/triggers.md @@ -169,6 +169,8 @@ When using stacked pull requests (a chain of PRs each targeting the previous one By default (`max-stack: 1`), workflows run only on the **top-most PR** in the stack — the one currently under review. Lower-stack PRs are skipped automatically. +This is supported for both `pull_request` and `pull_request_review` triggers. + ```yaml wrap on: pull_request: @@ -194,7 +196,16 @@ on: max-stack: -1 # run on all pull requests regardless of stack position ``` -Non-stacked PRs and non-`pull_request` events are unaffected by this setting. +You can also apply the same filter to review events: + +```yaml wrap +on: + pull_request_review: + types: [submitted] + max-stack: 2 # run only for reviews on the top 2 PRs in a stack +``` + +Non-stacked PRs and non-`pull_request`/`pull_request_review` events are unaffected by this setting. ### Comment Triggers diff --git a/pkg/parser/schema_location_test.go b/pkg/parser/schema_location_test.go index 4489ce561ba..a9b5dbf5a5c 100644 --- a/pkg/parser/schema_location_test.go +++ b/pkg/parser/schema_location_test.go @@ -710,3 +710,67 @@ func TestValidateMainWorkflowFrontmatterWithSchemaAndLocation_MaxStack(t *testin }) } } + +func TestValidateMainWorkflowFrontmatterWithSchemaAndLocation_PullRequestReviewMaxStack(t *testing.T) { + tests := []struct { + name string + maxStack any + wantErr bool + errContains string + }{ + { + name: "max-stack: 1 is valid (default)", + maxStack: 1, + wantErr: false, + }, + { + name: "max-stack: 2 is valid", + maxStack: 2, + wantErr: false, + }, + { + name: "max-stack: -1 is valid (disable stack protection)", + maxStack: -1, + wantErr: false, + }, + { + name: "max-stack: 0 is rejected", + maxStack: 0, + wantErr: true, + errContains: "max-stack", + }, + { + name: "max-stack: -2 is rejected", + maxStack: -2, + wantErr: true, + errContains: "max-stack", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + frontmatter := map[string]any{ + "on": map[string]any{ + "pull_request_review": map[string]any{ + "types": []any{"submitted"}, + "max-stack": tt.maxStack, + }, + }, + } + err := ValidateMainWorkflowFrontmatterWithSchemaAndLocation(frontmatter, "/test/workflow.md") + if tt.wantErr && err == nil { + t.Errorf("expected validation error for max-stack: %v, got nil", tt.maxStack) + return + } + if !tt.wantErr && err != nil { + t.Errorf("unexpected validation error for max-stack: %v: %v", tt.maxStack, err) + return + } + if tt.wantErr && err != nil && tt.errContains != "" { + if !strings.Contains(err.Error(), tt.errContains) { + t.Errorf("expected error containing %q, got: %v", tt.errContains, err) + } + } + }) + } +} diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index d3d24ea83d9..f3c5bc1b35c 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -1694,6 +1694,21 @@ "type": "string", "enum": ["submitted", "edited", "dismissed"] } + }, + "max-stack": { + "anyOf": [ + { + "type": "integer", + "const": -1, + "description": "Disable stack protection; run on every pull request review in the stack." + }, + { + "type": "integer", + "minimum": 1, + "description": "Run only on pull request reviews for the top N pull requests in the stack. Default is 1 (only the latest/top pull request)." + } + ], + "description": "Maximum number of top stack layers to run on for stacked pull request review events. Default is 1 (only the latest/top pull request in the stack). Set to -1 to disable stack protection and run on every pull request review in the stack. Value 0 is not allowed." } } }, diff --git a/pkg/workflow/compiler_draft_test.go b/pkg/workflow/compiler_draft_test.go index b1e1ddf06d3..f32c7f7dffb 100644 --- a/pkg/workflow/compiler_draft_test.go +++ b/pkg/workflow/compiler_draft_test.go @@ -558,6 +558,18 @@ func TestCommentOutProcessedFieldsInOnSectionBlankLineInBlock(t *testing.T) { assert.NotContains(t, result, "# \n") } +func TestCommentOutProcessedFieldsInOnSection_PullRequestReviewMaxStack(t *testing.T) { + compiler := NewCompiler() + + result := compiler.commentOutProcessedFieldsInOnSection(`on: + pull_request_review: + types: [submitted] + max-stack: 2 + workflow_dispatch:`, map[string]any{}) + + assert.Contains(t, result, "# max-stack: 2 # Stack filtering applied via job conditions") +} + func TestCommentOutProcessedFieldsInOnSectionTrailingSpaceOnNonBlankLine(t *testing.T) { compiler := NewCompiler() diff --git a/pkg/workflow/filters.go b/pkg/workflow/filters.go index 02b6f1ebfa5..8d86831aedb 100644 --- a/pkg/workflow/filters.go +++ b/pkg/workflow/filters.go @@ -196,17 +196,17 @@ func (c *Compiler) applyPullRequestForkFilter(data *WorkflowData, frontmatter ma // applyPullRequestStackFilter applies stacked pull request protection. // Default behavior: run only for the latest PR in a stack (max-stack = 1). -// Set on.pull_request.max-stack: -1 to disable this protection. +// Set on.pull_request.max-stack or on.pull_request_review.max-stack to -1 to disable this protection. func (c *Compiler) applyPullRequestStackFilter(data *WorkflowData, frontmatter map[string]any) { filtersLog.Print("Applying pull request stack filter") onValue, hasOn := frontmatter["on"] - if !hasOn || !hasPullRequestTrigger(onValue) { + if !hasOn || !hasStackFilterTrigger(onValue) { return } maxStack := 1 - if configuredMaxStack, ok := extractPullRequestMaxStack(onValue); ok { + if configuredMaxStack, ok := extractStackMaxStack(onValue); ok { maxStack = configuredMaxStack } @@ -220,7 +220,7 @@ func (c *Compiler) applyPullRequestStackFilter(data *WorkflowData, frontmatter m // equality operator. This gates the entire job (shows as "skipped") for non-top PRs. // GitHub Actions expressions do not support arithmetic (+, -, etc.), so we use // position == size to check that this PR is at the top of the stack. - stackCondition := "github.event_name != 'pull_request' || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size" + stackCondition := "(github.event_name != 'pull_request' && github.event_name != 'pull_request_review') || github.event.pull_request.stack == null || github.event.pull_request.stack.position == github.event.pull_request.stack.size" existingCondition := data.If conditionTree := BuildConditionTree(existingCondition, stackCondition) @@ -232,7 +232,7 @@ func (c *Compiler) applyPullRequestStackFilter(data *WorkflowData, frontmatter m // default-condition steps from running (they use if: success() by default). stackGateStep := fmt.Sprintf( "- name: Stack position gate (max-stack: %d)\n"+ - " if: github.event_name == 'pull_request' && github.event.pull_request.stack != null\n"+ + " if: (github.event_name == 'pull_request' || github.event_name == 'pull_request_review') && github.event.pull_request.stack != null\n"+ " env:\n"+ " STACK_POSITION: ${{ github.event.pull_request.stack.position }}\n"+ " STACK_SIZE: ${{ github.event.pull_request.stack.size }}\n"+ @@ -254,57 +254,81 @@ func (c *Compiler) applyPullRequestStackFilter(data *WorkflowData, frontmatter m } } -func hasPullRequestTrigger(onValue any) bool { +func hasStackFilterTrigger(onValue any) bool { switch on := onValue.(type) { case string: - return on == "pull_request" + return on == "pull_request" || on == "pull_request_review" case []any: for _, item := range on { - if item == "pull_request" { + if item == "pull_request" || item == "pull_request_review" { return true } if eventMap, ok := item.(map[string]any); ok { if _, exists := eventMap["pull_request"]; exists { return true } + if _, exists := eventMap["pull_request_review"]; exists { + return true + } } } case map[string]any: - _, exists := on["pull_request"] - return exists + if _, exists := on["pull_request"]; exists { + return true + } + if _, exists := on["pull_request_review"]; exists { + return true + } } return false } -func extractPullRequestMaxStack(onValue any) (int, bool) { - onMap, ok := onValue.(map[string]any) - if !ok { - return 0, false - } - - prValue, hasPR := onMap["pull_request"] - if !hasPR { - return 0, false - } - - prMap, ok := prValue.(map[string]any) - if !ok { - return 0, false +func extractStackMaxStack(onValue any) (int, bool) { + switch on := onValue.(type) { + case map[string]any: + return extractStackMaxStackFromMap(on) + case []any: + for _, item := range on { + eventMap, ok := item.(map[string]any) + if !ok { + continue + } + if maxStack, ok := extractStackMaxStackFromMap(eventMap); ok { + return maxStack, true + } + } } - maxStackValue, hasMaxStack := prMap["max-stack"] - if !hasMaxStack { - return 0, false - } + return 0, false +} - switch v := maxStackValue.(type) { - case int: - return v, true - case int64: - return int(v), true - case float64: - if v == float64(int(v)) { +func extractStackMaxStackFromMap(onMap map[string]any) (int, bool) { + for _, triggerName := range []string{"pull_request", "pull_request_review"} { + triggerValue, hasTrigger := onMap[triggerName] + if !hasTrigger { + continue + } + triggerMap, ok := triggerValue.(map[string]any) + if !ok { + continue + } + maxStackValue, hasMaxStack := triggerMap["max-stack"] + if !hasMaxStack { + continue + } + switch v := maxStackValue.(type) { + case int: + return v, true + case int64: return int(v), true + case uint: + return int(v), true + case uint64: + return int(v), true + case float64: + if v == float64(int(v)) { + return int(v), true + } } } diff --git a/pkg/workflow/filters_stack_integration_test.go b/pkg/workflow/filters_stack_integration_test.go index da9dd1514da..00d8ca22eff 100644 --- a/pkg/workflow/filters_stack_integration_test.go +++ b/pkg/workflow/filters_stack_integration_test.go @@ -60,6 +60,19 @@ permissions: contents: read --- +Test workflow. +`, + }, + { + name: "pull_request_review default max-stack (1) uses equality not arithmetic", + workflowBody: `--- +on: + pull_request_review: + types: [submitted] +permissions: + contents: read +--- + Test workflow. `, }, @@ -147,3 +160,42 @@ Test workflow. } } } + +func TestStackFilterPullRequestReviewMaxStack2UsesPreStep(t *testing.T) { + workflowBody := `--- +on: + pull_request_review: + types: [submitted] + max-stack: 2 +permissions: + contents: read +--- + +Test workflow. +` + tempDir := t.TempDir() + workflowPath := filepath.Join(tempDir, "test-workflow.md") + err := os.WriteFile(workflowPath, []byte(workflowBody), 0644) + require.NoError(t, err) + + compiler := NewCompiler() + err = compiler.CompileWorkflow(workflowPath) + require.NoError(t, err) + + lockPath := stringutil.MarkdownToLockFile(workflowPath) + lockContent, err := os.ReadFile(lockPath) + require.NoError(t, err) + + lockStr := string(lockContent) + require.Contains(t, lockStr, "Stack position gate (max-stack: 2)") + require.Contains(t, lockStr, "github.event_name == 'pull_request_review'") + + for _, line := range strings.Split(lockStr, "\n") { + trimmed := strings.TrimSpace(line) + if strings.HasPrefix(trimmed, "if: ") { + ifValue := strings.TrimPrefix(trimmed, "if: ") + require.NotContains(t, ifValue, "stack.position +", + "job-level if: must not contain arithmetic operators for pull_request_review max-stack: 2.\nLine: %s", line) + } + } +} diff --git a/pkg/workflow/filters_stack_test.go b/pkg/workflow/filters_stack_test.go index 89d214fcb8d..25ab5696b7e 100644 --- a/pkg/workflow/filters_stack_test.go +++ b/pkg/workflow/filters_stack_test.go @@ -49,6 +49,26 @@ func TestApplyPullRequestStackFilter_ConfiguredMaxStack(t *testing.T) { assert.NotContains(t, workflowData.If, "+", "job-level if must not contain arithmetic operators") } +func TestApplyPullRequestStackFilter_ConfiguredMaxStackInArrayTriggerForm(t *testing.T) { + compiler := NewCompiler() + workflowData := &WorkflowData{} + frontmatter := map[string]any{ + "on": []any{ + map[string]any{ + "pull_request": map[string]any{ + "types": []any{"opened"}, + "max-stack": 2, + }, + }, + }, + } + + compiler.applyPullRequestStackFilter(workflowData, frontmatter) + + assert.Empty(t, workflowData.If, "job-level if should not contain arithmetic for max-stack > 1") + assert.Contains(t, workflowData.PreSteps, "Stack position gate (max-stack: 2)") +} + func TestApplyPullRequestStackFilter_Disabled(t *testing.T) { compiler := NewCompiler() workflowData := &WorkflowData{If: "github.actor != 'dependabot[bot]'"} @@ -81,6 +101,39 @@ func TestApplyPullRequestStackFilter_SimplePullRequestTrigger(t *testing.T) { assert.NotContains(t, workflowData.If, "+", "job-level if must not contain arithmetic operators") } +func TestApplyPullRequestStackFilter_SimplePullRequestReviewTrigger(t *testing.T) { + compiler := NewCompiler() + workflowData := &WorkflowData{} + frontmatter := map[string]any{ + "on": "pull_request_review", + } + + compiler.applyPullRequestStackFilter(workflowData, frontmatter) + + assert.Contains(t, workflowData.If, "github.event_name != 'pull_request_review'") + assert.Contains(t, workflowData.If, "github.event.pull_request.stack.position == github.event.pull_request.stack.size") + assert.NotContains(t, workflowData.If, "+", "job-level if must not contain arithmetic operators") +} + +func TestApplyPullRequestStackFilter_PullRequestReviewConfiguredMaxStack(t *testing.T) { + compiler := NewCompiler() + workflowData := &WorkflowData{} + frontmatter := map[string]any{ + "on": map[string]any{ + "pull_request_review": map[string]any{ + "types": []any{"submitted"}, + "max-stack": 2, + }, + }, + } + + compiler.applyPullRequestStackFilter(workflowData, frontmatter) + + assert.Empty(t, workflowData.If, "job-level if should not contain arithmetic for max-stack > 1") + assert.Contains(t, workflowData.PreSteps, "Stack position gate (max-stack: 2)") + assert.Contains(t, workflowData.PreSteps, "github.event_name == 'pull_request_review'") +} + func TestApplyPullRequestStackFilter_NoPullRequestTrigger(t *testing.T) { compiler := NewCompiler() workflowData := &WorkflowData{If: "github.actor != 'dependabot[bot]'"} diff --git a/pkg/workflow/frontmatter_on_section_cleanup.go b/pkg/workflow/frontmatter_on_section_cleanup.go index 27c62fef7d4..31aae91811a 100644 --- a/pkg/workflow/frontmatter_on_section_cleanup.go +++ b/pkg/workflow/frontmatter_on_section_cleanup.go @@ -53,6 +53,7 @@ func newOnSectionLine(raw string) onSectionLine { type onSectionCleanupState struct { inPullRequest bool + inPullRequestReview bool inIssues bool inDiscussion bool inIssueComment bool @@ -119,7 +120,7 @@ func collectNativeLabelFilterSections(frontmatter map[string]any) map[string]str } func (s *onSectionCleanupState) inEventSection() bool { - return s.inPullRequest || s.inIssues || s.inDiscussion || s.inIssueComment + return s.inPullRequest || s.inPullRequestReview || s.inIssues || s.inDiscussion || s.inIssueComment } func (s *onSectionCleanupState) handleEventSectionEntry(info onSectionLine, result *[]string) bool { @@ -140,7 +141,7 @@ func (s *onSectionCleanupState) detectEventSection(info onSectionLine) (string, return "", false } switch info.trimmed { - case "pull_request:", "issues:", "discussion:", "issue_comment:", "deployment_status:", "workflow_run:": + case "pull_request:", "pull_request_review:", "issues:", "discussion:", "issue_comment:", "deployment_status:", "workflow_run:": return strings.TrimSuffix(info.trimmed, ":"), true default: return "", false @@ -152,6 +153,7 @@ func (s *onSectionCleanupState) activateEventSection(section string, indent int) s.inCommentBlock = false s.commentBlockIndent = "" s.inPullRequest = section == "pull_request" + s.inPullRequestReview = section == "pull_request_review" s.inIssues = section == "issues" s.inDiscussion = section == "discussion" s.inIssueComment = section == "issue_comment" @@ -198,6 +200,7 @@ func (s *onSectionCleanupState) leaveCurrentEventSection(info onSectionLine) { } if s.currentSectionIndent >= 0 && info.indent <= s.currentSectionIndent { s.inPullRequest = false + s.inPullRequestReview = false s.inIssues = false s.inDiscussion = false s.inIssueComment = false @@ -513,7 +516,7 @@ func (s *onSectionCleanupState) commentPullRequestAndTriggerField(info onSection switch { case s.inPullRequest && strings.Contains(info.trimmed, "draft:"): return true, " # Draft filtering applied via job conditions" - case s.inPullRequest && strings.HasPrefix(info.trimmed, "max-stack:"): + case (s.inPullRequest || s.inPullRequestReview) && strings.HasPrefix(info.trimmed, "max-stack:"): return true, " # Stack filtering applied via job conditions" case s.inPullRequest && strings.HasPrefix(info.trimmed, "forks:"): return true, " # Fork filtering applied via job conditions" From 164467a4a96286e081ee2c2231de986c9014c7f8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2026 02:44:17 +0000 Subject: [PATCH 2/3] docs(adr): add draft ADR-49453 for pull_request_review max-stack gating Co-Authored-By: Claude Sonnet 4.6 --- ...max-stack-gating-to-pull-request-review.md | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 docs/adr/49453-extend-max-stack-gating-to-pull-request-review.md diff --git a/docs/adr/49453-extend-max-stack-gating-to-pull-request-review.md b/docs/adr/49453-extend-max-stack-gating-to-pull-request-review.md new file mode 100644 index 00000000000..c2d516a08d4 --- /dev/null +++ b/docs/adr/49453-extend-max-stack-gating-to-pull-request-review.md @@ -0,0 +1,62 @@ +# ADR-49453: Extend `max-stack` Gating to `pull_request_review` Events + +**Date**: 2026-08-01 +**Status**: Draft +**Deciders**: pelikhan, copilot-swe-agent + +--- + +### Context + +The gh-aw workflow compiler introduced stacked PR support (ADR from PR #49420) that gates workflow runs using a `max-stack` filter on `pull_request` events: by default only the top-of-stack PR triggers runs, with `max-stack: N` to allow the top N layers and `max-stack: -1` to disable filtering entirely. + +However, this gating was only applied to `pull_request` event triggers. `pull_request_review` workflows were left ungated, so review-triggered runs executed on every layer of a stacked PR chain — not just the top. This broke the stack filter contract: a review submitted on an intermediate PR would trigger all workflows on that layer even when `max-stack: 1` was set. + +The `on.pull_request_review` section also lacked a `max-stack` configuration key in the workflow schema, so the setting could not be configured per-workflow. + +### Decision + +We will extend the `max-stack` gating logic to cover `pull_request_review` events, using the same semantics already established for `pull_request`: + +- Default (`max-stack: 1`): only the top-of-stack PR triggers the workflow. +- `max-stack: N`: the top N layers trigger the workflow. +- `max-stack: -1`: stack gating is disabled and all layers trigger. + +The `on.pull_request_review.max-stack` key is added to the workflow schema with the same value domain (`-1` or `>= 1`; `0` and other negative values are rejected). Compiled `.lock.yml` files are regenerated to apply the new `if:` conditions, and trigger-detection and `max-stack`-extraction paths are updated to handle both object and array `on:` forms consistently. + +### Alternatives Considered + +#### Alternative 1: Keep `pull_request_review` Ungated + +Leave review-event workflows running on every stack layer, accepting the inconsistency with `pull_request` event behavior. + +This was the status quo before this PR. It was rejected because it violates the stated intent of `max-stack`: users who configure stack gating on a workflow expect it to apply to all event types that workflow listens to, not just `pull_request`. Ungated review runs on lower stack layers create duplicate workflow execution and noisy CI feedback. + +#### Alternative 2: Separate `max-stack` Semantics for Review Events + +Introduce a distinct configuration key (e.g., `max-stack-review`) or different default behavior for `pull_request_review`, decoupling it from `pull_request` gating. + +This was rejected because it adds schema complexity without a clear benefit. The stack position concept is identical for both events (both carry `github.event.pull_request.stack`), and users configuring one event type expect the other to behave consistently. A separate knob would require users to duplicate configuration and reason about two separate gating policies. + +### Consequences + +#### Positive + +- `pull_request_review` workflows now respect `max-stack` gating, closing the gap in the stack filter contract. +- Schema is extended consistently, so `max-stack` is configurable for review events just as it is for PR events. +- Reduces redundant CI runs on lower stack layers when reviews are submitted, lowering resource consumption. +- Test coverage added for review-event stack filtering, default and configured `max-stack`, and schema validation. + +#### Negative + +- Workflows that previously ran on every stack layer when a review was submitted now run only on the top layer by default. Teams relying on the old (ungated) `pull_request_review` behavior may see unexpected workflow skips after this change. +- All affected compiled `.lock.yml` files must be regenerated, producing a large number of boilerplate changes across the repository that obscure the core logic change. + +#### Neutral + +- The `if:` condition expansion (`github.event_name != 'pull_request'` → `github.event_name != 'pull_request' && github.event_name != 'pull_request_review'`) is a mechanical change applied uniformly across every compiled workflow, making bulk review the only practical way to audit it. +- Unit and integration tests are updated/added to cover the new behavior; existing `pull_request` test coverage is not affected. + +--- + +*ADR created by [adr-writer agent]. Review and finalize before changing status from Draft to Accepted.* From 8dfbe75ec78713e01114632804cf5235c872f37d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Aug 2026 02:51:26 +0000 Subject: [PATCH 3/3] Strengthen pull_request_review max-stack tests: assert inequality and intermediate values Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/parser/schema_location_test.go | 10 ++++++++++ pkg/workflow/filters_stack_test.go | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/pkg/parser/schema_location_test.go b/pkg/parser/schema_location_test.go index a9b5dbf5a5c..be89df5b519 100644 --- a/pkg/parser/schema_location_test.go +++ b/pkg/parser/schema_location_test.go @@ -664,6 +664,11 @@ func TestValidateMainWorkflowFrontmatterWithSchemaAndLocation_MaxStack(t *testin maxStack: 2, wantErr: false, }, + { + name: "max-stack: 5 is valid (intermediate value)", + maxStack: 5, + wantErr: false, + }, { name: "max-stack: -1 is valid (disable stack protection)", maxStack: -1, @@ -728,6 +733,11 @@ func TestValidateMainWorkflowFrontmatterWithSchemaAndLocation_PullRequestReviewM maxStack: 2, wantErr: false, }, + { + name: "max-stack: 5 is valid (intermediate value)", + maxStack: 5, + wantErr: false, + }, { name: "max-stack: -1 is valid (disable stack protection)", maxStack: -1, diff --git a/pkg/workflow/filters_stack_test.go b/pkg/workflow/filters_stack_test.go index 25ab5696b7e..7f3b3b840b9 100644 --- a/pkg/workflow/filters_stack_test.go +++ b/pkg/workflow/filters_stack_test.go @@ -131,7 +131,11 @@ func TestApplyPullRequestStackFilter_PullRequestReviewConfiguredMaxStack(t *test assert.Empty(t, workflowData.If, "job-level if should not contain arithmetic for max-stack > 1") assert.Contains(t, workflowData.PreSteps, "Stack position gate (max-stack: 2)") + assert.Contains(t, workflowData.PreSteps, "max_stack=2") + // Intermediate positions are gated via inequality: skip when position + N <= size + assert.Contains(t, workflowData.PreSteps, "STACK_POSITION + max_stack <= STACK_SIZE") assert.Contains(t, workflowData.PreSteps, "github.event_name == 'pull_request_review'") + assert.NotContains(t, workflowData.If, "+", "job-level if must not contain arithmetic operators") } func TestApplyPullRequestStackFilter_NoPullRequestTrigger(t *testing.T) {