feat: implement issue #929 — auto-rebase: regression test — an approved PR stays approved/mergeable after an eligible update - #933
Conversation
…ed PR stays approved/mergeable after an eligible update
🤖 CodeAnt AI — Review Status
|
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning Review limit reached
Next review available in: 14 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdded a Bats end-to-end regression suite for auto-rebase approval survival. The suite models GitHub CLI responses, executes the reusable workflow update step, and verifies merge and rebase outcomes. ChangesAuto-rebase approval survival
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request adds a new integration regression test suite (approval-survival.bats) to verify that approved pull requests remain approved and mergeable after being updated via the auto-rebase workflow. Feedback suggests improving the BATS test assertion when checking for the absence of a pattern with grep by explicitly asserting an exit status of 1, preventing false positives from other failures.
| [[ "$output" == *"Branch updated"* ]] | ||
| # It updated with the approval-preserving method, never rebase. | ||
| grep -qx "merge" "${STATE_DIR}/update-methods.log" | ||
| ! grep -qx "rebase" "${STATE_DIR}/update-methods.log" |
There was a problem hiding this comment.
When using grep in BATS tests to assert the absence of a pattern, assert that the exit status is exactly 1 ([ "$status" -eq 1 ]) instead of using ! or checking for any non-zero status. This prevents false positives where other errors (such as a missing file or grep syntax error, which return exit status 2) cause the test to pass incorrectly.
run grep -qx "rebase" "${STATE_DIR}/update-methods.log"
[ "$status" -eq 1 ]
References
- When using grep in BATS tests to assert the absence of a pattern, assert that the exit status is exactly 1 ([ "$status" -eq 1 ]) instead of any non-zero status ([ "$status" -ne 0 ]). This prevents false positives where other errors (such as a missing file or grep syntax error, which return exit status 2) cause the test to pass incorrectly.
There was a problem hiding this comment.
Fixed in commit 4344a79: replaced ! grep -qx "rebase" with run grep -qx "rebase" / [ "$status" -eq 1 ] at line 145–146. This explicitly asserts exit status 1 (not-found) rather than any non-zero status, so a grep error (exit 2) no longer produces a false-positive pass.
PR Summary by QodoAdd regression test ensuring auto-rebase updates preserve PR approval (issue #929)
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
| # Extract the reusable's update run-block verbatim so we exercise the real | ||
| # workflow logic, not a hand-copied paraphrase of it. | ||
| RUN_SCRIPT="${TT_TMP}/run.sh" | ||
| yq -r '.jobs.auto-rebase.steps[] | ||
| | select(.name == "Update behind non-Dependabot PRs") | ||
| | .run' "$REUSABLE" > "$RUN_SCRIPT" | ||
| } |
There was a problem hiding this comment.
Suggestion: The test setup requires yq, but the auto-rebase test workflow installs only bats, shellcheck, and jq. On the configured CI runner, yq is unavailable, so every test fails during setup before the workflow run-block is exercised. Install yq explicitly or extract the YAML using an already-provisioned tool. [possible bug]
Severity Level: Major ⚠️
- ❌ CI fails before approval-survival tests execute.
- ⚠️ Auto-rebase regression coverage is unavailable.(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** test/workflows/auto-rebase/approval-survival.bats
**Line:** 49:55
**Comment:**
*Possible Bug: The test setup requires `yq`, but the auto-rebase test workflow installs only `bats`, `shellcheck`, and `jq`. On the configured CI runner, `yq` is unavailable, so every test fails during setup before the workflow run-block is exercised. Install `yq` explicitly or extract the YAML using an already-provisioned tool.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| _seed_approved_behind_pr() { | ||
| printf '1 feature-branch\n' > "${STATE_DIR}/pr_list" | ||
| printf 'main\n' > "${STATE_DIR}/base_ref" | ||
| printf '3\n' > "${STATE_DIR}/behind" | ||
| printf 'APPROVED\n' > "${STATE_DIR}/review_decision" | ||
| printf 'true\n' > "${STATE_DIR}/mergeable" | ||
| } |
There was a problem hiding this comment.
Suggestion: The seeded PR-list response is already reduced to an eligible PR, while the gh stub ignores the workflow's --jq filter. Consequently, a regression removing the Dependabot, fork, or same-repository filters would still pass because the fixture has pre-applied those filters and never supplies the fields needed to evaluate them. Return a JSON PR object containing those attributes and validate that the filtering is performed by the extracted run-block. [incomplete implementation]
Severity Level: Major ⚠️
- ⚠️ Workflow eligibility-filter regressions can escape this suite.
- ⚠️ Dependabot or fork branches could be updated unintentionally.(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** test/workflows/auto-rebase/approval-survival.bats
**Line:** 63:69
**Comment:**
*Incomplete Implementation: The seeded PR-list response is already reduced to an eligible PR, while the `gh` stub ignores the workflow's `--jq` filter. Consequently, a regression removing the Dependabot, fork, or same-repository filters would still pass because the fixture has pre-applied those filters and never supplies the fields needed to evaluate them. Return a JSON PR object containing those attributes and validate that the filtering is performed by the extracted run-block.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
Code Review by Qodo
Context used✅ Compliance rules (platform):
87 rules 1. _install_gh_stub bypasses shared helper
|
| # Integration regression test for issue #929 (part of #926, AC8): | ||
| # an APPROVED PR stays approved/mergeable after an eligible auto-rebase update. |
There was a problem hiding this comment.
1. approval-survival.bats not under integration 📘 Rule violation ▣ Testability
This file is explicitly described as an integration regression test but is located under test/workflows/... instead of a directory whose name includes integration. This violates the required unit/integration test separation by directory naming and can make CI test selection/gating unreliable.
Agent Prompt
## Issue description
`test/workflows/auto-rebase/approval-survival.bats` is written/labelled as an integration regression test, but it is not placed under a directory whose name includes `integration`, as required by the compliance rule.
## Issue Context
The test header comment states it is an “Integration regression test”, and it drives the reusable workflow run-block end-to-end (integration-style). The compliance checklist requires integration tests to live under a dedicated `integration` directory.
## Fix Focus Areas
- test/workflows/auto-rebase/approval-survival.bats[1-172]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| # `gh` stub on PATH — never touches the network. | ||
| TT_BIN="${TT_TMP}/bin" | ||
| mkdir -p "$TT_BIN" | ||
| _install_gh_stub |
There was a problem hiding this comment.
2. _install_gh_stub bypasses shared helper 📘 Rule violation ▣ Testability
The new test implements a bespoke gh stub and PATH setup inline instead of using the repo’s established tt_install_gh_stub helper pattern used in other test suites. This violates the requirement to use project-provided test helpers for mocking external services when such helpers exist, and increases duplication/inconsistency.
Agent Prompt
## Issue description
`approval-survival.bats` adds an ad-hoc `_install_gh_stub` implementation to mock `gh`, rather than using the repo’s standard `tt_install_gh_stub` helper approach used elsewhere.
## Issue Context
Other workflow test suites provide a reusable `tt_install_gh_stub` helper (and a `stubs/gh` script) to ensure consistent behavior and avoid duplicating stub logic across tests. This new test currently embeds a custom stub generator and PATH wiring.
## Fix Focus Areas
- test/workflows/auto-rebase/approval-survival.bats[42-115]
- test/workflows/auto-rebase/helpers/setup.bash[1-21]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| *compare/*) | ||
| cat "${STATE_DIR}/behind" | ||
| exit 0 | ||
| ;; |
There was a problem hiding this comment.
3. Stub bypasses --jq logic 🐞 Bug ⚙ Maintainability
The gh stub returns canned, already-filtered text for gh api ... --jq ... calls without validating or exercising the workflow’s jq expressions, so a broken/changed --jq filter (or API-shape expectation) in the real reusable could still pass this “end-to-end” test. This reduces the test’s effectiveness as a regression guard for the actual run-block behavior.
Agent Prompt
### Issue description
The new integration test stubs `gh` by matching on URL substrings and printing pre-shaped outputs, but it does not validate (or execute) the `--jq` expressions used by the real reusable workflow. This means regressions to the jq filters in `.github/workflows/auto-rebase-reusable.yml` may not be detected.
### Issue Context
The workflow relies on `gh api ... --jq ...` to shape outputs that are then parsed/used by bash control flow. The stub currently ignores the jq argument entirely and returns the final shaped text.
### Fix Focus Areas
- test/workflows/auto-rebase/approval-survival.bats[71-112]
Suggested implementation options:
1) **Add explicit assertions on the recorded gh calls** (simplest): after `_run_workflow`, assert `${STATE_DIR}/gh-calls.log` contains the expected `--jq` snippets for:
- PR list call (`pulls?state=open...`)
- base branch call (`--jq '.base.ref'`)
- compare call (`--jq '.behind_by'`)
2) **Make the stub enforce jq presence/values**: in each case arm, require `--jq` and check its value matches the expected expression; otherwise `exit 1` so the test fails.
3) **Higher fidelity**: have the stub output minimal JSON and apply the passed `--jq` using `jq` (if available) so jq breakage is truly exercised.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
CI checks on this PR are still running. Once they complete, re-mention Posted by the donpetry-bot PR-review cascade. |
donpetry-bot
left a comment
There was a problem hiding this comment.
Automated review — APPROVED ✓
Risk: LOW
Reviewed commit: 77c6a0c726afe76196991ede6e19b2f42016b6bc
Review mode: triage-approved (single reviewer)
Summary
Test-only PR adding test/workflows/auto-rebase/approval-survival.bats (+172/-0): an end-to-end regression suite for issue #929 proving an APPROVED, behind, conflict-free PR is updated via update_method=merge and stays approved/mergeable. It extracts the reusable workflow's real "Update behind non-Dependabot PRs" run-block via yq and drives it against a local gh stub that models merge-vs-rebase approval semantics, including a control test proving the assertions are non-vacuous. Confirms the triage-tier low-risk assessment: no workflow, script, or security-sensitive files touched.
Linked issue analysis
Closes #929 (part of #926, AC8), which asks for exactly this: bats/integration coverage that a behind, conflict-free, non-draft, APPROVED PR remains approved/mergeable after an auto-rebase update. The four added tests cover update-happens, ends-up-to-date, stays-approved/mergeable, and a rebase-would-dismiss control. The issue's note about extending coverage after the .github-private approval-survival spike is explicitly future work and does not block this PR. Substantively addressed.
Findings
No blocking findings. Bot review threads were evaluated individually:
- CodeAnt "Major: yq unavailable on CI runner" — refuted. The "Lint and bats" check on this head SHA executed all 4 new tests successfully (
ok 1..4 approval-survival:), soyqis present and the suite runs on CI. - Qodo "integration tests must live under an
integration/directory" — not a repo standard. Nointegration/directory exists anywhere undertest/; the file's placement matches every existing suite (eligibility.bats,comments.bats,merge-method.batsin the same dir). AGENTS.md requires integration tests be "clearly marked", which the header comment does, and CI runs them. - Qodo "bypasses shared
tt_install_gh_stubhelper" — no such helper exists. The suite'shelpers/setup.bashprovides only repo-root and tmpdir helpers. - CodeAnt/Qodo "stub pre-filters the PR list, so --jq eligibility filters aren't exercised" — accurate but out of scope. Eligibility filtering is unit-tested in
eligibility.bats; this suite deliberately targets approval survival. - Gemini (low)
! grep -qxstyle nit — non-blocking. The precedinggrep -qx "merge"on the same file already fails the test if the log file is missing.
Secret scanning: run_secret_scanning MCP tool unavailable in this environment; gitleaks CI check passed and the diff contains no credentials (the stub's GH_TOKEN="stub-token" is a dummy placeholder).
CI status
All required checks green on 77c6a0c: Lint and bats ✓ (new tests executed and passing), ShellCheck ✓, CodeQL ✓, Agent Security Scan ✓, Secret scan (gitleaks) ✓, agent-shield ✓, SonarCloud quality gate ✓, npm audit ✓. Cancelled dev-lead dispatch/ci-relay entries are superseded runs (final dispatch succeeded); remaining skips are ecosystem-conditional audits.
Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.
donpetry-bot
left a comment
There was a problem hiding this comment.
Automated review — APPROVED ✓
Risk: LOW
Reviewed commit: 77c6a0c726afe76196991ede6e19b2f42016b6bc
Review mode: triage-approved (single reviewer)
Summary
Test-only PR adding a new bats integration suite (test/workflows/auto-rebase/approval-survival.bats, +172/-0) that verifies an APPROVED, behind, conflict-free PR remains approved and mergeable after an eligible auto-rebase update. It extracts the reusable workflow's real 'Update behind non-Dependabot PRs' run-block via yq and drives it against a gh stub that models merge-vs-rebase approval-survival semantics, including a non-vacuity control test. Triage assessment (low-risk) is confirmed.
Linked issue analysis
Closes #929 (part of initiative #926, AC8). The issue asks for bats/integration coverage that a behind, conflict-free, non-draft, APPROVED PR gets updated by auto-rebase and stays approved/mergeable. The PR substantively addresses this: it seeds exactly that PR state, runs the real workflow run-block, asserts the update used the approval-preserving merge method, that the branch is up to date, and that review decision stays APPROVED / mergeable stays true, plus a control test proving a rebase would dismiss the approval. The issue's optional extension (ruleset-fix configuration, pending the .github-private spike) is explicitly future work and not required here.
Findings
No blocking findings.
- Security: none. Test-only change — no workflow, script, auth, or secret-adjacent code modified. No secrets in the diff (gitleaks CI check passed). The run_secret_scanning MCP tool was not available in this run; noted per policy, not a failure.
- Advisory bot threads (non-blocking): (1) CodeAnt claims yq is unavailable on the CI runner — contradicted by the green 'Lint and bats' check, which ran this suite (path filter covers test/workflows/auto-rebase/**); yq is preinstalled on ubuntu-latest. Minor hardening opportunity: add yq to the workflow's explicit install step so the suite doesn't depend on the runner image. (2) CodeAnt/Qodo note the gh stub ignores the --jq eligibility filters, so filter regressions wouldn't be caught here — accurate but out of scope; eligibility filtering is covered by eligibility.bats, and this suite's header documents its narrower purpose. (3) Gemini style nit on the '! grep -qx' absence assertion — functionally correct as written.
- Structure: well-scoped single-file PR with a clear header explaining scope and non-vacuity rationale.
CI status
All required checks green: Lint and bats ✓ (runs this new suite), ShellCheck ✓, CodeQL ✓, Agent Security Scan ✓, AgentShield ✓, Secret scan (gitleaks) ✓, SonarCloud quality gate ✓, npm audit ✓. Cancelled/skipped entries are superseded dispatch/relay runs and non-applicable ecosystem audits. mergeStateStatus BLOCKED only reflects the pending review requirement this cascade satisfies.
Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.
Superseded by automated re-review at 77c6a0c.
don-petry
left a comment
There was a problem hiding this comment.
The merge-method assertions in approval-survival.bats are a good, valuable regression guard — keep those. But the doc comments overstate what's actually verified:
update-branchwithupdate_method=mergepreserves the existing commits (no SHA rewrite) → an existing APPROVED review survives [...] the observable GitHub behavior this org relies on
This was never empirically confirmed. The original AC2 spike (petry-projects/.github-private#1437) was supposed to test this live — approve a real behind PR, let auto-rebase update it, observe whether the approval survives — but it resolved architecturally instead (actor-scoped ruleset bypass is infeasible) without ever running that live test. The actual reason approval survives in this org today is the fleet-wide ruleset relax applied across all 9 repos (dismiss_stale_reviews_on_push: false, require_last_push_approval: false on pr-quality) — not a confirmed inherent merge-vs-rebase GitHub behavior.
Since this test stubs gh itself (including the dismiss-on-push modeling), it can't catch a regression if the live ruleset were ever reverted to strict — it only proves the workflow requests merge method, which is real and worth keeping, but isn't the same claim as "approval survives."
Please: (1) correct the doc comments to attribute approval-survival to the ruleset relax rather than an unverified merge-vs-rebase behavior claim, and (2) add a note that this test cannot detect a future ruleset reversion — that would need a live/integration check against the real ruleset config, not a stub. The merge-method assertions themselves are fine as-is.
|
Fixed in test/workflows/auto-rebase/approval-survival.bats: corrected the doc comments to attribute approval-survival to this org's fleet-wide ruleset relax (dismiss_stale_reviews_on_push: false, require_last_push_approval: false) rather than an unverified GitHub behavior claim. Also added a note that this test cannot detect a future ruleset reversion — that would require a live integration check against the real ruleset config. |
Dev-Lead — fix-bot-comment (applied)Changes committed and pushed. |
|
|
Addressed your review in commit 4344a79. Change 1 — attribution corrected (per your point 1): The header no longer claims approval-survival is an empirically confirmed merge-vs-rebase GitHub behavior. It now attributes it to the fleet-wide pr-quality ruleset relax ( Change 2 — limitation note expanded (per your point 2): The existing one-line note is now explicit: this test cannot detect a future reversion of the pr-quality ruleset to strict settings ( The merge-method assertions are untouched. |
Dev-Lead — review-changes (applied)Changes committed and pushed. |
|
CI checks on this PR are still running. Once they complete, re-mention Posted by the donpetry-bot PR-review cascade. |



User description
Closes #929
Implemented by dev-lead agent. Please review.
CodeAnt-AI Description
Protect approved PRs from losing approval during automatic updates
What Changed
Impact
✅ Approved PRs remain mergeable after automatic updates✅ Behind branches are verified as updated✅ Approval-loss regressions are caught💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.
Summary by CodeRabbit