Configure Release Token for Automated Releases¶
This guide explains how to set up a Personal Access Token (PAT) to allow the automated release workflow to bypass branch protection rules.
Why This Is Needed¶
The automated release workflow (release.yml) needs to push commits to the protected main branch:
PSR creates a release commit (
chore(release): X.Y.Z)PSR updates
pyproject.tomlandCHANGELOG.mdPSR creates and pushes a git tag
The default GITHUB_TOKEN cannot bypass branch protection, so PSR fails with:
remote: error: GH006: Protected branch update failed for refs/heads/main
Solution: Use a Personal Access Token¶
A fine-grained Personal Access Token (PAT) with specific permissions can bypass branch protection.
Setup Steps¶
1. Create Fine-Grained Personal Access Token¶
Click “Generate new token” → “Generate new token (fine-grained)”
Configure the token:
Token name:
gamesheet-sdk-py-release-tokenDescription: “Allows automated release workflow to push to protected main branch”
Expiration: 1 year (or custom - you’ll need to renew it)
Repository access: Only select repositories →
gamesheet-sdk-pyPermissions:
Contents: Read and write ✅
Metadata: Read-only (automatically selected) ✅
Click “Generate token”
Copy the token (you won’t see it again!)
2. Add Token as Repository Secret¶
Go to: https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets
Click “New repository secret”
Configure:
Name:
RELEASE_TOKENSecret: Paste the token you copied
Click “Add secret”
3. Verify Workflow Configuration¶
The workflow (.github/workflows/release.yml) should already be configured to use the token:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
# Use PAT with permissions to bypass branch protection
token: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
- name: Run semantic-release
env:
GH_TOKEN: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
run: |
semantic-release version --changelog
The || fallback means:
If
RELEASE_TOKENexists → use it (can bypass protection)If
RELEASE_TOKENis missing → useGITHUB_TOKEN(will fail on protected branches)
Testing¶
After setting up the token:
Create a test commit with a conventional commit message:
git checkout -b test/release-token echo "# Test" >> README.md git add README.md git commit -m "chore: test release token configuration" git push -u origin test/release-token
Create and merge a PR to
mainThe
Version and Releaseworkflow should run successfully and push the release commit tomain
Token Renewal¶
Fine-grained PATs expire. When your token expires:
You’ll see workflow failures with authentication errors
Generate a new token following the same steps above
Update the
RELEASE_TOKENsecret with the new value
Set a calendar reminder to renew the token before it expires!
Security Considerations¶
Least Privilege: The token only has
Contents: writepermission on one repositoryExpiration: Tokens expire, requiring periodic renewal (reduces risk of leaked tokens)
Repository Secret: The token is encrypted and only accessible to workflows
Audit Trail: All actions taken with the token are logged in the repository
Alternative: GitHub App (More Secure)¶
For organizations or projects requiring higher security, consider using a GitHub App instead:
More granular permissions
Rotating credentials
Better audit logging
No expiration issues
Troubleshooting¶
Workflow Still Fails with “Protected branch update failed”¶
Check:
Token was created with
Contents: writepermissionToken was added as
RELEASE_TOKENsecret (exact name matters)Token hasn’t expired
Token scope includes the
gamesheet-sdk-pyrepository
Token Expired¶
Error: Bad credentials or 401 Unauthorized
Solution: Generate a new token and update the secret
Workflow Can’t Find Secret¶
Error: Workflow uses GITHUB_TOKEN instead of RELEASE_TOKEN
Check: Secret name is exactly RELEASE_TOKEN (case-sensitive)