Skip to content

Fall back to unsigned push instead of failing when a rebase hits a genuine merge conflict in pushSigned提交 - #56568

Open
dsyme with Copilot wants to merge 7 commits into
mainfrom
copilot/resolve-merge-conflict
Open

Fall back to unsigned push instead of failing when a rebase hits a genuine merge conflict in pushSigned提交#56568
dsyme with Copilot wants to merge 7 commits into
mainfrom
copilot/resolve-merge-conflict

Conversation

Copilot AI commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

When an agent branch conflicted with content added to the base branch (e.g. both modified CHANGELOG.md), pushSigned提交 aborted the pre-replay rebase and threw. This caused create_pull_request to abandon the pull request entirely and fall back to opening a GitHub issue, even though GitHub could have created the PR and simply flagged it as having conflicts to resolve.

Fix

  • In pushSigned提交 (actions/setup/js/push_signed_commits.cjs), when the rebase-onto-current-base fails due to a genuine merge conflict (i.e. not a recoverable shallow/partial-clone object-fetch issue, and not resolved by a custom conflict resolver):
    • Abort the failed rebase, restoring the branch to its original, un-rebased state.
    • Push those original commits directly via unsigned git push, instead of throwing.
    • This lets GitHub still create the pull request — it will surface as having conflicts, resolvable the same way as any other PR — rather than aborting the whole run.
  • The strict-failure behavior is preserved when the caller explicitly passes allowGitPushFallback: false.

Tests

  • Updated push_signed_commits.test.cjs to cover the new fallback-on-conflict success path (branch pushed as-is, expected warnings emitted) and to keep an explicit test asserting the original throw behavior when allowGitPushFallback: false.
  • Adjusted the backfill-path test to disable git push fallback so it still asserts the throw specifically for verifying no backfill is attempted on a genuine conflict.

Also added a changeset describing the behavioral change.


Run: https://github.com/github/gh-aw/actions/runs/33195749972

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See 网络 Configuration for more information.

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 38.7 AIC · ⌖ 8.78 AIC · ⊞ 8.8K ·
Comment /souschef to run again


Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 38.1 AIC · ⌖ 8.64 AIC · ⊞ 8.8K ·
Comment /souschef to run again


Automated branch refresh attempt from PR Sous Chef run https://github.com/github/gh-aw/actions/runs/33246602890.

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 10.4 AIC · ⌖ 8.7 AIC · ⊞ 8.8K ·
Comment /souschef to run again

Copilot AI linked an issue Aug 28, 2026 that may be closed by this pull request
…mmits

Co-authored-by: dsyme <7204669+dsyme@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix merge conflict in CHANGELOG.md Fall back to unsigned push instead of failing when a rebase hits a genuine merge conflict in pushSigned提交 Aug 28, 2026
Copilot AI requested a review from dsyme August 28, 2026 09:37
@dsyme
dsyme marked this pull request as ready for review August 28, 2026 09:45
Copilot AI balanced review requested due to automatic review settings August 28, 2026 09:45
@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

No ADR enforcement needed: PR does not have the 'implementation' label and has ≤100 new lines of code in business logic directories.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

⚠️ 安全 scanning failed for Ponytail Reviewer. Review the logs for details.

Lean already. Ship.

Warning

Firewall blocked 4 domains

The following domains were blocked by the firewall during workflow execution:

  • ab.chatgpt.com
  • api.github.com
  • chatgpt.com
  • github.com

[!TIP]
api.github.com is blocked because GitHub API access uses the built-in GitHub tools by default. Instead of adding api.github.com to network.allowed, use tools.github.mode: gh-proxy for direct pre-authenticated GitHub CLI access without requiring network access to api.github.com:

tools:
  github:
    mode: gh-proxy

See GitHub Tools for more information on gh-proxy mode.

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"
    - "api.github.com"
    - "chatgpt.com"
    - "github.com"

See 网络 Configuration for more information.

Generated by Ponytail Reviewer for #56568

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-08-28T00:00:00Z
review_event: REQUEST_CHANGES
top_themes:
  - unsigned fallback may violate signed-commit branch policy
  - missing coverage for fallback push failure / policy-rejected repos
files_reviewed:
  - .changeset/fix-signed-push-genuine-rebase-conflict-fallback.md
  - actions/setup/js/push_signed_commits.cjs
  - actions/setup/js/push_signed_commits.test.cjs
comment_count: 0

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · pi · gpt54 · 9.85 AIC · ⌖ 7.34 AIC · ⊞ 7K ·
Comment /review to run again

@github-actions github-actions 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.

Request changes

This fallback fixes one failure mode, but it introduces a worse one: on a genuine rebase conflict you now silently abandon the signed-commit path and push unsigned commits instead. That can violate branch rules in repositories that require signed commits, and there is no coverage here proving the caller handles that policy failure cleanly instead of regressing back into the old issue-fallback path.

Key blocking theme
  • Genuine content conflicts now take a completely different transport path with different policy semantics.
  • The new tests only cover the happy path where unsigned pushes are allowed; they do not cover a signed-commits-required repo or a failing fallback push.
  • This makes the behavior change under-protected for the exact class of repos that opted into signed replay in the first place.

🔎 Code quality review by PR Code Quality Reviewer · pi · gpt54 · 9.85 AIC · ⌖ 7.34 AIC · ⊞ 7K
Comment /review to run again

@github-actions github-actions 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.

Skills-Based Review 🧠

Applied /diagnosing-bugs — one comment, one minor issue. Overall this is a well-structured, well-tested fix.

📋 Key Themes & Highlights

Key Themes

  • Warning message accuracy: The conflictMessage string includes a user-facing "retry" instruction that is misleading when re-used inside the success-path core.warning call. Also, prefixing a non-error outcome with ERR_SYSTEM: may cause false positives in log monitoring. See the inline comment on line 604.

Positive Highlights

  • ✅ The fix is minimal and surgical — only the genuine conflict branch gains new behaviour; the shallow/partial-clone path is unchanged.
  • allowGitPushFallback: false guard is correctly respected, preserving the strict-failure mode for callers that rely on it.
  • ✅ 新建 tests are thorough: fallback success path, explicit-disable path, and updated backfill test all cover the changed logic, with clear arrange/act/assert structure.
  • ✅ Good changeset entry explaining the before/after behaviour.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet46 · 26.9 AIC · ⌖ 10.5 AIC · ⊞ 7.7K
Comment /matt to run again

// of a pull request), push the ORIGINAL un-rebased commits directly via unsigned
// `git push`. GitHub will still create the pull request; it will simply report the
// branch as having conflicts that need to be resolved, the same as any normal PR.
core.warning(`${conflictMessage} Falling back to an unsigned git push of the un-rebased commit(s) so the pull request can still be created (it will show as having merge conflicts with the base branch).`);

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.

[/diagnosing-bugs] The warning string embeds conflictMessage verbatim, which includes "Resolve conflicts by rebasing/cherry-picking locally and retry." — but in this path the operation succeeds, so that instruction is misleading to anyone reading logs.

💡 Suggested fix

Split the message so the "retry" instruction only appears in the thrown error, not in the fallback-success warning:

const diagnosticMessage =
  `${ERR_SYSTEM}: pushSigned提交: failed to rebase commit range onto current GraphQL parent (${firstGraphqlParentOid}). ` +
  `Root cause: ${combinedOutput.trim()}`;
if (allowGitPushFallback === false) {
  throw new Error(`${diagnosticMessage} Resolve conflicts by rebasing/cherry-picking locally and retry.`);
}
core.warning(
  `${diagnosticMessage} Falling back to an unsigned git push of the un-rebased commit(s) so the pull request can still be created (it will show as having merge conflicts with the base branch).`
);

This also keeps the ERR_SYSTEM: prefix out of a warning that doesn't represent a system failure, which may otherwise trigger false monitoring alerts.

@copilot please address this.

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 as suggested: split the message so the "retry" instruction only appears on the throw path, and the fallback-success warning no longer implies a retry is needed.

@github-actions github-actions 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.

Clean, well-tested fix. The allowGitPushFallback === false strict-equality guard correctly defaults to allowing the fallback for existing callers (undefined is not strictly false). The "no-backfill" test correctly gets allowGitPushFallback: false to preserve its throw semantics — without it that test would silently start passing for the wrong reason. No blocking issues found.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet46 · 21.3 AIC · ⌖ 10.5 AIC · ⊞ 6.2K

Copilot AI 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.

Pull request overview

Adds unsigned push fallback so conflicting agent branches can still open pull requests.

Changes:

  • Falls back after genuine rebase conflicts.
  • Preserves strict mode when fallback is disabled.
  • Adds integration coverage and a changeset.
Show a summary per file
File Description
actions/setup/js/push_signed_commits.cjs Implements conflict fallback.
actions/setup/js/push_signed_commits.test.cjs Tests fallback and strict failure.
.changeset/fix-signed-push-genuine-rebase-conflict-fallback.md Documents the behavior change.

Review details

  • Files reviewed: 3/3 changed files
  • Comments generated: 3
  • Review effort level: Balanced

Comment on lines +601 to +605
// of a pull request), push the ORIGINAL un-rebased commits directly via unsigned
// `git push`. GitHub will still create the pull request; it will simply report the
// branch as having conflicts that need to be resolved, the same as any normal PR.
core.warning(`${conflictMessage} Falling back to an unsigned git push of the un-rebased commit(s) so the pull request can still be created (it will show as having merge conflicts with the base branch).`);
const fallbackSha = await pushBranchAndResolveHead({ branch, cwd, gitAuthEnv, pushRemoteUrl, pushToken });
Comment on lines +596 to +598
// Genuine merge conflict (not a shallow/partial-clone object-fetch issue, and no custom
// resolver handled it): rebasing the commit range onto the current base cannot be done
// automatically, and replaying the stale-base commits through GraphQL would silently
Comment on lines +605 to +607
const fallbackSha = await pushBranchAndResolveHead({ branch, cwd, gitAuthEnv, pushRemoteUrl, pushToken });
core.info(`pushSigned提交: unsigned git push fallback (unresolved rebase conflict) completed, using pushed SHA ${fallbackSha}`);
return fallbackSha;
@pelikhan

Copy link
Copy Markdown
Collaborator

Branch protection will block unsigned commits so this will fail for branches who require signed commits.

You can use signed/* in gh-aw to trigger this protection.

@github-actions

Copy link
Copy Markdown
Contributor

Category: bug | Risk: medium | Score: 58/100 (impact 27/50, urgency 16/30, quality 15/20) | Action: fast_track | Batch: workflow-ux

Generated by 🔧 PR Triage Agent · copilot · mai10 · 16.9 AIC · ⌖ 2.63 AIC · ⊞ 16.6K ·

@github-actions

Copy link
Copy Markdown
Contributor

Category: bug | Risk: medium | Score: 72 (impact 40 + urgency 18 + quality 14) | Action: fast_track | Batch: workflow-ux. This is a high-value workflow/PR-creation fix with clear regression coverage and a targeted fallback path.

Generated by 🔧 PR Triage Agent · copilot · mai10 · 18.1 AIC · ⌖ 2.63 AIC · ⊞ 16.6K ·

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot There is still blocking review feedback on this PR. Please address the signed-commit branch-protection concern, verify the fallback-path coverage is complete for policy-rejected repos, refresh the branch if needed, and then run the pr-finisher skill before handing back.

Current blocking feedback, newest first:

Generated by 👨🍳 PR Sous Chef

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See 网络 Configuration for more information.

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 21.7 AIC · ⌖ 8.64 AIC · ⊞ 6.4K ·
Comment /souschef to run again

…allback

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

@copilot There is still blocking review feedback on this PR. Please address the signed-commit branch-protection concern, verify the fallback-path coverage is complete for policy-rejected repos, refres...

Found one remaining gap from the linked review: when the object backfill succeeds but the retried rebase still fails, that was a genuine content conflict revealed post-backfill, yet it unconditionally threw instead of taking the unsigned-push fallback. Fixed in a5f0498's follow-up (latest commit) — that path now goes through the same fallback, preflight checks, and fatal-abort handling as the non-backfill genuine-conflict case, with a new test (should fall back to an unsigned push when a genuine merge conflict is only revealed after a successful object backfill) covering it. The branch-protection/signed-commits-required rejection path (combined error, tested via a pre-receive hook) and the policy-violation coverage were already added in prior commits and remain unchanged. All 243 tests across the affected suites pass, and lint is clean.

@github-actions

Copy link
Copy Markdown
Contributor

Category: bug | Risk: medium | Score: 56 (impact 27/urgency 15/quality 14) | Action: fast_track | CI: unknown

Generated by 🔧 PR Triage Agent · copilot · mai10 · 22.4 AIC · ⌖ 3.03 AIC · ⊞ 15.6K ·

@github-actions

Copy link
Copy Markdown
Contributor

Category: bug | Risk: medium | Score: 56 (impact 27/urgency 15/quality 14) | Action: fast_track

Generated by 🔧 PR Triage Agent · copilot · mai10 · 22.4 AIC · ⌖ 3.03 AIC · ⊞ 15.6K ·

@github-actions

Copy link
Copy Markdown
Contributor

Category: bug | Risk: medium | Score: 70/100 (impact 32/50, urgency 24/30, quality 14/20) | Action: fast_track | Batch: workflow-safety | Note: High-impact fallback behavior for signed-push/PR creation; good fit for expedited review.

Generated by 🔧 PR Triage Agent · copilot · mai10 · 17 AIC · ⌖ 2.53 AIC · ⊞ 15.6K ·

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot There is still blocking review feedback on this PR. Please verify the latest signed-commit branch-protection handling on the current head, address any remaining review concern, refresh the branch if needed, and then run the pr-finisher skill before handing back.

Current blocking feedback, newest first:

Your follow-up says the combined-error path and signed-commit rejection coverage were added, but this PR still needs a fresh maintainer-ready handoff on the current head.

Run: https://github.com/github/gh-aw/actions/runs/33241945198

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 38.1 AIC · ⌖ 8.64 AIC · ⊞ 8.8K ·
Comment /souschef to run again

Copilot AI commented Aug 29, 2026

Copy link
Copy Markdown
Contributor Author

@copilot There is still blocking review feedback on this PR. Please verify the latest signed-commit branch-protection handling on the current head, address any remaining review concern, refresh the br...

Verified on the current head (8ab960c, after merging main): the branch-protection combined-error path (should surface a combined error (not swallow it) when the unsigned push fallback is itself rejected, e.g. by branch protection requiring signed commits) and the post-backfill genuine-conflict fallback are both still present and passing. Ran the full affected suite (push_signed_commits.test.cjs, push_experiment_state.test.cjs, create_pull_request.test.cjs) — 243/243 pass, and lint is clean. No further code changes were needed for this pass.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot Please refresh this PR for forward progress. Re-run the pr-finisher skill, address any remaining review feedback, and update the branch if needed.

Run: https://github.com/github/gh-aw/actions/runs/33246602890

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 10.4 AIC · ⌖ 8.7 AIC · ⊞ 8.8K ·
Comment /souschef to run again

Copilot AI commented Aug 29, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Please refresh this PR for forward progress. Re-run the pr-finisher skill, address any remaining review feedback, and update the branch if needed.

Run: https://github.com/github/gh-aw/acti...

Branch is already up to date with main (no rebase needed) and the current head (8ab960c) has no new review feedback beyond what was already addressed and verified. Re-ran push_signed_commits.test.cjs (68/68 passing) and lint is clean. No code changes needed this pass.

注册 for free to join this conversation on GitHub. Already have an account? 登录 to comment

项目

None yet

Development

Successfully merging this pull request may close these issues.

Failure to create PR due to merge conflict

5 participants