pre-commit: authentication in internal github repos
β’ 309 words β’ 2 min β’ updated
Problem statement: prek can’t clone a repo: that lives in an internal
(private) GitHub repo β https:// clone fails without credentials.
I forked my personal
pre-commit-hooks into an
org-owned repo and updated all our .pre-commit-config.yaml files to point at
it:
- repo: https://github.com/<org>/pre-commit-hooks
rev: 5695e23285bef67d1dee957e5c12e86f58ba843b # frozen: v1.0.0
hooks:
- id: check-bash-shebangThis approach works locally (my GitHub token is broad).
CI (github actions) fails though:
fatal: could not read Username for 'https://github.com': terminal prompts disabledThe repo is INTERNAL, not public. As such, prek clones the repo: URL to
fetch the hooks; with no credentials on the runner, it can’t.
First instinct: git@github.com:<org>/pre-commit-hooks. Runners have no SSH
key though!
The fix is to keep https:// in the config, mint a short-lived token that can read
the hooks repo, and tell git to rewrite the URL:
- name: Generate app token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
id: generate-token
with:
client-id: ${{ vars.APP_CLIENT_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: pre-commit-hooks
permission-contents: read
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: Authenticate git for internal hook repos
env:
TOKEN: ${{ steps.generate-token.outputs.token }}
run: git config --global url."https://x-access-token:${TOKEN}@github.com/".insteadOf "https://github.com/"
- uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2.0.4Two things worth noting.
-
First: never inline
${{ steps.generate-token.outputs.token }}directly into arun:shell string β zizmor (a GitHub Actions security linter) flags it as a template injection risk. Pass it viaenv:and use the shell variable instead. -
Second: the
repositories: pre-commit-hooksscope only works if the App is actually installed on that repo. That one is a manual step in GitHub’s UI βgithub.com/organizations/<org>/settings/installationsβ the App β Repository access β add the repo. No amount of YAML fixes it otherwise; it silently returns a 404 from the App installation endpoint otherwise.
After the installation grant, the clone goes through and prek runs cleanly.
π€ Drafted with /bloggify.