mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
ci(release): authenticate main pushes with an admin RELEASE_TOKEN (#486)
Point semantic-release's version-bump push and the docs-changelog push at a RELEASE_TOKEN admin PAT so they clear the 16 required checks (default token is rejected). Falls back to the default token, so no change until the secret is set. Documents creating/rotating the token in RELEASE.md.
This commit is contained in:
@@ -37,7 +37,12 @@ jobs:
|
||||
|
||||
- name: Run semantic-release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# RELEASE_TOKEN is a fine-grained PAT (repo Contents/Issues/PRs: write)
|
||||
# owned by an admin, so semantic-release's push of the chore(release)
|
||||
# commit + tag clears branch protection (enforce_admins is off). Falls
|
||||
# back to the default token if the secret is unset, so behaviour is
|
||||
# unchanged until the secret exists.
|
||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
run: npx semantic-release
|
||||
|
||||
- name: Check for new release
|
||||
@@ -72,7 +77,7 @@ jobs:
|
||||
- name: Update docs changelog
|
||||
if: steps.notes.outputs.has_notes == 'true' && steps.check.outputs.version
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
VERSION: ${{ steps.check.outputs.version }}
|
||||
run: |
|
||||
CHANGELOG="apps/docs/changelog.md"
|
||||
@@ -100,8 +105,12 @@ jobs:
|
||||
git config user.name "SnapOtter"
|
||||
git config user.email "snapotter.hq@gmail.com"
|
||||
git add "$CHANGELOG"
|
||||
git commit -m "docs: update changelog for v${VERSION}" || true
|
||||
git push origin HEAD:main || true
|
||||
git commit -m "docs: update changelog for v${VERSION} [skip ci]" || true
|
||||
# Authenticate this direct push explicitly: the job's checkout uses
|
||||
# persist-credentials: false, so there is no ambient credential. The
|
||||
# PAT's admin identity bypasses branch protection; if the secret is
|
||||
# unset this no-ops (|| true) exactly as before.
|
||||
git push "https://x-access-token:${RELEASE_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" HEAD:main || true
|
||||
echo "Docs changelog updated for v${VERSION}."
|
||||
|
||||
prebuilt:
|
||||
|
||||
+18
@@ -15,6 +15,24 @@ SnapOtter ships a multi-arch container image to Docker Hub (`snapotter/snapotter
|
||||
|
||||
The `manifest` job targets the `publish-images` GitHub Environment, which requires a maintainer to approve the run before it proceeds. If Trivy fails at step 4, `manifest` never runs and no tags are published.
|
||||
|
||||
## One-time setup: `RELEASE_TOKEN`
|
||||
|
||||
Step 1 (`release`) pushes a version-bump commit and tag to `main`, which is protected. The default GitHub Actions token cannot push past the required status checks, so the workflow authenticates that push with `RELEASE_TOKEN`: a fine-grained PAT owned by an admin. Because `enforce_admins` is off on `main`, an admin identity bypasses the checks.
|
||||
|
||||
Create it once, and rotate it when it expires:
|
||||
|
||||
1. GitHub → **Settings → Developer settings → Fine-grained personal access tokens → Generate new token**.
|
||||
2. Resource owner: `snapotter-hq`. Repository access: **Only select repositories → `snapotter-hq/SnapOtter`**.
|
||||
3. Repository permissions: **Contents** read+write, **Issues** read+write, **Pull requests** read+write. semantic-release commits and tags (Contents) and comments on released issues/PRs (Issues, Pull requests). Metadata read is added automatically.
|
||||
4. Expiration: your call, up to a year. Set a reminder to rotate before it lapses.
|
||||
5. Store it as a repo secret:
|
||||
```bash
|
||||
gh secret set RELEASE_TOKEN --repo snapotter-hq/SnapOtter
|
||||
```
|
||||
Paste the token when prompted.
|
||||
|
||||
If `RELEASE_TOKEN` is missing, the workflow falls back to the default token, the push to `main` is rejected by branch protection, and the `release` job fails at the semantic-release step. So set the secret before cutting a release. A classic PAT with the `repo` scope also works and is simpler to configure, but it can reach every repo you have access to, so the fine-grained token is preferred.
|
||||
|
||||
## Cut a release
|
||||
|
||||
1. Make sure `main` is green and everything you want in the release is merged.
|
||||
|
||||
Reference in New Issue
Block a user