Skip to content

fix(full-loop-helper): if-form capture for gh pr merge under set -e#18750

Merged
marcusquinn merged 1 commit intomainfrom
hotfix/full-loop-merge-set-e-capture
Apr 13, 2026
Merged

fix(full-loop-helper): if-form capture for gh pr merge under set -e#18750
marcusquinn merged 1 commit intomainfrom
hotfix/full-loop-merge-set-e-capture

Conversation

@marcusquinn
Copy link
Copy Markdown
Owner

Summary

PR #18748 shipped the --admin fallback for branch-protection rejections (GH#18538), but the implementation used a bare command-substitution under set -euo pipefail that exits the script before the exit-code capture runs. The fallback never triggers; the function silently returns 0 without merging.

Switch to the if-form which is portable across bash versions and respects errexit semantics.

How it was found

PR #18748 self-merged successfully via its own --admin fallback — but only because I had this if-form fix applied locally and uncommitted in the worktree at the time I ran the wrapper. The actual merged code was the bare-assignment version, which I verified by checking out fresh main and running the function — it returns silently without printing the fallback path.

Diff

-	local _merge_out _merge_rc
-	_merge_out=$(gh pr merge "$pr_number" --repo "$repo" "$merge_method" 2>&1)
-	_merge_rc=$?
+	local _merge_out _merge_rc=0
+	if _merge_out=$(gh pr merge "$pr_number" --repo "$repo" "$merge_method" 2>&1); then
+		_merge_rc=0
+	else
+		_merge_rc=$?
+	fi

Testing

  • bash -n clean
  • shellcheck clean (only the pre-existing SC1091 from shared-constants.sh source)
  • This PR's own merge will be the live test — if the fallback works, the wrapper proves itself.

Ref #18538



aidevops.sh v3.8.10 plugin for OpenCode v1.4.3 with claude-opus-4-6 spent 17h 59m and 69,753 tokens on this with the user in an interactive session.

…r set -e

PR #18748 shipped the --admin fallback for branch-protection rejections
(GH#18538), but used a bare assignment to capture the merge output:

    _merge_out=$(gh pr merge ... 2>&1)
    _merge_rc=$?

Under `set -euo pipefail` (line 8), a failing command substitution
exits the script before `_merge_rc=$?` runs. The function silently
returns, the --admin fallback never triggers, and the wrapper looks
like it succeeded when in fact it bailed without merging anything.

Discovered by self-test: PR #18748 only merged because I had the
if-form fix applied locally and uncommitted in the worktree at the
time I ran the wrapper. The merged main code was the bare-assignment
version and would have failed silently for the next worker.

Switch to the if-form which is portable across all bash versions and
respects errexit semantics:

    if _merge_out=$(gh pr merge ... 2>&1); then
        _merge_rc=0
    else
        _merge_rc=$?
    fi

Ref #18538
@marcusquinn marcusquinn added the origin:interactive Auto-created from TODO.md tag label Apr 13, 2026
@gemini-code-assist
Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 13, 2026

Important

Review skipped

Auto reviews are limited based on label configuration.

🚫 Review skipped — only excluded labels are configured. (1)
  • no-review

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0652ccb6-3042-4b82-9ac1-2d53b04c0eb4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hotfix/full-loop-merge-set-e-capture

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 and usage tips.

@github-actions github-actions bot added the bug Auto-created from TODO.md tag label Apr 13, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

SonarCloud: 0 bugs, 0 vulnerabilities, 226 code smells

Mon Apr 13 22:31:42 UTC 2026: Code review monitoring started
Mon Apr 13 22:31:43 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 226

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 226
  • VULNERABILITIES: 0

Generated on: Mon Apr 13 22:31:45 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@marcusquinn marcusquinn merged commit bda72d9 into main Apr 13, 2026
35 of 36 checks passed
@marcusquinn marcusquinn deleted the hotfix/full-loop-merge-set-e-capture branch April 13, 2026 22:32
@codacy-production
Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

TIP This summary will be updated as you push new changes. Give us feedback

@sonarqubecloud
Copy link
Copy Markdown

marcusquinn added a commit that referenced this pull request Apr 13, 2026
… discipline

Captures the lesson from the GH#18538 session where PR #18748 shipped a
`set -e` bug in full-loop-helper.sh's --admin fallback that the local
self-test passed only because of an uncommitted if-form fix in the
worktree. PR #18750 was the hotfix.

The brief proposes adding a 'Self-modifying tooling test discipline'
subsection to prompts/build.txt with the rule and the evidence chain.

Ref #18538
marcusquinn added a commit that referenced this pull request Apr 13, 2026
…ment task (#18754)

* plan(t2062): file self-improvement task — self-modifying tooling test discipline

Captures the lesson from the GH#18538 session where PR #18748 shipped a
`set -e` bug in full-loop-helper.sh's --admin fallback that the local
self-test passed only because of an uncommitted if-form fix in the
worktree. PR #18750 was the hotfix.

The brief proposes adding a 'Self-modifying tooling test discipline'
subsection to prompts/build.txt with the rule and the evidence chain.

Ref #18538

* chore(t2062): stamp ref:GH#18753 from issue-sync
marcusquinn added a commit that referenced this pull request Apr 13, 2026
Extends cmd_merge arg parser to accept --admin and --auto flags and
pass them through to gh pr merge. Enables workers and interactive
sessions to use gh's native branch-protection escape hatches without
bypassing the sanctioned merge wrapper.

Design:
- Explicit --admin / --auto skip the error-retry fallback (intent is
  already set; retrying --admin when --admin was requested is a no-op,
  retrying --admin when --auto was requested would clobber queue intent).
- No-flag path preserves the GH#18538 / PR #18748 / PR #18750 branch-
  protection error-retry fallback verbatim.
- --auto success reports 'queued for auto-merge' (correct semantics:
  gh doesn't merge now, it queues when required checks pass).
- Bash 3.2 safe: empty array expansion uses ${arr[@]+"${arr[@]}"} —
  plain "${arr[@]}" under set -u raises 'unbound variable' on macOS
  default bash.

Verification:
- shellcheck clean (SC1091 info only, pre-existing source directive).
- bash -n syntax clean.
- 21/21 runtime assertions pass in /tmp/test-cmd-merge-parsing.sh covering:
  * bash 3.2 empty-array crash regression
  * --admin, --auto, --admin --auto, --rebase --admin pass-through
  * --admin failure suppresses retry (no duplicate gh call)
  * no-flag branch-protection failure still triggers fallback (#18748/#18750)
  * unknown flag rejection
- show_help usage line updated.

Closes #18731.
Context: #18725 (fix that surfaced this), t1382 review bot gate,
GH#17541 sanctioned merge path, #18748 (--admin fallback), #18750
(set -e capture fix), #18732 (superseded stale PR on same branch).
marcusquinn added a commit that referenced this pull request Apr 13, 2026
…31) (#18757)

Extends cmd_merge arg parser to accept --admin and --auto flags and
pass them through to gh pr merge. Enables workers and interactive
sessions to use gh's native branch-protection escape hatches without
bypassing the sanctioned merge wrapper.

Design:
- Explicit --admin / --auto skip the error-retry fallback (intent is
  already set; retrying --admin when --admin was requested is a no-op,
  retrying --admin when --auto was requested would clobber queue intent).
- No-flag path preserves the GH#18538 / PR #18748 / PR #18750 branch-
  protection error-retry fallback verbatim.
- --auto success reports 'queued for auto-merge' (correct semantics:
  gh doesn't merge now, it queues when required checks pass).
- Bash 3.2 safe: empty array expansion uses ${arr[@]+"${arr[@]}"} —
  plain "${arr[@]}" under set -u raises 'unbound variable' on macOS
  default bash.

Verification:
- shellcheck clean (SC1091 info only, pre-existing source directive).
- bash -n syntax clean.
- 21/21 runtime assertions pass in /tmp/test-cmd-merge-parsing.sh covering:
  * bash 3.2 empty-array crash regression
  * --admin, --auto, --admin --auto, --rebase --admin pass-through
  * --admin failure suppresses retry (no duplicate gh call)
  * no-flag branch-protection failure still triggers fallback (#18748/#18750)
  * unknown flag rejection
- show_help usage line updated.

Closes #18731.
Context: #18725 (fix that surfaced this), t1382 review bot gate,
GH#17541 sanctioned merge path, #18748 (--admin fallback), #18750
(set -e capture fix), #18732 (superseded stale PR on same branch).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Auto-created from TODO.md tag origin:interactive Auto-created from TODO.md tag

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant