Skip to content

feat: implement issue #929 — auto-rebase: regression test — an approved PR stays approved/mergeable after an eligible update - #933

Merged
don-petry merged 3 commits into
mainfrom
dev-lead/issue-929-20260803-0211
Aug 3, 2026
Merged

feat: implement issue #929 — auto-rebase: regression test — an approved PR stays approved/mergeable after an eligible update#933
don-petry merged 3 commits into
mainfrom
dev-lead/issue-929-20260803-0211

Conversation

@don-petry

@don-petry don-petry commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

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

  • Added end-to-end regression coverage for an approved, behind, conflict-free PR being updated through the auto-rebase workflow
  • Verifies the update uses a merge so the PR becomes current while remaining approved and mergeable
  • Confirms that a rebase would dismiss the approval, ensuring the test detects a regression

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:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

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:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

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

  • Tests
    • Added end-to-end coverage for automatic pull request updates.
    • Verified that approved pull requests remain approved, current, and mergeable when updated safely.
    • Confirmed that approvals are dismissed and merging is blocked when changes require a rebase.

…ed PR stays approved/mergeable after an eligible update
@don-petry
don-petry requested a review from a team as a code owner August 3, 2026 02:18
@codeant-ai

codeant-ai Bot commented Aug 3, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR 77c6a0c Aug 03, 2026 · 02:18 02:20

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@don-petry, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 14 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9b44e288-932e-4426-9c7d-7e10e86a012d

📥 Commits

Reviewing files that changed from the base of the PR and between 4648ee2 and 43adf91.

📒 Files selected for processing (1)
  • test/workflows/auto-rebase/approval-survival.bats
📝 Walkthrough

Walkthrough

Added 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.

Changes

Auto-rebase approval survival

Layer / File(s) Summary
Test fixture and modeled pull request state
test/workflows/auto-rebase/approval-survival.bats
Documents the scenario, prepares temporary state, and seeds an approved, behind, conflict-free, non-draft pull request.
Workflow execution and update behavior
test/workflows/auto-rebase/approval-survival.bats
Runs the extracted workflow block and models GitHub CLI updates, approval changes, and mergeability changes.
Approval survival assertions
test/workflows/auto-rebase/approval-survival.bats
Checks that merge updates preserve approval and mergeability. A control test checks that rebase updates dismiss approval and make the pull request unmergeable.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the auto-rebase approval-survival regression test requested by issue #929.
Linked Issues check ✅ Passed The test covers an approved, behind, conflict-free, non-draft PR that remains approved and mergeable after an auto-rebase update [#929].
Out of Scope Changes check ✅ Passed The pull request adds only the regression test required for the linked issue and contains no unrelated changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev-lead/issue-929-20260803-0211

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Aug 3, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low

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
  1. 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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add regression test ensuring auto-rebase updates preserve PR approval (issue #929)

🧪 Tests 🕐 10-20 Minutes

Grey Divider

AI Description

• Add end-to-end bats regression coverage for issue #929 approval/mergeability survival.
• Execute the reusable workflow’s real update run-block (extracted via yq) under test.
• Model GitHub update-branch behavior with a stubbed gh to catch merge→rebase regressions.
Diagram

graph TD
  T["approval-survival.bats"] --> W["auto-rebase-reusable.yml"] --> Y["yq: extract run"] --> R["run.sh (update block)"] --> G["gh stub"] --> S[("state files")]
  R --> L["eligibility.sh + comments.sh"]
Loading
High-Level Assessment

The chosen approach (extracting and executing the workflow’s real run-block with a local gh stub) is the best tradeoff: it’s drift-resistant, fully offline/deterministic, and validates the critical org-specific invariant that update_method=merge preserves approvals. Alternatives like running GitHub Actions via act or calling real GitHub APIs would be heavier, flakier, and require network/secrets.

Files changed (1) +172 / -0

Tests (1) +172 / -0
approval-survival.batsAdd end-to-end bats test asserting approvals survive auto-rebase merge updates +172/-0

Add end-to-end bats test asserting approvals survive auto-rebase merge updates

• Introduces an integration regression test for issue #929 by executing the reusable workflow’s "Update behind non-Dependabot PRs" run-block against a stubbed 'gh' CLI. The stub models the key semantic difference between merge vs rebase updates (approval preserved vs dismissed) and asserts the PR becomes up-to-date while remaining APPROVED/mergeable.

test/workflows/auto-rebase/approval-survival.bats

Comment on lines +49 to +55
# 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"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Fix in Cursor Fix in VSCode Claude

(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
👍 | 👎

Comment on lines +63 to +69
_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"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Fix in Cursor Fix in VSCode Claude

(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
👍 | 👎

@qodo-code-review

qodo-code-review Bot commented Aug 3, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (2) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 87 rules

Grey Divider


Remediation recommended

1. _install_gh_stub bypasses shared helper 📘 Rule violation ▣ Testability
Description
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.
Code

test/workflows/auto-rebase/approval-survival.bats[R42-45]

+  # `gh` stub on PATH — never touches the network.
+  TT_BIN="${TT_TMP}/bin"
+  mkdir -p "$TT_BIN"
+  _install_gh_stub
Relevance

●● Moderate

Repo has both shared tt_install_gh_stub (accepted) and bespoke gh stubs in tests; pattern not
consistently enforced.

PR-#422
PR-#616

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 2239150 requires using project-provided mocking helpers in tests when they exist.
The new test creates its own _install_gh_stub and installs it on PATH, while other suites in this
repo already provide a tt_install_gh_stub helper to install a gh stub, demonstrating an existing
shared pattern that this test bypasses.

Rule 2239150: Use project-provided test helpers to mock external services
test/workflows/auto-rebase/approval-survival.bats[42-47]
test/workflows/auto-rebase/approval-survival.bats[71-79]
test/workflows/feature-ideation/helpers/setup.bash[29-42]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## 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


2. approval-survival.bats not under integration 📘 Rule violation ▣ Testability
Description
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.
Code

test/workflows/auto-rebase/approval-survival.bats[R2-3]

+# Integration regression test for issue #929 (part of #926, AC8):
+# an APPROVED PR stays approved/mergeable after an eligible auto-rebase update.
Relevance

●● Moderate

No historical evidence found enforcing integration-vs-unit separation by directory name under
test/workflows.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 2238326 requires integration tests to reside under a directory whose name includes
integration. The added file self-identifies as an integration regression test, yet its path is
test/workflows/auto-rebase/... (no integration directory), so the new addition violates the
directory-naming separation requirement.

Rule 2238326: Integration tests must be separated from unit tests by directory naming
test/workflows/auto-rebase/approval-survival.bats[1-8]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## 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


3. Stub bypasses --jq logic 🐞 Bug ⚙ Maintainability
Description
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.
Code

test/workflows/auto-rebase/approval-survival.bats[R99-102]

+  *compare/*)
+    cat "${STATE_DIR}/behind"
+    exit 0
+    ;;
Relevance

●● Moderate

No close precedent on stubs validating gh api --jq; team does accept “non-vacuous”
test-strengthening sometimes.

PR-#740

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The reusable workflow depends on gh api ... --jq for PR enumeration, base branch, and behind
count, but the test stub ignores --jq and emits precomputed outputs based only on substring
matching, so jq regressions won’t be caught by this test.

.github/workflows/auto-rebase-reusable.yml[119-146]
test/workflows/auto-rebase/approval-survival.bats[49-55]
test/workflows/auto-rebase/approval-survival.bats[78-110]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### 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


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment on lines +2 to +3
# Integration regression test for issue #929 (part of #926, AC8):
# an APPROVED PR stays approved/mergeable after an eligible auto-rebase update.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

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

Comment on lines +42 to +45
# `gh` stub on PATH — never touches the network.
TT_BIN="${TT_TMP}/bin"
mkdir -p "$TT_BIN"
_install_gh_stub

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

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

Comment on lines +99 to +102
*compare/*)
cat "${STATE_DIR}/behind"
exit 0
;;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

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

@donpetry-bot

Copy link
Copy Markdown
Contributor

CI checks on this PR are still running. Once they complete, re-mention @donpetry-bot to trigger a fresh review.

Posted by the donpetry-bot PR-review cascade.

@don-petry
don-petry enabled auto-merge (squash) August 3, 2026 02:31
donpetry-bot
donpetry-bot previously approved these changes Aug 3, 2026

@donpetry-bot donpetry-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:), so yq is present and the suite runs on CI.
  • Qodo "integration tests must live under an integration/ directory" — not a repo standard. No integration/ directory exists anywhere under test/; the file's placement matches every existing suite (eligibility.bats, comments.bats, merge-method.bats in 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_stub helper" — no such helper exists. The suite's helpers/setup.bash provides 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 -qx style nit — non-blocking. The preceding grep -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 donpetry-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@donpetry-bot
donpetry-bot dismissed their stale review August 3, 2026 02:44

Superseded by automated re-review at 77c6a0c.

@don-petry don-petry left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-branch with update_method=merge preserves 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.

@don-petry
don-petry disabled auto-merge August 3, 2026 02:54
@don-petry

Copy link
Copy Markdown
Contributor Author

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.

@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — fix-bot-comment (applied)

Changes committed and pushed.

@don-petry
don-petry enabled auto-merge (squash) August 3, 2026 02:55
@don-petry
don-petry disabled auto-merge August 3, 2026 02:56
@sonarqubecloud

sonarqubecloud Bot commented Aug 3, 2026

Copy link
Copy Markdown

@don-petry
don-petry merged commit de298ab into main Aug 3, 2026
23 checks passed
@don-petry
don-petry deleted the dev-lead/issue-929-20260803-0211 branch August 3, 2026 02:58
@don-petry

Copy link
Copy Markdown
Contributor Author

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 (dismiss_stale_reviews_on_push: false, require_last_push_approval: false) and notes that the AC2 spike in .github-private#1437 was intended to verify this live but resolved architecturally without that test.

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 (require_last_push_approval: true, dismiss_stale_reviews_on_push: true) — that would need a live integration check against the real ruleset config, not a stub.

The merge-method assertions are untouched.

@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — review-changes (applied)

Changes committed and pushed.

@donpetry-bot

Copy link
Copy Markdown
Contributor

CI checks on this PR are still running. Once they complete, re-mention @donpetry-bot to trigger a fresh review.

Posted by the donpetry-bot PR-review cascade.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

auto-rebase: regression test — an approved PR stays approved/mergeable after an eligible update

2 participants