CI/CD Patterns
GitHub Actions patterns for automated builds, tests, and deployments.
Security-Gated Deployment
Block deployment if security checks fail:
jobs:
security-gate:
name: Security Gate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: TruffleHog Secret Scan
uses: trufflesecurity/trufflehog@v3.88.0
with:
path: ./
extra_args: --only-verified
- name: Content Security Scan
run: |
# Custom pattern scanning
if grep -rPn 'sk-[a-zA-Z0-9]{48}' content/; then
echo "::error::API key detected"
exit 1
fi
build:
needs: security-gate # Must pass first
runs-on: ubuntu-latest
# ... build stepsReusable Workflow Pattern
Centralize common workflows:
# .github/workflows/security-sentinel.yml (reusable)
name: Security Sentinel
on:
workflow_call:
inputs:
scan_path:
type: string
default: './'
fail_on_finding:
type: boolean
default: false
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run scans
run: |
# TruffleHog, Trivy, Semgrep
continue-on-error: ${{ !inputs.fail_on_finding }}# Project workflow calling the reusable one
jobs:
security:
uses: org/ops-core/.github/workflows/security-sentinel.yml@main
with:
scan_path: './src'
fail_on_finding: trueStatic Site Deployment
Pattern for GitHub Pages with Quartz/Jekyll:
name: Deploy to GitHub Pages
on:
push:
branches: [main]
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for git dates
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm run build
- uses: actions/upload-pages-artifact@v3
with:
path: public
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/deploy-pages@v4
id: deploymentiOS Testing Workflow
Test multiple Xcode schemes:
name: iOS Tests
on:
push:
paths:
- '**/*.swift'
- '**/project.pbxproj'
jobs:
test:
runs-on: macos-latest
strategy:
matrix:
scheme: [Poker, MadLibs, Quest-Forge]
steps:
- uses: actions/checkout@v4
- name: Test ${{ matrix.scheme }}
run: |
xcodebuild test \
-scheme "${{ matrix.scheme }}" \
-destination "platform=iOS Simulator,name=iPhone 15" \
-resultBundlePath "results/${{ matrix.scheme }}"Scheduled Dashboard Updates
Run workflows on schedule:
name: Update Dashboards
on:
schedule:
- cron: '0 */6 * * *' # Every 6 hours
workflow_dispatch: # Manual trigger
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run aggregation
run: python scripts/aggregate.py
- name: Commit changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
git diff --staged --quiet || git commit -m "chore: update dashboards"
git pushPre-Commit Integration
Use Husky for local hooks, CI for enforcement:
# In CI - verify what pre-commit should have caught
- name: Lint check
run: npm run lint
- name: Security scan
run: npm run security:scanBest Practices
| Practice | Why |
|---|---|
| Pin action versions | Reproducible builds |
Use fetch-depth: 0 | Need full git history |
| Separate build/deploy jobs | Can retry deploy without rebuild |
| Use environments | Track deployment status |
| Cache node_modules | Faster builds |