Skip to content

fix(ci): grant statuses:write so renovate can set branch status checks#7

Merged
njhensley merged 1 commit into
mainfrom
ci/renovate-add-statuses-permission
May 4, 2026
Merged

fix(ci): grant statuses:write so renovate can set branch status checks#7
njhensley merged 1 commit into
mainfrom
ci/renovate-add-statuses-permission

Conversation

@njhensley

Copy link
Copy Markdown
Owner

Summary

One-line permission addition (statuses: write) that fixes the persistent Repository has changed during renovation aborts every Renovate run has hit since PR #4.

Root cause

The error message is misleading. Pulled the debug-level log from run 25346172853:

Request failed with status code 403 (Forbidden):
  POST https://api.github.com/repos/njhensley/aicr/statuses/cf3dc7d1...
  "message": "Resource not accessible by integration"
  "x-accepted-github-permissions": "statuses=write"

DEBUG: Caught error setting branch status - aborting
Error: integration-unauthorized
    at setStability (status-checks.ts:94:3)
    at setBranchStatusChecks (branch/index.ts:64:3)
    at processBranch (branch/index.ts:776:5)

DEBUG: Passing repository-changed error up
INFO: Repository has changed during renovation - aborting

After Renovate creates each branch, it calls POST /repos/{owner}/{repo}/statuses/{sha} to write a stability status check (used by the cooldown / merge-confidence pipeline). Our workflow's permissions: block had contents, pull-requests, and issues write, but not statuses. The 403 propagates as integration-unauthorized, which Renovate's error handler maps internally to repository-changed — a wildly misleading message for what's actually a missing OAuth scope.

NVIDIA/gpu-operator's workflow works because they don't set permissions: at all, so GitHub falls back to default write-all which implicitly includes statuses: write. We were trying to be principle-of-least-privilege but blocked a required scope.

PRs #5 and #6 (drop checkout / restore configurationFile / conditional dry-run) chased symptoms that couldn't have been the cause. Their changes are still defensible on their own merits (PR #6 in particular re-aligns with gpu-operator's pattern), but only this PR addresses the actual abort.

Fixes: persistent repository-changed aborts since PR #4
Related: #5, #6

Type of Change

  • Bug fix
  • Build/CI/tooling

Implementation Notes

  • One line + a comment explaining why we need it (so future PRs auditing permissions don't strip it again).

Testing

actionlint .github/workflows/renovate.yaml   # clean

Post-merge validation:

  1. Delete orphan renovate/build-tools branch (will be re-created by next run with proper status check).
  2. Single gh workflow run renovate.yaml --repo njhensley/aicr.
  3. Expected: branch + PR + stability status check on the branch's commit, run completes with result: "renovate-pr-created" (or similar) instead of repository-changed.

Risk Assessment

  • Low — Single permission addition. statuses: write lets the GITHUB_TOKEN write status checks on commits in this repo only; matches what gpu-operator's setup gets implicitly via the default permission set.

Checklist

  • Linter passes (actionlint)
  • I did not skip/disable tests to make CI green
  • Commits are cryptographically signed (git commit -S)

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.
@njhensley njhensley merged commit 2998205 into main May 4, 2026
22 checks passed
njhensley added a commit that referenced this pull request May 4, 2026
Confirmed in production run 25346453345: the regex manager stats
showed `"regex": {"fileCount": 4, "depCount": 56}` instead of the
expected 2/28. With `configurationFile: .github/renovate.json5`
passed, the action mounts the file as Renovate's global config AND
Renovate auto-discovers the same file from the cloned working tree;
both loads register the customManagers and every annotation gets
extracted twice. The doubling produced 14 "Cannot find replaceString
in current file content. Was it already updated?" warnings across
the four created branches — Renovate's first pass applied the
replacement, the second pass tried to re-apply but the content no
longer matched.

PR #6 added `configurationFile:` chasing the "repository-changed"
aborts under the wrong hypothesis; PR #7 found and fixed the actual
cause (missing `statuses: write` permission). With #7 in place we
can drop `configurationFile:` cleanly. Earlier dry-run experiments in
RENOVATE_PLATFORM=local mode had already shown this doubling, but I
mis-attributed it to local-mode specifics. Production confirms the
behavior is the same.

`actions/checkout` stays — it's not the cause of any issue we've
seen, and the upstream gpu-operator pattern keeps it.
@njhensley njhensley deleted the ci/renovate-add-statuses-permission branch June 23, 2026 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant