mirror of
https://github.com/garrytan/gstack.git
synced 2026-08-31 18:30:39 +02:00
fix(ci): least-privilege permissions + fork-safe concurrency keys
- evals.yml / evals-periodic.yml evals jobs: explicit contents:read + packages:read (container-image pull) and persist-credentials:false — the jobs that execute PR-authored code with three provider API keys ran on the repo-default token grant with the token written into .git/config - permissions blocks for the 4 workflows that had none (skill-docs, make-pdf-gate, windows-free-tests, windows-setup-e2e) - fork-safe concurrency keys: actionlint, skill-docs, make-pdf-gate, windows-setup-e2e switch from head_ref to PR-number keying — a bare branch name carries no fork prefix, so same-name branches from two forks shared one group and cancelled each other's runs Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
9fbd0700ff
commit
e2904be7a4
@@ -6,11 +6,11 @@ on:
|
|||||||
branches: [main]
|
branches: [main]
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
# Cancel superseded runs for the same branch (matches evals.yml,
|
# PR-number keyed (run_id fallback for push): a bare branch name carries no
|
||||||
# windows-free-tests.yml, etc.). head_ref is set on pull_request; ref_name is
|
# fork prefix, so same-name branches from two forks would share one group and
|
||||||
# the fallback for push so a rapid push series doesn't pile up stale lint runs.
|
# cancel each other's runs (same rationale as free-tests.yml).
|
||||||
concurrency:
|
concurrency:
|
||||||
group: actionlint-${{ github.head_ref || github.ref_name }}
|
group: actionlint-${{ github.event.pull_request.number || github.run_id }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
# Lint needs nothing from the token; the job runs a third-party image with
|
# Lint needs nothing from the token; the job runs a third-party image with
|
||||||
|
|||||||
@@ -68,6 +68,11 @@ jobs:
|
|||||||
evals:
|
evals:
|
||||||
runs-on: ubicloud-standard-8
|
runs-on: ubicloud-standard-8
|
||||||
needs: build-image
|
needs: build-image
|
||||||
|
# Least privilege (mirrors evals.yml): read-only contents, packages:read
|
||||||
|
# for the container-image pull.
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: read
|
||||||
container:
|
container:
|
||||||
image: ${{ needs.build-image.outputs.image-tag }}
|
image: ${{ needs.build-image.outputs.image-tag }}
|
||||||
credentials:
|
credentials:
|
||||||
@@ -110,6 +115,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Fix bun temp
|
- name: Fix bun temp
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -89,6 +89,13 @@ jobs:
|
|||||||
runs-on: ${{ matrix.suite.runner || 'ubicloud-standard-8' }}
|
runs-on: ${{ matrix.suite.runner || 'ubicloud-standard-8' }}
|
||||||
needs: build-image
|
needs: build-image
|
||||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
||||||
|
# Least privilege for the job that executes PR-authored code with three
|
||||||
|
# provider API keys in env: read-only contents, packages:read for the
|
||||||
|
# container-image pull below. Without this block the job ran on the
|
||||||
|
# repo-default token grant.
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: read
|
||||||
container:
|
container:
|
||||||
image: ${{ needs.build-image.outputs.image-tag }}
|
image: ${{ needs.build-image.outputs.image-tag }}
|
||||||
credentials:
|
credentials:
|
||||||
@@ -176,6 +183,9 @@ jobs:
|
|||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
# Don't write the token into .git/config — this job runs
|
||||||
|
# PR-authored code; nothing in it pushes.
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
# Bun creates root-owned temp dirs during Docker build. GH Actions runs as
|
# Bun creates root-owned temp dirs during Docker build. GH Actions runs as
|
||||||
# runner user with HOME=/github/home. Redirect bun's cache to a writable dir.
|
# runner user with HOME=/github/home. Redirect bun's cache to a writable dir.
|
||||||
|
|||||||
@@ -16,9 +16,15 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: make-pdf-gate-${{ github.head_ref || github.run_id }}
|
# PR-number keyed: head_ref carries no fork prefix, so same-name branches
|
||||||
|
# from two forks would share one group and cancel each other's runs.
|
||||||
|
group: make-pdf-gate-${{ github.event.pull_request.number || github.run_id }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
# Build + test only — no token writes.
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
gate:
|
gate:
|
||||||
strategy:
|
strategy:
|
||||||
|
|||||||
@@ -10,9 +10,16 @@ on:
|
|||||||
# windows-free-tests.yml, etc.). head_ref is set on pull_request; ref_name is
|
# windows-free-tests.yml, etc.). head_ref is set on pull_request; ref_name is
|
||||||
# the fallback for push so a rapid push series doesn't pile up stale runs.
|
# the fallback for push so a rapid push series doesn't pile up stale runs.
|
||||||
concurrency:
|
concurrency:
|
||||||
group: skill-docs-${{ github.head_ref || github.ref_name }}
|
# PR-number keyed (run_id fallback for push/dispatch): a bare branch name
|
||||||
|
# carries no fork prefix, so same-name branches from two forks would share
|
||||||
|
# one group and cancel each other's runs (same rationale as free-tests.yml).
|
||||||
|
group: skill-docs-${{ github.event.pull_request.number || github.run_id }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
# The job only reads the checkout and runs the generator — no token writes.
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-freshness:
|
check-freshness:
|
||||||
runs-on: ubicloud-standard-2
|
runs-on: ubicloud-standard-2
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ concurrency:
|
|||||||
group: windows-free-${{ github.event.pull_request.number || github.run_id }}
|
group: windows-free-${{ github.event.pull_request.number || github.run_id }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
# Test-only lane — no token writes.
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
windows-free-tests:
|
windows-free-tests:
|
||||||
# Ubicloud Windows runner (same provider as the Linux evals workflow).
|
# Ubicloud Windows runner (same provider as the Linux evals workflow).
|
||||||
|
|||||||
@@ -26,9 +26,15 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: windows-setup-e2e-${{ github.head_ref || github.run_id }}
|
# PR-number keyed: head_ref carries no fork prefix, so same-name branches
|
||||||
|
# from two forks would share one group and cancel each other's runs.
|
||||||
|
group: windows-setup-e2e-${{ github.event.pull_request.number || github.run_id }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
# Install-path exercise only — no token writes.
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
windows-setup:
|
windows-setup:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
|||||||
Reference in New Issue
Block a user