Repository navigation
[aw]: create-pull-request breaks on Azure DevOps' default shallow-fetch pipelines: prepare-pr-base bounded deepening can't reach the merge-base, and the emitted checkout: self has no fetchDepth #1541
Description
Submission requirements
- I generated this issue with an agent that used
.github/agents/ado-aw.agent.md. - I reviewed the generated issue and confirm it is being filed directly in
githubnext/ado-aw.
Problem summary
Since #1460 (0.44.0), create-pull-request's prepare-pr-base resolves the diff base by bounded
progressive deepening (the fail-closed tests pin it at "4 depths × 2 branches" = 8 fetches) against
origin/<target-branch>, then fails closed if no real merge-base is found (correct — no more
silent HEAD^1 fallback).
The trouble is the starting depth. ado-aw emits a bare checkout: self (no fetchDepth), so
the clone depth is governed by the pipeline's Shallow fetch setting — and Azure DevOps
defaults new pipelines (post sprint 209,
Sep 2022) to shallow depth 1. On any repo whose target-branch fork point is more than ~4
deepening steps back, prepare-pr-base can't reach the merge-base and gives up:
[prepare-pr-base] warning: Could not resolve merge-base against 'origin/*' after
progressive deepening. create-pull-request may fail to compute a diff base for
'/mnt/vss/_work/1/s' on this pool.
create-pull-request then has no diff base and the safe-output fails (observed as the safe-outputs
MCP "connection closing" during safeoutputs-create-pull-request). Because shallow-depth-1 is the
default for modern ADO pipelines, this isn't an exotic edge case — it hits any such pipeline
with a non-trivial branch distance to the target, and the failure is opaque (a buried
prepare-pr-base warning, not an obvious "your checkout is too shallow" message).
Per the checkout docs,
the two documented ways to get full history are (a) disable Shallow fetch in the pipeline
settings UI, or (b) set fetchDepth: 0 on the checkout step. ado-aw controls neither: there is
no front-matter knob for checkout depth (on 0.45.1, self-checkout and workspace are
rejected; repos.self.fetch-depth compiles but emits no fetchDepth). So the only options a user
has are an out-of-band pipeline-UI toggle (easy to forget, not in source control, invisible if the
pipeline is recreated) or a post-compile patch of the generated lock.
Reproduction details
- ado-aw: 0.45.1 (behavior originates in fix(ado-script): fail closed for unresolved synthetic PR merge-base #1460 / 0.44.0; unchanged in 0.45.x)
- Pipeline: created after Sep 2022 → Shallow fetch = depth 1 by default;
checkout: self
emitted by ado-aw with nofetchDepth. - Repo shape: target branch (
origin/develop) forks from the run branch (integration) more
than ~4 deepening increments back. - Safe output:
create-pull-requestwithtarget-branch: develop. - Result:
prepare-pr-baseprints "Could not resolve merge-base ... after progressive
deepening"; create-pull-request fails to compute a base. - Confirmed fix: disabling Shallow fetch (equivalently
fetchDepth: 0) makes full history +
allorigin/*refs present, so the merge-base resolves immediately and the deepening loop is a
no-op — create-pull-request produces a correct 1-commit diff.
Proposed next step
Any one of these removes the out-of-band toggle / lock-patch requirement:
- Emit
fetchDepth: 0on the checkouts ado-aw generates for create-pull-request (at least in
the job(s) that runprepare-pr-base). create-pull-request fundamentally needs history back to
the merge-base; a shallow checkout can't provide it, so defaulting these checkouts to full is
the correct, self-contained behavior — no dependency on a pipeline UI setting. - Full-unshallow fallback in
prepare-pr-base. When bounded deepening exhausts its steps
without a merge-base, do one finalgit fetch --unshallow(or deepen to full) before failing
closed. fix(ado-script): fail closed for unresolved synthetic PR merge-base #1460's correctness guarantee is preserved — full history can only make a real
merge-base findable, never fabricate a wrong one. - A front-matter knob for checkout depth (honor
repos.self.fetch-depth: 0, or a top-level
checkout: { fetch-depth: 0 }), so depth is expressed in source alongside the rest of the
workflow rather than in a pipeline UI toggle.
Workaround in the meantime: disable Shallow
fetch in the pipeline settings UI — ⋮ More actions → Triggers → YAML → Get sources → Shallow
fetch.)
Activity