mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-13 20:14:34 +00:00
fix(ci): harden self-hosted workflow trust boundaries
Keep active CCS workflows on self-hosted runners, gate self-hosted PR execution to trusted authors, and scope privileged release credentials to the exact git operations that need them.
This commit is contained in:
1 parent
d86032ed0a
commit
2273757c83
17 files changed
+210
-29
No files matched your search
@@ -74,10 +74,14 @@ jobs:
|
||||
if: >-
|
||||
github.event_name != 'workflow_dispatch' &&
|
||||
(
|
||||
github.event_name == 'pull_request_target' ||
|
||||
(
|
||||
github.event_name == 'pull_request_target' &&
|
||||
contains(fromJSON('["COLLABORATOR","MEMBER","OWNER"]'), github.event.pull_request.author_association)
|
||||
) ||
|
||||
(
|
||||
github.event_name == 'issue_comment' &&
|
||||
github.event.issue.pull_request &&
|
||||
contains(fromJSON('["COLLABORATOR","MEMBER","OWNER"]'), github.event.issue.author_association) &&
|
||||
github.event.comment.body == '/review' &&
|
||||
(
|
||||
contains(fromJSON('["COLLABORATOR","MEMBER","OWNER"]'), github.event.comment.author_association) ||
|
||||
|
||||
@@ -16,6 +16,8 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
if: >-
|
||||
contains(fromJSON('["COLLABORATOR","MEMBER","OWNER"]'), github.event.pull_request.author_association)
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
env:
|
||||
# Keep Bun cache isolated per job workspace so parallel self-hosted runs
|
||||
@@ -58,6 +60,8 @@ jobs:
|
||||
run: ${{ matrix.check.cmd }}
|
||||
|
||||
build:
|
||||
if: >-
|
||||
contains(fromJSON('["COLLABORATOR","MEMBER","OWNER"]'), github.event.pull_request.author_association)
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
name: build
|
||||
env:
|
||||
@@ -98,6 +102,8 @@ jobs:
|
||||
if-no-files-found: error
|
||||
|
||||
test:
|
||||
if: >-
|
||||
contains(fromJSON('["COLLABORATOR","MEMBER","OWNER"]'), github.event.pull_request.author_association)
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
name: test
|
||||
needs: [build]
|
||||
|
||||
@@ -21,7 +21,10 @@ on:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
if: >-
|
||||
github.event_name != 'pull_request' ||
|
||||
contains(fromJSON('["COLLABORATOR","MEMBER","OWNER"]'), github.event.pull_request.author_association)
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
name: Deploy ccs-installer to CloudFlare
|
||||
|
||||
steps:
|
||||
|
||||
@@ -50,9 +50,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: dev
|
||||
# PAT_TOKEN required: dev-release pushes version bump commits to dev,
|
||||
# and protected branches reject github.token writes once status checks are required.
|
||||
token: ${{ secrets.PAT_TOKEN }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
@@ -93,8 +91,16 @@ jobs:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: |
|
||||
# Use custom dev release script instead of semantic-release
|
||||
# This ensures dev versions follow {stable}-dev.{N} pattern
|
||||
auth_header=$(printf 'x-access-token:%s' "$GITHUB_TOKEN" | base64 | tr -d '\n')
|
||||
echo "::add-mask::${auth_header}"
|
||||
export GIT_CONFIG_COUNT=2
|
||||
export GIT_CONFIG_KEY_0=http.https://github.com/kaitranntt/ccs.extraheader
|
||||
export GIT_CONFIG_VALUE_0="AUTHORIZATION: basic ${auth_header}"
|
||||
export GIT_CONFIG_KEY_1=http.https://github.com/kaitranntt/ccs.git.extraheader
|
||||
export GIT_CONFIG_VALUE_1="AUTHORIZATION: basic ${auth_header}"
|
||||
|
||||
# Use custom dev release script instead of semantic-release.
|
||||
# This ensures dev versions follow {stable}-dev.{N} pattern.
|
||||
chmod +x scripts/dev-release.sh
|
||||
./scripts/dev-release.sh
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ concurrency:
|
||||
jobs:
|
||||
publish:
|
||||
if: ${{ github.event_name != 'release' || !github.event.release.prerelease }}
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
@@ -7,7 +7,7 @@ on:
|
||||
|
||||
jobs:
|
||||
label:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: read
|
||||
|
||||
@@ -7,7 +7,7 @@ on:
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
|
||||
permissions:
|
||||
contents: write # For creating GitHub releases
|
||||
@@ -66,4 +66,4 @@ jobs:
|
||||
## What's Changed
|
||||
See [CHANGELOG.md](https://github.com/kaitranntt/ccs/blob/main/CHANGELOG.md)
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -21,9 +21,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# PAT_TOKEN required: semantic-release pushes version bump commits to main,
|
||||
# which needs branch protection bypass. github.token cannot push to protected branches.
|
||||
token: ${{ secrets.PAT_TOKEN }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
@@ -58,12 +56,20 @@ jobs:
|
||||
env:
|
||||
HUSKY: 0
|
||||
# PAT_TOKEN bypasses branch protection so semantic-release can push
|
||||
# version bump + CHANGELOG commits directly to main
|
||||
# version bump + CHANGELOG commits directly to main.
|
||||
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: |
|
||||
auth_header=$(printf 'x-access-token:%s' "$GITHUB_TOKEN" | base64 | tr -d '\n')
|
||||
echo "::add-mask::${auth_header}"
|
||||
export GIT_CONFIG_COUNT=2
|
||||
export GIT_CONFIG_KEY_0=http.https://github.com/kaitranntt/ccs.extraheader
|
||||
export GIT_CONFIG_VALUE_0="AUTHORIZATION: basic ${auth_header}"
|
||||
export GIT_CONFIG_KEY_1=http.https://github.com/kaitranntt/ccs.git.extraheader
|
||||
export GIT_CONFIG_VALUE_1="AUTHORIZATION: basic ${auth_header}"
|
||||
|
||||
set +e
|
||||
OUTPUT=$(bun x semantic-release 2>&1)
|
||||
STATUS=$?
|
||||
|
||||
@@ -22,7 +22,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
sync-project:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -10,16 +10,20 @@ jobs:
|
||||
runs-on: [self-hosted, linux, x64]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# PAT_TOKEN is required because this pushes to protected dev and must
|
||||
# trigger follow-up Push CI / Dev Release workflows.
|
||||
token: ${{ secrets.PAT_TOKEN }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Harden Git workspace
|
||||
run: |
|
||||
rm -rf .git/hooks
|
||||
mkdir -p .git/hooks
|
||||
git config --local core.hooksPath /dev/null
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
@@ -47,4 +51,14 @@ jobs:
|
||||
git commit --no-edit
|
||||
fi
|
||||
|
||||
git push origin dev
|
||||
# PAT_TOKEN is required because this pushes to protected dev and must
|
||||
# trigger follow-up Push CI / Dev Release workflows. Keep it scoped to
|
||||
# the final push rather than persisting it in the checkout config.
|
||||
auth_header=$(printf 'x-access-token:%s' "$PAT_TOKEN" | base64 | tr -d '\n')
|
||||
echo "::add-mask::${auth_header}"
|
||||
git -c core.hooksPath=/dev/null \
|
||||
-c "http.https://github.com/kaitranntt/ccs.extraheader=AUTHORIZATION: basic ${auth_header}" \
|
||||
-c "http.https://github.com/kaitranntt/ccs.git.extraheader=AUTHORIZATION: basic ${auth_header}" \
|
||||
push origin dev
|
||||
env:
|
||||
PAT_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||
Reference in new issue
Block a user