Skip to content

[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

@dschmittwilken

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 no fetchDepth.
  • Repo shape: target branch (origin/develop) forks from the run branch (integration) more
    than ~4 deepening increments back.
  • Safe output: create-pull-request with target-branch: develop.
  • Result: prepare-pr-base prints "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 +
    all origin/* 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:

  1. Emit fetchDepth: 0 on the checkouts ado-aw generates for create-pull-request (at least in
    the job(s) that run prepare-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.
  2. Full-unshallow fallback in prepare-pr-base. When bounded deepening exhausts its steps
    without a merge-base, do one final git 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.
  3. 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.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingjavascriptPull requests that update javascript coderustPull requests that update rust code

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions