Skip to main content

github-actions-advanced

Design, debug, and harden GitHub Actions CI/CD workflows, including reusable workflows, matrix builds, self-hosted runners, OIDC authentication, caching, environments, secrets, and release automation.

Quellinformationen

Repository
alpertuncortak/crypto-data-pipeline
Letzte Quellaktivität
3. Juni 2026 um 12:03
Erkannte Sprache von SKILL.md
Englisch
Sterne
2
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
github-actions-advanced
description
Design, debug, and harden GitHub Actions CI/CD workflows, including reusable workflows, matrix builds, self-hosted runners, OIDC authentication, caching, environments, secrets, and release automation.
category
devops
risk
safe
source
community
date_added
2026-05-30
# GitHub Actions Advanced Skill Expert guidance for designing, writing, debugging, and securing **production-grade** GitHub Actions workflows. --- ## When to Use This Skill - User mentions GitHub Actions, `.github/workflows`, CI/CD pipelines, runners, jobs, steps, or actions - User wants to automate builds, tests, deployments, or releases via GitHub - User asks about matrix builds, reusable workflows, composite actions, or self-hosted runners - User needs help with OIDC authentication, caching strategies, or secrets management - User says "my GitHub pipeline is failing" or "set up CI for my repo" - User asks about workflow security, hardening, or environment protection rules ## When NOT to Use This Skill - The user is working with GitLab CI/CD → recommend `gitlab-ci-patterns` - The user is working with CircleCI, Jenkins, or other CI platforms - The task is purely about Docker image building without GitHub context → recommend `docker-expert` - The task is about Kubernetes deployment configuration → recommend `kubernetes-architect` --- ## Step 1: Understand Context Before Responding When invoked, first gather context: ```bash # Discover existing workflows in the repo find .github/workflows -name "*.yml" -o -name "*.yaml" 2>/dev/null | head -20 # Check for composite actions find .github/actions -name "action.yml" 2>/dev/null # Detect tech stack (influences runner OS, language setup actions) ls package.json requirements.txt Gemfile go.mod Cargo.toml pom.xml 2>/dev/null ``` Then adapt recommendations to: - Existing workflow patterns in the repo - The tech stack and language runtime - Whether this is a monorepo or single-project repo - Whether self-hosted or GitHub-hosted runners are in use --- ## Workflow Structure Reference ```yaml name: Workflow Name on: # Triggers (see Triggers section) push: branches: [main] permissions: # Always declare — principle of least privilege contents: read env: # Workflow-level env vars NODE_VERSION: '20' concurrency: # Prevent duplicate runs group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true # Cancel older runs for same branch jobs: job-id: name: Human-readable name runs-on: ubuntu-24.04 # Pin OS version — never use -latest in prod timeout-minutes: 15 # Always set — prevents runaway jobs environment: production # Links to GitHub Environment (approvals/secrets) steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Step name run: echo "hello" ``` --- ## Triggers (`on:`) ### Common Patterns ```yaml on: push: branches: [main, 'release/**'] paths-ignore: ['**.md', 'docs/**'] # Skip docs-only changes pull_request: types: [opened, synchronize, reopened] branches: [main] workflow_dispatch: # Manual trigger with inputs inputs: environment: description: 'Deploy target' required: true type: choice options: [staging, production] dry-run: description: 'Dry run only?' type: boolean default: false schedule: - cron: '0 2 * * 1' # Monday 2am UTC workflow_call: # Called by other workflows (reusable) inputs: image-tag: type: string required: true secrets: deploy-token: required: true release: types: [published] # Trigger only on published releases pull_request_target: # Runs with repo secrets — use with care! types: [labeled] # Gate with label + author_association check ``` > **Security Warning:** `pull_request_target` runs with repo secrets. Only use after a maintainer labels the PR. Never check out fork code without explicit sandboxing. --- ## Reusable Workflows Split large pipelines into composable units stored in `.github/workflows/`. **Convention:** Prefix internal/reusable workflows with `_` (e.g., `_build.yml`). ### Caller (`.github/workflows/deploy.yml`) ```yaml jobs: call-build: uses: ./.github/workflows/_build.yml # Same-repo reusable # uses: org/repo/.github/workflows/build.yml@main # Cross-repo with: image-tag: ${{ github.sha }} secrets: inherit # Pass all caller secrets down call-test: uses: ./.github/workflows/_test.yml with: node-version: '20' secrets: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} # Explicit secret passing ``` ### Reusable Workflow (`.github/workflows/_build.yml`) ```yaml on: workflow_call: inputs: image-tag: type: string required: true push: type: boolean default: false secrets: registry-token: required: false outputs: digest: description: "Image digest" value: ${{ jobs.build.outputs.digest }} jobs: build: runs-on: ubuntu-24.04 timeout-minutes: 20 outputs: digest: ${{ steps.build.outputs.digest }} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - id: build uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0 with: push: ${{ inputs.push }} tags: myapp:${{ inputs.image-tag }} ``` --- ## Matrix Builds ```yaml jobs: test: strategy: fail-fast: false # Don't cancel others if one fails max-parallel: 4 # Limit concurrent runners matrix: os: [ubuntu-24.04, windows-2022, macos-14] node: ['18', '20', '22'] exclude: - os: windows-2022 node: '18' include: - os: ubuntu-24.04 node: '22' experimental: true # Custom matrix variable runs-on: ${{ matrix.os }} timeout-minutes: 20 steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: ${{ matrix.node }} cache: 'npm' - run: npm ci - run: npm test continue-on-error: ${{ matrix.experimental == true }} ``` ### Dynamic Matrix via Script ```yaml jobs: generate-matrix: runs-on: ubuntu-24.04 outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - id: set-matrix run: | SERVICES=$(ls services/ | jq -R -s -c 'split("\n")[:-1]') echo "matrix={\"service\":$SERVICES}" >> $GITHUB_OUTPUT build: needs: generate-matrix strategy: matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} runs-on: ubuntu-24.04 steps: - run: echo "Building ${{ matrix.service }}" ``` --- ## Caching Strategies ### Language Setup Actions (Preferred — No Extra Step Needed) ```yaml # Node.js - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: '20' cache: 'npm' # or 'yarn' or 'pnpm' # Python - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: '3.12' cache: 'pip' # Go - uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: '1.23' cache: true # Java / Gradle / Maven - uses: actions/setup-java@7a6d8a8234af8eb26422e24052f73b12b0e46a27 # v4.6.0 with: distribution: 'temurin' java-version: '21' cache: 'maven' # or 'gradle' ``` ### Manual Cache (Any Tool) ```yaml - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 id: cache-deps with: path: | ~/.cache/pip .venv key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }} restore-keys: | ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }} ${{ runner.os }}-pip- - name: Install deps (only on cache miss) if: steps.cache-deps.outputs.cache-hit != 'true' run: pip install -r requirements.txt ``` ### Docker Layer Caching ```yaml - uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0 with: cache-from: type=gha cache-to: type=gha,mode=max # For registry-backed cache (cross-branch): # cache-from: type=registry,ref=ghcr.io/myorg/myapp:buildcache # cache-to: type=registry,ref=ghcr.io/myorg/myapp:buildcache,mode=max ``` --- ## OIDC Authentication (Keyless Cloud Auth) **Never store long-lived cloud credentials as secrets.** Use OIDC to get short-lived tokens that expire automatically. ### AWS ```yaml permissions: id-token: write contents: read steps: - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 with: role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole aws-region: us-east-1 role-session-name: GitHubActions-${{ github.run_id }} # Trust policy on the IAM role must include: # "token.actions.githubusercontent.com" as OIDC provider # Condition: "repo:org/repo:ref:refs/heads/main" (restrict to branch) ``` ### GCP (Workload Identity Federation) ```yaml permissions: id-token: write contents: read steps: - uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f # v2.1.7 with: workload_identity_provider: projects/123456789/locations/global/workloadIdentityPools/github-pool/providers/github-provider service_account: github-actions@my-project.iam.gserviceaccount.com token_format: access_token # or 'id_token' ``` ### Azure (Federated Identity) ```yaml permissions: id-token: write contents: read steps: - uses: azure/login@a65d910e8af852a8061c627c456678983e180302 # v2.2.0 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} # No client secret needed! Uses OIDC federated credentials ``` --- ## Environments & Deployment Protection ```yaml jobs: deploy-staging: environment: name: staging url: https://staging.myapp.com runs-on: ubuntu-24.04 timeout-minutes: 30 steps: - run: ./scripts/deploy.sh staging deploy-production: needs: deploy-staging environment: name: production url: https://myapp.com # Shown in the GitHub UI deployment panel runs-on: ubuntu-24.04 timeout-minutes: 30 steps: - run: ./scripts/deploy.sh production ``` **Configure in Settings → Environments:** - **Required reviewers** — manual approval gate before run - **Wait timer** — delay after approval (e.g., 10-minute buffer) - **Branch/tag restrictions** — only `main` or `v*` tags can deploy to prod - **Environment-specific secrets** — override repo-level secrets per environment - **Deployment branches** — whitelist which branches can target this environment --- ## Secrets Management ```yaml # Access repo/org/environment secrets env: DB_PASSWORD: ${{ secrets.DB_PASSWORD }} # Auto-provided token — no setup needed - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 with: github-token: ${{ secrets.GITHUB_TOKEN }} # Hierarchy (most specific wins): # environment secret > repo secret > org secret ``` ### Masking Dynamic Values ```yaml - name: Generate and mask dynamic token run: | TOKEN=$(./scripts/generate-token.sh) echo "::add-mask::$TOKEN" # Mask in all subsequent logs echo "DEPLOY_TOKEN=$TOKEN" >> $GITHUB_ENV ``` ### Secrets in Composite Actions ```yaml # Secrets cannot be passed as inputs to composite actions # Pass them as env vars instead: - uses: ./.github/actions/my-action env: SECRET_VALUE: ${{ secrets.MY_SECRET }} ``` --- ## Composite Actions Package reusable step sequences into local actions. No container spin-up, no separate workflow file needed. ### Action Definition (`.github/actions/setup-app/action.yml`) ```yaml name: Setup App description: Install and configure application dependencies inputs: node-version: description: 'Node.js version' required: false default: '20' install-flags: description: 'Additional npm install flags' required: false default: '' outputs: cache-hit: description: 'Whether the dependency cache was hit' value: ${{ steps.cache.outputs.cache-hit }} runs: using: composite steps: - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: ${{ inputs.node-version }} cache: npm
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen