How to properly support optional secrets.OTHER_TOKEN instead of GitHub default token in GitHub Actions workflows
✅ DO:
env:
GITHUB_TOKEN: ${{ secrets.OTHER_TOKEN || github.token }}
jobs:
job1:
# ...use env.GITHUB_TOKEN...
reusable:
uses: org/repo/.github/workflows/reusable.yml@main
secrets:
GITHUB_TOKEN: ${{ secrets.OTHER_TOKEN || github.token }} # duplication because env context is not allowed here❌ DON'T:
- Don't use
github.tokenorsecrets.GITHUB_TOKENdirectly. - Don't set
env.GITHUB_TOKENwithout fallback togithub.token. - Don't forget to pass token to reusable workflow through
secrets.GITHUB_TOKEN(even in case workflow also accept token in some othersecretsorinputs).
✅ DO:
on:
workflow_call: # no token-related inputs/secrets needed
permissions: # always set minimal required permissions
contents: read
issues: write # example
jobs:
reusable:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # for use in steps
steps:
call_other:
uses: ./.github/workflows/helper.yml
secrets:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}❌ DON'T:
- Don't use
github.token. - Don't add explicit token
inputs/secrets- they add complexity without benefits. - Don't skip setting permissions (they will have no effect when using OTHER_TOKEN, but still useful without OTHER_TOKEN).
✅ DO:
steps:
# Use env.GITHUB_TOKEN for maximum compatibility:
- uses: actions/some-action@v1
env:
GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }}
# If action supports token via with:
- uses: actions/another-action@v1
env:
GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }} # always set env too
with:
token: ${{ env.GITHUB_TOKEN }} # and pass via with❌ DON'T:
- Don't skip setting
env.GITHUB_TOKENeven if action accepts token viawith. - Don't use
github.tokenorsecrets.GITHUB_TOKENdirectly.
This setup enables:
- Alternative token use when needed (
secrets.OTHER_TOKEN). - Fallback to default token when not needed.
- Proper permissions when using default token.
- Maximum compatibility with all action types.
- If 3rd-party reusable workflow uses
github.token(it must usesecrets.GITHUB_TOKENinstead). - If 3rd-party action uses
github.tokenorsecrets.GITHUB_TOKEN(it must useenv.GITHUB_TOKENand/or custom inputs instead - with fallback to any ofgithub.tokenorsecrets.GITHUB_TOKEN).