fix: make translation workflow work without a Copilot plan - #80
Merged
Conversation
The run after PR 76 merged failed with a bare "HTTP Error 403: Forbidden" traceback, which says nothing about why or what to do. The endpoint explains itself in the response body, so read it and print it. For 401 and 403 specifically, spell out the actual cause: a repository GITHUB_TOKEN inherits the organisation's GitHub Models access, not that of whoever triggered the run, so 'models: read' in the workflow is necessary but not sufficient and an org owner has to enable Models. A personal token working locally is not evidence that CI will work, which is exactly how this got missed.
The scheduled run failed with 403 because GitHub Models access is a Copilot entitlement, and a repository GITHUB_TOKEN carries the organisation's entitlement rather than the triggering user's. This org is on the free plan with no Copilot seats, so the built-in token cannot reach GitHub Models however the workflow permissions are set, and the org settings offer nothing to enable. A personal token working locally was never evidence that CI would work. Both GitHub Models and OpenRouter speak the same chat/completions shape, so the endpoint, key and model are now a small provider table. Whichever API key is present decides which is used, OPENROUTER_API_KEY first; TRANSLATE_PROVIDER and TRANSLATE_MODEL override for one-off runs. OpenRouter needs no Copilot entitlement, has no 4000-token output cap, and costs roughly twelve cents for a full nine-language backfill, which is already done. Drops the now-pointless 'models: read' permission so the next reader does not assume it is load-bearing.
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.
The scheduled run after #76 merged failed with
403 Forbidden. Everything up to the API call was correct, including finding the 18 new melody strings and chunking them, but the request itself was rejected.Cause
GitHub Models access is a Copilot entitlement, and a repository
GITHUB_TOKENcarries the organisation's entitlement rather than that of whoever triggered the run. This org is on the free plan with 0 Copilot seats, so the built-in token cannot reach GitHub Models however the workflow permissions are set. There is also nothing to switch on: the Models section does not appear in organisation settings at all, because the entitlement is missing.This was missed because local testing used a personal access token backed by a personal Copilot entitlement. That validated the translation logic but proved nothing about CI, since the two are different identities.
Fix
GitHub Models and OpenRouter speak the same OpenAI-compatible chat/completions shape, so the endpoint, key and model become a small provider table. Whichever API key is present decides which is used:
OPENROUTER_API_KEYMODELS_TOKENmodels:read.GITHUB_TOKENTRANSLATE_PROVIDERandTRANSLATE_MODELoverride the choice for one-off runs, which also makes it easy to A/B a cheaper model.OpenRouter costs roughly $0.12 for a full nine-language backfill. That backfill is already done, so ongoing cost is a fraction of a cent per year.
Also in this PR
models: readpermission, which was doing nothing, so the next reader does not assume it is load-bearing.Setup
Requires an
OPENROUTER_API_KEYrepository secret (already added). A repository secret rather than an organisation one keeps it readable only by this repo, and because the workflow is push-triggered rather thanpull_request-triggered, fork PRs never receive it.Verification
TRANSLATE_PROVIDERandTRANSLATE_MODELoverrides.githubprovider.verify_translations.pystill passing on all 9 languages.