Token discovers only one repo #10
Labels
No labels
bug
dependencies
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
alex/renovate-bot#10
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
See https://forge.l3x.in/alex/renovate-bot/actions/runs/39/jobs/0/attempt/1
We should use a token that lets create PRs for every repo in our Forgejo.
/pi report
Now let me look at the CI run referenced in the issue to understand the actual error.## Report: Token discovers only one repo
Root Cause
The most recent commit (
1c71451"ci: update token") changed the Renovate auth token from a dedicated PAT to the CI runner's built-in token:The
PI_TOKENis the scoped token injected by the Forgejo Actions runner for the "Pi AI Agent" workflow (.forgejo/workflows/pi.yml). That token is scoped to this repository only (it's the per-workflow-run token, equivalent toGITHUB_TOKEN, restricted to the repo the pipeline runs in).Renovate's
autodiscover: true(inconfig.js) discovers repositories by calling the Forgejo/repos/searchAPI with the provided token. BecausePI_TOKENonly grants access toalex/renovate-bot, the search returns exactly one repository — the one this pipeline lives in — and Renovate never sees the rest of thealexnamespace (or the instance).Why the original setup worked
The
README.mddocuments creating a classic Personal Access Token with scopesrepo(read/write) +user(read) and storing it assecrets.RENOVATE_TOKEN. A user-scoped PAT like that grants access to every repository thealexuser owns or is a member of, which is exactly what autodiscovery needs to enumerate all repos and open PRs in them.Fix
Switch
RENOVATE_TOKENback to a token that has instance-wide (or at least namespace-wide) repository access. Two options:Revert to the documented PAT — create a Forgejo PAT with
repo+userscope for a user that can access all target repos, store it assecrets.RENOVATE_TOKEN, and restoreRENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }}in the workflow. This is the simplest fix and matches the existing README instructions.Broaden
PI_TOKEN's scope — if you want to keep usingPI_TOKEN, regenerate it as a fine-grained/user PAT with access to all repositories (not just this one). Fine-grained tokens scoped to a single repo will still only discover that repo.Either way, the token passed to Renovate must be able to list and write to every repo where Renovate should operate. The per-run pipeline token cannot do this and must not be used.
I have not made any changes — let me know if you'd like me to apply option 1 (revert the token line) and open a PR.
View action run | Model: zai/glm-5.2 (thinking: xhigh) | Time: 1m 35s | Tokens: 39.2K | Pi SDK v0.80.3 | Action v2.25.1
/pi search Renovate up-to-date docs and see exactly which permissions the PAT requires (btw PI_TOKEN IS already a PAT, perhaps is missing some permissions)
Let me check the CI logs for the referenced run and search Renovate's current documentation.Let me extract the actual documentation content from the Renovate Gitea platform page (Forgejo uses the Gitea platform in Renovate).I have the official docs. Let me verify how Renovate actually calls the autodiscover API on Gitea/Forgejo, so I can be precise about why only one repo is returned.Let me check how
botUserIDis determined and whatusableRepofilters, to be precise about the autodiscover behavior.I now have the authoritative answer, confirmed against both the official Renovate Forgejo docs and the Renovate source code. Here's the precise analysis.What the current Renovate docs require
From the official Forgejo platform docs (docs.renovatebot.com/modules/platform/forgejo), the PAT must have these scopes:
repoissueorganizationuseremailmiscread:packagesWhy exactly one repo is discovered
I traced this in the Renovate source. Autodiscovery (with
autodiscover: true, no topics/namespaces) does this inlib/modules/platform/gitea/index.ts:…which hits
GET /api/v1/repos/search?uid=<botUserID>(seegitea-helper.ts:69).Two things then happen:
/repos/searchis scoped to what the token can access. Gitea/Forgejo returns only repositories the token has access to. So if the token is valid for a single repo, the search returns exactly that one repo — regardless of how many repos thealexaccount owns.usableRepo()requires push permission (utils.ts:157):Even if a repo is visible, it's dropped unless the token grants write on it. A read-only or single-repo token fails this check for everything else.
This combination is the fingerprint of a repo-scoped token: one repo discovered, the one the token was minted for (
alex/renovate-bot).The core issue: "PAT" ≠ "broadly scoped"
You're right that
PI_TOKENis a PAT — but the symptom is not about missing scope categories (likeissue/organization); it's about which repositories the token was granted on. Forgejo has two PAT types:repo,issue,organization,user). This grants access to every repository the account owns / is a member of → autodiscover finds all of them. ✅PI_TOKENwas created scoped only toalex/renovate-bot, autodiscover can only ever see that one repo. ❌ ← almost certainly your case.So even if you add
issue+organizationscopes toPI_TOKEN, it will still discover only one repo until its repository access covers all target repos.Fix
Regenerate
PI_TOKEN(inalex→ Settings → Applications) so it has access to all repositories plus the scopes above. Two valid options:Option A — Classic PAT (simplest, matches the docs):
repo(RW),issue(RW),organization(R),user(R)alexowns.Option B — Fine-grained PAT (if you must keep using one):
alex/renovate-bot.Either way, re-store it as
PI_TOKEN(the workflow already passes${{ secrets.PI_TOKEN }}asRENOVATE_TOKEN), then re-run the workflow.Two related findings while I was in here
config.jsusesplatform: 'gitea'. The Renovate docs now say: "Use forgejo as the platform if you are using Forgejo. Forgejo support will be removed from gitea platform in a future release." Since you're on Forgejo, this should beplatform: 'forgejo'. (Doesn't cause the one-repo bug, but is a pending breakage.)issue(RW) +organization(R) as shown above.I have not changed any files — the actual fix (the token) lives in Forgejo's UI, not in this repo. If you'd like, I can open a follow-up PR that updates
config.jstoplatform: 'forgejo'and corrects the README's PAT scope list.View action run | Model: zai/glm-5.2 (thinking: xhigh) | Time: 4m 15s | Tokens: 176.2K | Pi SDK v0.80.3 | Action v2.25.1
/pi new pr to update the readme with token permissions docs (also links to official docs related)
Now let me check the issue thread for more context:Now I have the full picture. Let me update the README with comprehensive token permissions documentation, including the correct scopes, the classic vs fine-grained PAT distinction, and links to official docs.Now let me also update the Troubleshooting section to reference the token permissions more specifically:Let me also update the Resources section to include the Forgejo token docs:Let me verify the final result:The README looks complete and accurate. Let me create the PR:Let me try manually creating the branch and PR:Branch pushed. Now let me create the PR via the API:PR #11 has been created and is ready for review.
What changed
The README's token setup section is now comprehensive, covering the exact permissions needed for autodiscovery and PR creation across all repos:
Required scopes table — adds
issue(RW) andorganization(R) alongside the previously documentedrepo+user. This is critical because in Forgejo/Gitea, pull requests are modeled as issues, so theissuescope is required to open and update PRs on Forgejo ≥ 1.20.Classic PAT vs fine-grained PAT — explains the root cause of the "only one repo discovered" bug: a fine-grained token scoped to a single repository causes autodiscover to find only that repo. A classic PAT (or a fine-grained PAT with "All repositories" access) grants the account-wide access that
autodiscoverneeds.Troubleshooting checklist — step-by-step diagnosis for the single-repo scenario, including the fact that Renovate silently skips repos where the token lacks write permission.
Other corrections:
RENOVATE_TOKEN→PI_TOKEN(matches the actual workflow'ssecrets.PI_TOKEN)View action run | Model: zai/glm-5.2 (thinking: xhigh) | Time: 4m 41s | Tokens: 249.8K | Pi SDK v0.80.3 | Action v2.25.1