bump.yml checkout: the REPOSITORY_ACCESS_TOKEN fallback only fires on an empty variable, so a valid-but-unauthorized bot token breaks any repo the bot cannot reach #24

Open
opened 2026-08-02 19:29:56 +00:00 by gravityfargo · 0 comments
Owner

The problem

.forgejo/workflows/bump.yml:67-70 checks out with:

- name: Check out
  uses: actions/checkout@v7
  with:
      token: ${{ env.REPOSITORY_ACCESS_TOKEN || github.token }}
      fetch-depth: 0

The comment above it states the intent:

pushes made with the default actions token never trigger workflows, so the tag push would not fire a tag-triggered publish. The bot PAT (from the same Infisical path as the signing key) makes the pushes trigger; outside the org the default token applies and downstream workflows need a manual dispatch.

|| returns the right operand only when the left is falsy. So "outside the org the default token applies" holds only when REPOSITORY_ACCESS_TOKEN is empty — that is, when Infisical is unreachable or unconfigured for the caller. It does not hold for the case that actually matters: Infisical resolves fine, the variable is populated with a perfectly valid commitizen-bot PAT, and that account simply has no access to the calling repo. The intended fallback never engages, and checkout fails instead.

Observed

gravityfargo/mcp-vikunja — private, personal namespace — adopted common-versioning + common-versioning-python from the templates repo and merged to main.

Run https://code.modernleft.org/gravityfargo/mcp-vikunja/actions/runs/5 (run id 4320), job 6216 Bump version and changelog with commitizen.

The Infisical step succeeded:

Injected secrets as environment variables

Checkout then failed three times with retries, and the job ended there:

[command]/usr/bin/git -c protocol.version=2 fetch --no-tags --prune --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*
remote: Repository not found
fatal: repository 'https://code.modernleft.org/gravityfargo/mcp-vikunja/' not found
The process '/usr/bin/git' failed with exit code 128

The sibling jobs in the same run — test (6211) and code-quality (6213) — checked out the same commit successfully, because they use the default job token, which is scoped to the repo being built. That contrast is what isolates the cause to the token, not to the repo or the runner.

commitizen-bot was not a collaborator on the repo. Forgejo answers "Repository not found" rather than 403 for a private repo a credential cannot see, which is why the error names nothing useful.

Scope

Every repo in the templates ADOPTERS.md carrying common-versioning is under the ModernLeft org, where the bot is presumably a member, so nothing has hit this before. Any adopter in a personal namespace, or any private repo the bot is not a collaborator on, hits it on the first push to main after adopting — i.e. the failure is discovered by breaking main, since build-version.yml has no workflow_dispatch and cannot be exercised beforehand.

Note that read access is not sufficient to fix it in general: bump.yml:106 pushes the branch and tag, so the bot needs write.

Workaround applied

commitizen-bot added as a write collaborator on gravityfargo/mcp-vikunja. Not yet re-verified by a run, because the workflow is push-triggered only.

Options

  1. Probe before trusting the PAT. Test the bot token's access to the calling repo and genuinely fall back to github.token when it fails, which is what the comment already promises.
  2. Make it explicit with an input — e.g. use-bot-token defaulting to true, so an out-of-org caller opts out rather than discovering the constraint from a checkout failure.
  3. Fail early with a real message. Even keeping current behaviour, asserting the bot's access up front would replace "Repository not found" with something that names the cause, in the same spirit as the existing Assert signing key materialized step.
  4. Document the precondition in the templates common-versioning/TEMPLATE.md: adopting the layer requires commitizen-bot to have write on the repo. Worth doing regardless of which of the above lands, and it belongs next to the existing note about needing an initial tag.
## The problem `.forgejo/workflows/bump.yml:67-70` checks out with: ```yaml - name: Check out uses: actions/checkout@v7 with: token: ${{ env.REPOSITORY_ACCESS_TOKEN || github.token }} fetch-depth: 0 ``` The comment above it states the intent: > pushes made with the default actions token never trigger workflows, so the tag push would not fire a tag-triggered publish. The bot PAT (from the same Infisical path as the signing key) makes the pushes trigger; **outside the org the default token applies** and downstream workflows need a manual dispatch. `||` returns the right operand only when the left is falsy. So "outside the org the default token applies" holds only when `REPOSITORY_ACCESS_TOKEN` is **empty** — that is, when Infisical is unreachable or unconfigured for the caller. It does not hold for the case that actually matters: Infisical resolves fine, the variable is populated with a perfectly valid `commitizen-bot` PAT, and that account simply has no access to the calling repo. The intended fallback never engages, and checkout fails instead. ## Observed `gravityfargo/mcp-vikunja` — private, personal namespace — adopted `common-versioning` + `common-versioning-python` from the templates repo and merged to `main`. Run https://code.modernleft.org/gravityfargo/mcp-vikunja/actions/runs/5 (run id 4320), job 6216 `Bump version and changelog with commitizen`. The Infisical step succeeded: ``` Injected secrets as environment variables ``` Checkout then failed three times with retries, and the job ended there: ``` [command]/usr/bin/git -c protocol.version=2 fetch --no-tags --prune --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/* remote: Repository not found fatal: repository 'https://code.modernleft.org/gravityfargo/mcp-vikunja/' not found The process '/usr/bin/git' failed with exit code 128 ``` The sibling jobs in the same run — `test` (6211) and `code-quality` (6213) — checked out the same commit successfully, because they use the default job token, which is scoped to the repo being built. That contrast is what isolates the cause to the token, not to the repo or the runner. `commitizen-bot` was not a collaborator on the repo. Forgejo answers "Repository not found" rather than 403 for a private repo a credential cannot see, which is why the error names nothing useful. ## Scope Every repo in the templates `ADOPTERS.md` carrying `common-versioning` is under the `ModernLeft` org, where the bot is presumably a member, so nothing has hit this before. Any adopter in a personal namespace, or any private repo the bot is not a collaborator on, hits it on the first push to `main` after adopting — i.e. the failure is discovered by breaking `main`, since `build-version.yml` has no `workflow_dispatch` and cannot be exercised beforehand. Note that read access is not sufficient to fix it in general: `bump.yml:106` pushes the branch and tag, so the bot needs **write**. ## Workaround applied `commitizen-bot` added as a write collaborator on `gravityfargo/mcp-vikunja`. Not yet re-verified by a run, because the workflow is push-triggered only. ## Options 1. **Probe before trusting the PAT.** Test the bot token's access to the calling repo and genuinely fall back to `github.token` when it fails, which is what the comment already promises. 2. **Make it explicit with an input** — e.g. `use-bot-token` defaulting to `true`, so an out-of-org caller opts out rather than discovering the constraint from a checkout failure. 3. **Fail early with a real message.** Even keeping current behaviour, asserting the bot's access up front would replace "Repository not found" with something that names the cause, in the same spirit as the existing `Assert signing key materialized` step. 4. **Document the precondition** in the templates `common-versioning/TEMPLATE.md`: adopting the layer requires `commitizen-bot` to have write on the repo. Worth doing regardless of which of the above lands, and it belongs next to the existing note about needing an initial tag.
Sign in to join this conversation.
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
ModernLeft/commitizen-ci#24
No description provided.