chore(ci): comprehensive CI/CD audit fixes per best practices

Implements all 13 fixes identified in the CI/CD audit against
github-actions-ci-cd-best-practices.instructions.md

Critical fixes:

Remove hardcoded encryption key from playwright.yml (security)
Fix artifact filename mismatch in supply-chain-pr.yml (bug)
Pin GoReleaser to ~> v2.5 instead of latest (supply chain)
High priority fixes:

Upgrade CodeQL action from v3 to v4 in supply-chain-pr.yml
Add environment protection for release workflow
Fix shell variable escaping ($$ → $) in release-goreleaser.yml
Medium priority fixes:

Add timeout-minutes to playwright.yml (20 min)
Add explicit permissions to quality-checks.yml
Add timeout-minutes to codecov-upload.yml jobs (15 min)
Fix benchmark.yml permissions (workflow-level read, job-level write)
Low priority fixes:

Add timeout-minutes to docs.yml jobs (10/5 min)
Add permissions block to docker-lint.yml
Add timeout-minutes to renovate.yml (30 min)
This commit is contained in:
GitHub Actions
2026-01-15 15:25:58 +00:00
parent 0892637164
commit 3590553519
10 changed files with 759 additions and 55 deletions

View File

@@ -22,14 +22,19 @@ concurrency:
env:
GO_VERSION: '1.25.5'
# Minimal permissions at workflow level; write permissions granted at job level for push only
permissions:
contents: write
deployments: write
contents: read
jobs:
benchmark:
name: Performance Regression Check
runs-on: ubuntu-latest
# Grant write permissions for storing benchmark results (only used on push via step condition)
# Note: GitHub Actions doesn't support dynamic expressions in permissions block
permissions:
contents: write
deployments: write
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

View File

@@ -22,6 +22,7 @@ jobs:
backend-codecov:
name: Backend Codecov Upload
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
@@ -53,6 +54,7 @@ jobs:
frontend-codecov:
name: Frontend Codecov Upload
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

View File

@@ -14,6 +14,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
hadolint:
runs-on: ubuntu-latest

View File

@@ -28,6 +28,7 @@ jobs:
build:
name: Build Documentation
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
# Step 1: Get the code
@@ -331,6 +332,7 @@ jobs:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
timeout-minutes: 5
needs: build
steps:

View File

@@ -23,6 +23,7 @@ jobs:
playwright:
name: E2E Tests
runs-on: ubuntu-latest
timeout-minutes: 20
# Only run for PRs or manual dispatch
if: >-
github.event_name == 'workflow_dispatch' ||
@@ -31,7 +32,7 @@ jobs:
env:
CHARON_ENV: development
CHARON_DEBUG: "1"
CHARON_ENCRYPTION_KEY: dGVzdC1lbmNyeXB0aW9uLWtleS1mb3ItY2ktMzJieXQ=
CHARON_ENCRYPTION_KEY: ${{ secrets.CHARON_CI_ENCRYPTION_KEY }}
steps:
- name: Checkout repository

View File

@@ -10,6 +10,10 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
checks: write
env:
GO_VERSION: '1.25.5'
NODE_VERSION: '24.12.0'

View File

@@ -20,6 +20,9 @@ permissions:
jobs:
goreleaser:
runs-on: ubuntu-latest
environment:
name: release
url: https://github.com/${{ github.repository }}/releases
env:
# Use the built-in GITHUB_TOKEN by default for GitHub API operations.
# If you need to provide a PAT with elevated permissions, add a GITHUB_TOKEN secret
@@ -45,8 +48,8 @@ jobs:
working-directory: frontend
run: |
# Inject version into frontend build from tag (if present)
VERSION=$${GITHUB_REF#refs/tags/}
echo "VITE_APP_VERSION=$$VERSION" >> $GITHUB_ENV
VERSION=${GITHUB_REF#refs/tags/}
echo "VITE_APP_VERSION=${VERSION}" >> $GITHUB_ENV
npm ci
npm run build
@@ -63,7 +66,7 @@ jobs:
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6
with:
distribution: goreleaser
version: latest
version: '~> v2.5'
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -17,6 +17,7 @@ permissions:
jobs:
renovate:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

View File

@@ -169,14 +169,14 @@ jobs:
if: steps.check-artifact.outputs.artifact_found == 'true'
id: load-image
run: |
if [[ ! -f "pr-image.tar" ]]; then
echo "❌ pr-image.tar not found in artifact"
if [[ ! -f "charon-pr-image.tar" ]]; then
echo "❌ charon-pr-image.tar not found in artifact"
ls -la
exit 1
fi
echo "🐳 Loading Docker image..."
LOAD_OUTPUT=$(docker load -i pr-image.tar)
LOAD_OUTPUT=$(docker load -i charon-pr-image.tar)
echo "${LOAD_OUTPUT}"
# Extract image name from load output
@@ -273,8 +273,8 @@ jobs:
- name: Upload SARIF to GitHub Security
if: steps.check-artifact.outputs.artifact_found == 'true'
# github/codeql-action v3.28.1
uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d
# github/codeql-action v4
uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89
continue-on-error: true
with:
sarif_file: grype-results.sarif