Skip to content

ci(trailers): the trailer gate cannot see a release promotion — fixed fetch-depth 100 vs 808 commits #16931

Description

@mrveiss

Finding

The release promotion #16801 (main → release) fails No commit trailers — not because any commit carries a banned trailer, but because the gate cannot see the whole release:

scanned 554 commits but GitHub reports 808
the checkout is too shallow and the oldest commits would go unexamined. Raise fetch-depth (#16207).

.github/workflows/no-commit-trailers.yml checks out at a fixed fetch-depth: 100. #16801 carries 808 commits, so 254 of them were never examined, and the gate correctly refuses to report a truncated range as clean.

This is the guard working, and its own comment predicted it

The depth was set by #16207 with a measured rationale: a full clone is ~12,900 commits on main, cost 13s of git for 1s of work (93% of the job) on every PR, and the deepest PR among the last 40 merged was 30 commits — so 100 was over 3x the observed maximum. The comment then adds:

The depth is a guess about the future, so the scan refuses to run rather than trust it.

A release promotion is the future it was guarding against. Every main → release PR carries every commit since the last release, so it will always exceed any fixed depth chosen for ordinary PRs. The next release will fail the same way, and the one after.

The release would pass once the gate can see it

Checked locally against all 808 commits in release..main, applying the gate's own rule to each commit's final block:

Trailer Commits Gate verdict
Co-authored-by: github-actions[bot] (two address forms) 73 allowed — [bot] identities are exempt by rule (#13654)
Co-authored-by: dependabot[bot] 27 allowed — same rule
Co-authored-by: t <…> — placeholder author leaked from test fixtures (#16124) 17 all 17 already listed in .github/commit-trailer-baseline.txt

So the depth is the only thing between #16801 and a green gate.

Fix

Size the fetch to the PR instead of guessing once for all of them:

fetch-depth: ${{ (github.event_name == 'merge_group' || github.event.pull_request.commits > 90) && '0' || '100' }}

GitHub Actions expressions support comparison but not arithmetic, which is why this is a threshold rather than commits + N.

Acceptance criteria

Activity

  1. added this to the v0.9.0 milestone on Sep 18, 2026
  2. github-actions commented on Sep 19, 2026

    @github-actions
    Contributor

    PR #16932 (merged to main) references this issue with a close keyword.

    fix(ci): size the trailer gate's fetch to the PR so a release is scanned whole (#16931)

    If this issue is fully resolved, close it manually. If work remains, no action is needed.

  3. mrveiss commented on Sep 28, 2026

    @mrveiss
    OwnerAuthor

    Chunking triage — a proposal, not an assignment

    Nothing was relabelled, moved or closed by this pass.

  4. mrveiss commented on Sep 28, 2026

    @mrveiss
    OwnerAuthor

    Closure pass — all four criteria met. Closing.

    Evidence at origin/main 7adaca8c29; workflow .github/workflows/no-commit-trailers.yml.

    AC1 — #16801 passes No commit trailers having scanned all its commits — MET, observed. gh pr checks 16801 reports No commit trailers pass 44s (run 35862044000). The scanned-count equality is what the guard itself enforces: :94 fails when scanned != EXPECTED_COMMITS with "the checkout is too shallow and the oldest commits would go unexamined". So a pass on a 682-commit promotion is the full scan — the guard cannot pass on a truncated range.

    AC2 — an ordinary PR still checks out at depth 100 — MET. :61:

    fetch-depth: ${{ (github.event_name == 'merge_group' || github.event.pull_request.commits > 90) && '0' || '100' }}

    Full history only for a merge group or a PR deeper than 90 commits. The comment at :55-60 records why the threshold is 90 rather than arithmetic — "Expressions have comparison but no arithmetic" — and that depth 100 is guaranteed to fail anyway for that set, so the #16207 saving is never spent on a PR that would have passed.

    AC3 — the truncation guard unchanged and still failing an unreachable range — MET. Both halves survive: the endpoint-presence check ("is not present in the checkout — this PR is deeper than the checkout") and the scanned-vs-reported count check. Its comment records the case it exists for: at depth 100 both endpoints can be present while git rev-list silently returns fewer commits.

    AC4 — the error message no longer hardcodes "fetch-depth 100" — MET. Both messages now read "Raise fetch-depth in this workflow" and "Raise fetch-depth (#16207)", with no depth named, which is correct now that the depth is chosen per PR.

    Landed via PR#16932 / 4c6879080d. All four met — closing.

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions