You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Restrict auto-rebase fan-out to review-ready PRs (free, plan-independent mitigation) #465
Implements the fan-out restriction from petry-projects/.github-private epic #736 / story #738 (idea discussion #735). The auto-rebase reusable currently calls update-branch on every behind non-Dependabot PR, generating ~170–220 redundant branch-update CI runs/day, most re-staled before review.
Change: In .github/workflows/auto-rebase-reusable.yml, narrow the "find behind non-Dependabot same-repo PRs" step so it updates a PR only if it is non-draft AND (has an APPROVED review OR carries an auto-rebase:ready label). Expose the predicate as a tunable workflow input so a "front-of-queue N" variant can be selected without a code change.
Must preserve: the merge-method update (so approvals aren't invalidated) and the <!-- auto-rebase-conflict: sentinel path (the agentic conflict-resolution feature). Dependabot/fork handling unchanged.
Implementer note: check the actual APPROVED review state (not only reviewDecision, which can be null without required-reviews). Update the source-of-truth docs standards/workflows/auto-rebase.yml and standards/ci-standards.md.
Acceptance criteria mirror .github-private story #738.
Narrow .github/workflows/auto-rebase-reusable.yml so it only updates a PR that is non-draft AND (has an APPROVED review OR carries the auto-rebase:ready label), exposing the predicate as a tunable eligible_filter workflow input — while preserving the merge-method update, the <!-- auto-rebase-conflict: sentinel path, and unchanged Dependabot/fork handling.
Implementation Checklist
.github/workflows/auto-rebase-reusable.yml — add eligible_filter input (default = review-ready predicate); replace candidate discovery with a single GraphQL query enriching each PR with isDraft, labels, and actual APPROVED review state (not reviewDecision), then apply the tunable predicate. Loop body (compare → update-branch merge → blocked/conflict sentinels) preserved verbatim.
.github/workflows/auto-rebase-tests.yml — new CI gate (shellcheck + bats) mirroring add-to-project-tests.yml.
standards/workflows/auto-rebase.yml — document the review-ready gate + tunable input in the header (source-of-truth template).
standards/ci-standards.md — update §8 (Auto-Rebase) to describe the gate and input.
Tests to Write
test/workflows/auto-rebase/eligible-filter.bats + helpers/setup.bash — extract the eligible_filter default from the reusable YAML and assert classification against PR fixtures:
non-draft + APPROVED → eligible
non-draft + auto-rebase:ready label → eligible
non-draft + no approval + no label → excluded
draft (even if approved/labelled) → excluded
default filter over a mixed set selects exactly the review-ready PRs
a front-of-queue-style override filter selects a different subset (tunable without code change)
Narrow the auto-rebase reusable so it only updates a behind, non-Dependabot, same-repo PR when the PR is non-draft AND (has a current APPROVED review OR carries the auto-rebase:ready label), exposing the predicate as a tunable eligibility workflow input. Merge-method update, the <!-- auto-rebase-conflict: sentinel path, and Dependabot/fork handling are preserved unchanged.
Add .github/scripts/auto-rebase/README.md — contract docs for the lib
Edit .github/workflows/auto-rebase-reusable.yml — add eligibility (default review-ready), ready_label (default auto-rebase:ready), and tooling_ref (default v1) inputs; checkout tooling; source the lib; gate update-branch on the predicate using the actual APPROVED review state (reviews API, not reviewDecision)
Add .github/workflows/auto-rebase-tests.yml — CI gate (shellcheck + bats), mirroring feature-ideation-tests.yml
Update standards/workflows/auto-rebase.yml — document the new gating + tunable input (thin caller unchanged functionally)
Update standards/ci-standards.md §8 — describe eligibility gating and the eligibility input
Wired the predicate into auto-rebase-reusable.yml behind a tunable eligibility input (checks out tooling, sources the lib, gates update-branch)
Approval determined from actual review states (latest decision review per reviewer wins), not reviewDecision
Preserved the merge-method update and the <!-- auto-rebase-conflict: sentinel path; Dependabot/fork handling unchanged
Added CI gate auto-rebase-tests.yml (shellcheck + bats)
Updated source-of-truth docs: standards/workflows/auto-rebase.yml and standards/ci-standards.md §8
Behavior
A behind, non-Dependabot, same-repo PR is now updated only when eligible:
eligibility
Updates a behind PR when…
review-ready (default)
non-draft AND (current APPROVED review OR carries ready_label, default auto-rebase:ready)
all
always (restores the prior unrestricted fan-out)
New modes (e.g. "front-of-queue N") can be added to the lib and selected via the input with no workflow change.
Test Results
# bats test/workflows/auto-rebase/ → 18/18 pass
ok 1 has_current_approval: single APPROVED review counts as approved
ok 4 has_current_approval: reviewer who approved then requested changes is not approved
ok 5 has_current_approval: reviewer who requested changes then approved is approved
ok 7 has_current_approval: a dismissed approval is not approved
ok 12 pr_eligible review-ready: non-draft + approved is eligible
ok 13 pr_eligible review-ready: non-draft + ready label is eligible
ok 15 pr_eligible review-ready: draft is ineligible even when approved
ok 16 pr_eligible all: always eligible (legacy fan-out escape hatch)
ok 18 pr_eligible: unknown mode errors out (exit 2)
# Full suite: bats -r test/ → 220/220 pass
# shellcheck -x .github/scripts/auto-rebase/lib/eligibility.sh → clean
# bash .dev-lead/scripts/dev-lead-lint.sh → all checks passed
# markdownlint-cli2 (README + ci-standards.md) → 0 errors
.github/workflows/auto-rebase-tests.yml (new): shellcheck + bats CI gate
test/workflows/auto-rebase/eligibility.bats + helpers/setup.bash (new): unit tests
standards/workflows/auto-rebase.yml: documents the new gating + override inputs
standards/ci-standards.md: §8 updated with eligibility table and approval semantics
Notes
Approval edge cases covered by tests: approve→changes-requested (not approved), changes-requested→approve (approved), later COMMENTED doesn't cancel approval, dismissed approval excluded, multi-reviewer.
The reusable now checks out petry-projects/.github@tooling_ref (default v1) to source the lib, matching the feature-ideation pattern. Existing thin-caller stubs need no change — all new inputs default to the restrictive behavior.
Activity
don-petry commentedon Jun 15, 2026
Dev-Lead Implementation Plan
Issue: #465 — Restrict auto-rebase fan-out to review-ready PRs (free, plan-independent mitigation)
Scope
Narrow
.github/workflows/auto-rebase-reusable.ymlso it only updates a PR that is non-draft AND (has an APPROVED review OR carries theauto-rebase:readylabel), exposing the predicate as a tunableeligible_filterworkflow input — while preserving the merge-method update, the<!-- auto-rebase-conflict:sentinel path, and unchanged Dependabot/fork handling.Implementation Checklist
.github/workflows/auto-rebase-reusable.yml— addeligible_filterinput (default = review-ready predicate); replace candidate discovery with a single GraphQL query enriching each PR withisDraft,labels, and actual APPROVED review state (notreviewDecision), then apply the tunable predicate. Loop body (compare → update-branch merge → blocked/conflict sentinels) preserved verbatim..github/workflows/auto-rebase-tests.yml— new CI gate (shellcheck + bats) mirroringadd-to-project-tests.yml.standards/workflows/auto-rebase.yml— document the review-ready gate + tunable input in the header (source-of-truth template).standards/ci-standards.md— update §8 (Auto-Rebase) to describe the gate and input.Tests to Write
test/workflows/auto-rebase/eligible-filter.bats+helpers/setup.bash— extract theeligible_filterdefault from the reusable YAML and assert classification against PR fixtures:auto-rebase:readylabel → eligibleTest Command
bats --print-output-on-failure test/workflows/auto-rebase/don-petry commentedon Jun 15, 2026
Dev-Lead Implementation Plan
Issue: #465 — Restrict auto-rebase fan-out to review-ready PRs (free, plan-independent mitigation)
Scope
Narrow the auto-rebase reusable so it only updates a behind, non-Dependabot, same-repo PR when the PR is non-draft AND (has a current APPROVED review OR carries the
auto-rebase:readylabel), exposing the predicate as a tunableeligibilityworkflow input. Merge-method update, the<!-- auto-rebase-conflict:sentinel path, and Dependabot/fork handling are preserved unchanged.Implementation Checklist
.github/scripts/auto-rebase/lib/eligibility.sh— pure, sourceable predicate functions (auto_rebase_has_current_approval,auto_rebase_has_ready_label,auto_rebase_pr_eligible).github/scripts/auto-rebase/README.md— contract docs for the lib.github/workflows/auto-rebase-reusable.yml— addeligibility(defaultreview-ready),ready_label(defaultauto-rebase:ready), andtooling_ref(defaultv1) inputs; checkout tooling; source the lib; gateupdate-branchon the predicate using the actual APPROVED review state (reviews API, notreviewDecision).github/workflows/auto-rebase-tests.yml— CI gate (shellcheck + bats), mirroringfeature-ideation-tests.ymlstandards/workflows/auto-rebase.yml— document the new gating + tunable input (thin caller unchanged functionally)standards/ci-standards.md§8 — describe eligibility gating and theeligibilityinputTests to Write
test/workflows/auto-rebase/eligibility.bats+helpers/setup.bashauto_rebase_has_current_approval: APPROVED present; latest-per-reviewer wins (approve→changes_requested = not approved); dismissed approval excluded; COMMENTED ignored; empty arrayauto_rebase_has_ready_label: label present / absent / empty labelsauto_rebase_pr_eligible: review-ready gates draft out; approved-only eligible; label-only eligible; neither = ineligible;allmode always eligible; unknown mode errorsTest Command
bats test/workflows/auto-rebase/(full suite:bats -r test/)don-petry commentedon Jun 15, 2026
Dev-Lead: Implementation Complete
Plan Execution
.github/scripts/auto-rebase/lib/eligibility.sh) + contract READMEauto-rebase-reusable.ymlbehind a tunableeligibilityinput (checks out tooling, sources the lib, gatesupdate-branch)reviewDecisionmerge-method update and the<!-- auto-rebase-conflict:sentinel path; Dependabot/fork handling unchangedauto-rebase-tests.yml(shellcheck + bats)standards/workflows/auto-rebase.ymlandstandards/ci-standards.md§8Behavior
A behind, non-Dependabot, same-repo PR is now updated only when eligible:
eligibilityreview-ready(default)APPROVEDreview OR carriesready_label, defaultauto-rebase:ready)allNew modes (e.g. "front-of-queue N") can be added to the lib and selected via the input with no workflow change.
Test Results
Files Changed
.github/scripts/auto-rebase/lib/eligibility.sh(new): predicate functions.github/scripts/auto-rebase/README.md(new): contract docs.github/workflows/auto-rebase-reusable.yml: tunable inputs, tooling checkout, eligibility gate.github/workflows/auto-rebase-tests.yml(new): shellcheck + bats CI gatetest/workflows/auto-rebase/eligibility.bats+helpers/setup.bash(new): unit testsstandards/workflows/auto-rebase.yml: documents the new gating + override inputsstandards/ci-standards.md: §8 updated with eligibility table and approval semanticsNotes
petry-projects/.github@tooling_ref(defaultv1) to source the lib, matching the feature-ideation pattern. Existing thin-caller stubs need no change — all new inputs default to the restrictive behavior.feat: implement issue #465 — Restrict auto-rebase fan-out to review-r…
fix(auto-rebase): source predicate from reusable's own commit, not @v1 …
fix(auto-rebase): surface skipped-but-conflicting PRs instead of sile…
Add the persona @-mention router (#754)