fix(ci): drop actions/checkout from renovate workflow#5
Merged
Conversation
The `actions/checkout` step was modeled on NVIDIA/gpu-operator's renovate workflow, but our setup deliberately does not pass `configurationFile:` (to avoid customManager doubling — see PR #3). Without that input, the renovatebot/github-action clones the repo itself inside Docker and has no need for an outer working tree. Observed failure: every Renovate run since the practice exercise started would create the first eligible branch (e.g. `renovate/build-tools`) and then abort 0.3s later with "Repository has changed during renovation" — even though no commit to main happened during the run window. The credentials and working tree planted at /home/runner/work by `actions/checkout` are the suspect: Renovate's container-internal git operations and the runner-side git state cross-contaminate, and Renovate misinterprets its own branch push as a base-branch advance. Removing the step removes the cross-contamination surface. The action documents that checkout is not required when using its default internal-clone mode.
7 tasks
njhensley
added a commit
that referenced
this pull request
May 4, 2026
…kflow (#6) Reverts toward the known-working NVIDIA/gpu-operator pattern after PRs #5 (drop checkout) and earlier failed to clear the persistent "Repository has changed during renovation" abort. Three concrete changes: 1. **Add back actions/checkout.** The action documents that it clones internally, but the host-side git state planted by checkout appears to keep Renovate's pre/post hooks consistent. Removing it in PR #5 did not fix the abort, suggesting checkout was never the culprit. 2. **Pass configurationFile: .github/renovate.json5.** The earlier concern about customManager doubling came from `RENOVATE_PLATFORM=local` dry-runs; in production (platform=github) Renovate dedupes by manager identity, so the same-file case is benign. Without configurationFile, the action runs Renovate without a global config — and that mode is associated with mid-run race conditions that surface as "repository-changed" aborts right after a successful branch push. 3. **Set RENOVATE_DRY_RUN conditionally.** Previously the env var was emitted on every run as `''` (empty string when dryRun=false). Renovate's option parser may treat the *presence* of the env var differently from its unset state. The new "Configure dry-run mode" step writes the var to GITHUB_ENV only when explicitly requested, keeping the env clean for the common case. Verified end-to-end via actionlint. Soft-launch loop continues — once this lands, dispatch Renovate manually and check whether `renovate/build-tools` (the only bundle past the cooldown filter) finally produces a PR alongside its branch.
6 tasks
njhensley
added a commit
that referenced
this pull request
May 4, 2026
#7) Root cause of the persistent "Repository has changed during renovation" aborts since PR #4 — Renovate was calling POST /repos/{owner}/{repo}/ statuses/{sha} after each branch creation to write a stability status check (tied to the cooldown / merge-confidence flow). The workflow's permissions block had contents:write, pull-requests:write, issues:write but not statuses:write, so the call 403'd with "integration- unauthorized". Renovate's error handler maps that internally to "repository-changed", which is why every prior debugging attempt (checkout, configurationFile, dry-run env, digest pin) chased the wrong symptom. Confirmed via debug log on run 25346172853: Request failed with status code 403 (Forbidden): POST .../statuses/cf3dc7d1... "x-accepted-github-permissions": "statuses=write" DEBUG: Caught error setting branch status - aborting Error: integration-unauthorized DEBUG: Passing repository-changed error up The earlier hypothesis fixes in PRs #5 and #6 weren't wrong per se (actions/checkout and configurationFile aren't the cause, and RENOVATE_DRY_RUN='' isn't either) — they just couldn't have fixed the underlying permission gap. With statuses:write added, Renovate's post-branch status-check call should succeed and the run should complete normally.
6 tasks
njhensley
added a commit
that referenced
this pull request
May 13, 2026
Audit findings #5 and #6: the pointer file was duplicating fingerprint, criteriaMatch, phaseSummary, and attestedAt — nearly a copy of the predicate, with no Go consumer reading the denormalized fields. Two sources of truth with no good answer for which to trust on mismatch. A pointer's job is to *locate* the signed bundle, not to summarize it. A reviewer who wants fingerprint dimensions or per-phase pass/fail counts fetches the bundle from PointerBundle.OCI and reads predicate.json — that's the authoritative copy and the only one. Before After ────── ───── schemaVersion schemaVersion recipe recipe attestations[]: attestations[]: bundle bundle signer signer (omitempty) attestedAt attestedAt fingerprint ──── DROPPED criteriaMatch ──── DROPPED phaseSummary ──── DROPPED (also resolves audit #6: pointer phaseSummary block omitted .skipped despite predicate carrying it) logsBundle ──── DROPPED (feature deferred in 0277fec; will return as omitempty when log capture lands) Wire changes: - PointerAttestation: 7 fields → 3. - PointerFingerprint, PointerCriteriaMatch, PointerPhaseStat, PointerLogsBundle types deleted along with their build helpers (pointerFingerprintFrom, pointerPhaseSummaryFrom). - PointerInputs.LogsBundle dropped — no caller ever populated it. - Schema version stays at 1.0.0; no committed pointer files exist yet and the design doc's '2.0.0 reserved for multi-instance' plan is preserved. Test coverage: - TestBuildPointer_OmitsDenormalizedFields: asserts the rendered YAML has no fingerprint:, criteriaMatch:, phaseSummary:, or logsBundle: keys. Catches regressions where a future commit adds a field back without updating the design rationale. - Existing fingerprint round-trip and logsBundle round-trip tests deleted (they asserted denormalization that no longer happens). Design doc (docs/design/007-recipe-evidence.md): - Pointer schema example shrunk to match. - Added 'The pointer is a locator, not a denormalized cache' paragraph documenting the rationale. - Verifier step 7 updated to read criteriaMatch from the predicate rather than the pointer. - Verifier step 11 (logs bundle verification) marked deferred pending log capture; spelled out that V1 pointers omit the field entirely so verifiers don't error on absence.
njhensley
added a commit
that referenced
this pull request
May 13, 2026
Audit findings #5 and #6: the pointer file was duplicating fingerprint, criteriaMatch, phaseSummary, and attestedAt — nearly a copy of the predicate, with no Go consumer reading the denormalized fields. Two sources of truth with no good answer for which to trust on mismatch. A pointer's job is to *locate* the signed bundle, not to summarize it. A reviewer who wants fingerprint dimensions or per-phase pass/fail counts fetches the bundle from PointerBundle.OCI and reads predicate.json — that's the authoritative copy and the only one. Before After ────── ───── schemaVersion schemaVersion recipe recipe attestations[]: attestations[]: bundle bundle signer signer (omitempty) attestedAt attestedAt fingerprint ──── DROPPED criteriaMatch ──── DROPPED phaseSummary ──── DROPPED (also resolves audit #6: pointer phaseSummary block omitted .skipped despite predicate carrying it) logsBundle ──── DROPPED (feature deferred in 0277fec; will return as omitempty when log capture lands) Wire changes: - PointerAttestation: 7 fields → 3. - PointerFingerprint, PointerCriteriaMatch, PointerPhaseStat, PointerLogsBundle types deleted along with their build helpers (pointerFingerprintFrom, pointerPhaseSummaryFrom). - PointerInputs.LogsBundle dropped — no caller ever populated it. - Schema version stays at 1.0.0; no committed pointer files exist yet and the design doc's '2.0.0 reserved for multi-instance' plan is preserved. Test coverage: - TestBuildPointer_OmitsDenormalizedFields: asserts the rendered YAML has no fingerprint:, criteriaMatch:, phaseSummary:, or logsBundle: keys. Catches regressions where a future commit adds a field back without updating the design rationale. - Existing fingerprint round-trip and logsBundle round-trip tests deleted (they asserted denormalization that no longer happens). Design doc (docs/design/007-recipe-evidence.md): - Pointer schema example shrunk to match. - Added 'The pointer is a locator, not a denormalized cache' paragraph documenting the rationale. - Verifier step 7 updated to read criteriaMatch from the predicate rather than the pointer. - Verifier step 11 (logs bundle verification) marked deferred pending log capture; spelled out that V1 pointers omit the field entirely so verifiers don't error on absence.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Removes the
actions/checkoutstep from.github/workflows/renovate.yaml. Therenovatebot/github-actionclones the repo itself inside Docker and doesn't need an outer working tree.Motivation / Context
Diagnosed during the fork practice exercise: every Renovate run since merging PR #3 would successfully create the first eligible branch (
renovate/build-tools, after the cooldown filter) and then abort 0.3s later withRepository has changed during renovation— even thoughmaindid not advance during the run window (verified via the GitHub commits API).Pattern from logs (
run 25345091057):The
actions/checkoutstep plants a working tree + credentials at/home/runner/work/aicr/aicr. Renovate's container-internal git operations only mount/tmp:/tmp, but the action's host-side post-step does its own git config reads/writes that interfere with Renovate's view of refs. The interaction was clean in NVIDIA/gpu-operator's workflow because that one passesconfigurationFile:— which we deliberately don't (it causes customManager doubling, see PR #3). Without that input, our setup uses the action's default internal clone, and the outer checkout becomes redundant + harmful.Fixes: silent abort after first branch creation
Related: #1, #3, #4
Type of Change
Component(s) Affected
Implementation Notes
steps:documents why future drive-bys shouldn't put checkout back.Testing
actionlint .github/workflows/renovate.yaml # cleanAfter merge:
renovate/build-toolsbranch (it was created by the aborting runs but has no PR).Risk Assessment
Checklist
actionlint)git commit -S)