Github Actions

作者 bobmatnyc718070a7d622无许可证77 个星标收录于 2026年10月8日更新于 2026年10月8日仓库2个月前更新

GitHub Actions CI/CD workflows for automating build, test, and deployment

仅含说明DevOps & Cloud
AI 生成的概览

用于编写 GitHub Actions CI/CD 工作流 YAML 的参考指南,涵盖构建、测试与部署自动化。

功能
该技能提供关于 GitHub Actions(GitHub 原生 CI/CD 平台)的说明文档。它讲解工作流 YAML 结构、触发器、作业、步骤、动作、上下文、运行器、矩阵策略、环境变量与密钥,并附有大量示例片段。内容还涉及特定框架的流水线、部署模式、测试工作流与发布自动化。
适用场景
当你需要编写或理解 GitHub Actions 工作流文件时使用,例如在拉取请求上自动运行测试、合并后构建与部署、发布软件包或安排定时任务。它是 CI/CD 配置参考,而非可执行工具。
运行要求
不附带脚本,仅为说明文档。应用这些指导需要启用 Actions 的 GitHub 仓库,工作流可能引用仓库密钥、第三方动作以及托管或自托管运行器。

GitHub Actions CI/CD

Summary

GitHub Actions is GitHub's native CI/CD platform for automating software workflows. Define workflows in YAML files to build, test, and deploy code directly from your repository with event-driven automation.

When to Use

  • Automate testing on every pull request
  • Build and deploy applications on merge to main
  • Schedule regular tasks (nightly builds, backups)
  • Publish packages to registries (npm, PyPI, Docker Hub)
  • Run security scans and code quality checks
  • Automate release processes and changelog generation

Quick Start

Basic Test Workflow

Create .github/workflows/test.yml:

yaml
name: Test
on:  push:    branches: [main]  pull_request:    branches: [main]
jobs:  test:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4      - uses: actions/setup-node@v4        with:          node-version: '20'      - run: npm ci      - run: npm test

Complete GitHub Actions Guide

Core Concepts

Workflows

YAML files in .github/workflows/ that define automation pipelines.

Structure:

  • Name: Workflow identifier
  • Triggers: Events that start the workflow
  • Jobs: One or more jobs to execute
  • Steps: Commands/actions within each job
yaml
name: CI Pipelineon: [push, pull_request]jobs:  build:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4      - run: echo "Building project"

Jobs

Independent execution units that run in parallel by default.

yaml
jobs:  lint:    runs-on: ubuntu-latest    steps:      - run: npm run lint
  test:    runs-on: ubuntu-latest    needs: lint  # Wait for lint to complete    steps:      - run: npm test
  deploy:    runs-on: ubuntu-latest    needs: [lint, test]  # Wait for both    steps:      - run: ./deploy.sh

Steps

Sequential commands or actions within a job.

yaml
steps:  # Use pre-built action  - uses: actions/checkout@v4
  # Run shell command  - run: npm install
  # Named step with environment  - name: Run tests    run: npm test    env:      NODE_ENV: test

Actions

Reusable units of code (from marketplace or custom).

yaml
# Official action- uses: actions/checkout@v4
# Third-party action- uses: docker/build-push-action@v5  with:    context: .    push: true    tags: user/app:latest
# Local action- uses: ./.github/actions/custom-action

Workflow Syntax

Triggers (on)

Push Events
yaml
on:  push:    branches:      - main      - 'releases/**'  # Wildcard pattern    tags:      - 'v*'  # All version tags    paths:      - 'src/**'      - '!src/docs/**'  # Exclude docs
Pull Request Events
yaml
on:  pull_request:    types: [opened, synchronize, reopened]    branches: [main, develop]    paths-ignore:      - '**.md'      - 'docs/**'
Schedule (Cron)
yaml
on:  schedule:    # Every day at 2:30 AM UTC    - cron: '30 2 * * *'    # Every Monday at 9:00 AM UTC    - cron: '0 9 * * 1'
Manual Trigger
yaml
on:  workflow_dispatch:    inputs:      environment:        description: 'Deployment environment'        required: true        type: choice        options:          - staging          - production      version:        description: 'Version to deploy'        required: false        default: 'latest'
Multiple Triggers
yaml
on:  push:    branches: [main]  pull_request:    branches: [main]  schedule:    - cron: '0 0 * * 0'  # Weekly  workflow_dispatch:  # Manual

Environment Variables

Workflow-level
yaml
env:  NODE_ENV: production  API_URL: https://api.example.com
jobs:  build:    runs-on: ubuntu-latest    steps:      - run: echo $NODE_ENV
Job-level
yaml
jobs:  test:    runs-on: ubuntu-latest    env:      TEST_DATABASE: test_db    steps:      - run: pytest
Step-level
yaml
steps:  - name: Build    run: npm run build    env:      BUILD_TARGET: production

Secrets

Store sensitive data in repository settings.

yaml
steps:  - name: Deploy    run: ./deploy.sh    env:      API_KEY: ${{ secrets.API_KEY }}      DATABASE_URL: ${{ secrets.DATABASE_URL }}

Best Practices:

  • Never commit secrets to code
  • Use GitHub encrypted secrets
  • Limit secret access to specific environments
  • Rotate secrets regularly

Contexts

github Context

Repository and workflow information.

yaml
steps:  - name: Print context    run: |      echo "Repository: ${{ github.repository }}"      echo "Ref: ${{ github.ref }}"      echo "SHA: ${{ github.sha }}"      echo "Actor: ${{ github.actor }}"      echo "Event: ${{ github.event_name }}"      echo "Branch: ${{ github.ref_name }}"

env Context

Access environment variables.

yaml
env:  BUILD_ID: 12345
steps:  - run: echo "Build ${{ env.BUILD_ID }}"

secrets Context

Access repository secrets.

yaml
- run: echo "Token exists"  env:    TOKEN: ${{ secrets.GITHUB_TOKEN }}

matrix Context

Access matrix values.

yaml
strategy:  matrix:    node: [18, 20, 22]steps:  - run: echo "Testing Node ${{ matrix.node }}"

needs Context

Access outputs from dependent jobs.

yaml
jobs:  build:    outputs:      version: ${{ steps.get_version.outputs.version }}    steps:      - id: get_version        run: echo "version=1.2.3" >> $GITHUB_OUTPUT
  deploy:    needs: build    steps:      - run: echo "Deploying ${{ needs.build.outputs.version }}"

Runners

GitHub-hosted Runners

yaml
jobs:  ubuntu:    runs-on: ubuntu-latest  # ubuntu-22.04
  macos:    runs-on: macos-latest  # macOS 14
  windows:    runs-on: windows-latest  # Windows 2022
  specific:    runs-on: ubuntu-20.04  # Specific version

Available Runners:

  • ubuntu-latest, ubuntu-22.04, ubuntu-20.04
  • macos-latest, macos-14, macos-13
  • windows-latest, windows-2022, windows-2019

Self-hosted Runners

yaml
runs-on: self-hosted
# With labelsruns-on: [self-hosted, linux, x64, gpu]

Setup:

  1. Go to Settings → Actions → Runners
  2. Click "New self-hosted runner"
  3. Follow platform-specific instructions
  4. Add custom labels for targeting

Matrix Strategies

Basic Matrix

Test across multiple versions.

yaml
strategy:  matrix:    node: [18, 20, 22]    os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}steps:  - uses: actions/setup-node@v4    with:      node-version: ${{ matrix.node }}

Include/Exclude

yaml
strategy:  matrix:    node: [18, 20, 22]    os: [ubuntu-latest, windows-latest]    include:      # Add specific combination      - node: 22        os: macos-latest        experimental: true    exclude:      # Remove specific combination      - node: 18        os: windows-latest

Fail-fast

yaml
strategy:  fail-fast: false  # Continue other jobs if one fails  matrix:    node: [18, 20, 22]

Max Parallel

yaml
strategy:  max-parallel: 2  # Run only 2 jobs concurrently  matrix:    node: [18, 20, 22]

Common Actions

Checkout Code

yaml
- uses: actions/checkout@v4  with:    fetch-depth: 0  # Full history for changelog    submodules: true  # Include submodules

Setup Node.js

yaml
- uses: actions/setup-node@v4  with:    node-version: '20'    cache: 'npm'  # or 'yarn', 'pnpm'    registry-url: 'https://registry.npmjs.org'

Setup Python

yaml
- uses: actions/setup-python@v5  with:    python-version: '3.11'    cache: 'pip'

Setup Java

yaml
- uses: actions/setup-java@v4  with:    distribution: 'temurin'    java-version: '17'    cache: 'maven'

Setup Go

yaml
- uses: actions/setup-go@v5  with:    go-version: '1.21'    cache: true

Cache Dependencies

yaml
- uses: actions/cache@v4  with:    path: |      ~/.npm      node_modules    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}    restore-keys: |      ${{ runner.os }}-node-

Upload Artifacts

yaml
- uses: actions/upload-artifact@v4  with:    name: build-output    path: dist/    retention-days: 7

Download Artifacts

yaml
- uses: actions/download-artifact@v4  with:    name: build-output    path: dist/

Conditional Execution

if Conditions

yaml
steps:  - name: Deploy to production    if: github.ref == 'refs/heads/main'    run: ./deploy.sh
  - name: Deploy to staging    if: github.ref == 'refs/heads/develop'    run: ./deploy-staging.sh
  - name: Only on PR    if: github.event_name == 'pull_request'    run: echo "This is a PR"
  - name: On success    if: success()    run: echo "Previous steps succeeded"
  - name: On failure    if: failure()    run: echo "A step failed"
  - name: Always run    if: always()    run: echo "Cleanup tasks"

Job Conditions

yaml
jobs:  deploy:    if: github.ref == 'refs/heads/main'    runs-on: ubuntu-latest    steps:      - run: ./deploy.sh

Framework-Specific Workflows

Node.js/TypeScript

yaml
name: Node.js CI
on: [push, pull_request]
jobs:  test:    runs-on: ubuntu-latest    strategy:      matrix:        node-version: [18, 20, 22]    steps:      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4        with:          node-version: ${{ matrix.node-version }}          cache: 'npm'
      - run: npm ci
      - run: npm run lint
      - run: npm run type-check
      - run: npm test        env:          CI: true
      - run: npm run build
      - uses: codecov/codecov-action@v4        if: matrix.node-version == 20        with:          token: ${{ secrets.CODECOV_TOKEN }}

Python

yaml
name: Python CI
on: [push, pull_request]
jobs:  test:    runs-on: ubuntu-latest    strategy:      matrix:        python-version: ['3.10', '3.11', '3.12']    steps:      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5        with:          python-version: ${{ matrix.python-version }}          cache: 'pip'
      - run: pip install -r requirements.txt
      - run: pip install pytest pytest-cov mypy ruff
      - run: ruff check .
      - run: mypy .
      - run: pytest --cov=. --cov-report=xml
      - uses: codecov/codecov-action@v4        if: matrix.python-version == '3.11'

Docker

yaml
name: Docker Build
on:  push:    branches: [main]    tags: ['v*']
jobs:  build:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3        with:          username: ${{ secrets.DOCKERHUB_USERNAME }}          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - uses: docker/metadata-action@v5        id: meta        with:          images: user/app          tags: |            type=ref,event=branch            type=semver,pattern={{version}}            type=semver,pattern={{major}}.{{minor}}
      - uses: docker/build-push-action@v5        with:          context: .          push: true          tags: ${{ steps.meta.outputs.tags }}          labels: ${{ steps.meta.outputs.labels }}          cache-from: type=gha          cache-to: type=gha,mode=max

Next.js with Vercel

yaml
name: Next.js CI
on:  push:    branches: [main]  pull_request:    branches: [main]
jobs:  build:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4        with:          node-version: '20'          cache: 'npm'
      - run: npm ci
      - run: npm run lint
      - run: npm run build
      - run: npm test
  deploy-preview:    if: github.event_name == 'pull_request'    runs-on: ubuntu-latest    needs: build    steps:      - uses: actions/checkout@v4
      - uses: amondnet/vercel-action@v25        with:          vercel-token: ${{ secrets.VERCEL_TOKEN }}          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
  deploy-production:    if: github.ref == 'refs/heads/main'    runs-on: ubuntu-latest    needs: build    steps:      - uses: actions/checkout@v4
      - uses: amondnet/vercel-action@v25        with:          vercel-token: ${{ secrets.VERCEL_TOKEN }}          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}          vercel-args: '--prod'

Deployment Patterns

Vercel Deployment

yaml
name: Deploy to Vercel
on:  push:    branches: [main]
jobs:  deploy:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4
      - uses: amondnet/vercel-action@v25        with:          vercel-token: ${{ secrets.VERCEL_TOKEN }}          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}          vercel-args: '--prod'

Netlify Deployment

yaml
name: Deploy to Netlify
on:  push:    branches: [main]
jobs:  deploy:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4        with:          node-version: '20'
      - run: npm ci      - run: npm run build
      - uses: netlify/actions/cli@master        with:          args: deploy --prod --dir=dist        env:          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}

AWS S3 + CloudFront

yaml
name: Deploy to AWS
on:  push:    branches: [main]
jobs:  deploy:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4        with:          node-version: '20'
      - run: npm ci      - run: npm run build
      - uses: aws-actions/configure-aws-credentials@v4        with:          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}          aws-region: us-east-1
      - run: aws s3 sync dist/ s3://${{ secrets.S3_BUCKET }} --delete
      - run: |          aws cloudfront create-invalidation \            --distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} \            --paths "/*"

Docker Registry Push

yaml
name: Publish Docker Image
on:  release:    types: [published]
jobs:  push:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4
      - uses: docker/login-action@v3        with:          registry: ghcr.io          username: ${{ github.actor }}          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v5        with:          context: .          push: true          tags: |            ghcr.io/${{ github.repository }}:latest            ghcr.io/${{ github.repository }}:${{ github.event.release.tag_name }}

Testing Workflows

Unit Tests with Coverage

yaml
name: Test Coverage
on: [push, pull_request]
jobs:  test:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4        with:          node-version: '20'          cache: 'npm'
      - run: npm ci
      - run: npm test -- --coverage
      - uses: codecov/codecov-action@v4        with:          token: ${{ secrets.CODECOV_TOKEN }}          files: ./coverage/coverage-final.json          fail_ci_if_error: true

Integration Tests

yaml
name: Integration Tests
on: [push, pull_request]
jobs:  integration:    runs-on: ubuntu-latest    services:      postgres:        image: postgres:15        env:          POSTGRES_PASSWORD: postgres        options: >-          --health-cmd pg_isready          --health-interval 10s          --health-timeout 5s          --health-retries 5        ports:          - 5432:5432
      redis:        image: redis:7        options: >-          --health-cmd "redis-cli ping"          --health-interval 10s          --health-timeout 5s          --health-retries 5        ports:          - 6379:6379
    steps:      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4        with:          node-version: '20'
      - run: npm ci
      - run: npm run test:integration        env:          DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test          REDIS_URL: redis://localhost:6379

E2E Tests with Playwright

yaml
name: E2E Tests
on: [push, pull_request]
jobs:  e2e:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4        with:          node-version: '20'          cache: 'npm'
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npm run build
      - run: npm run test:e2e
      - uses: actions/upload-artifact@v4        if: always()        with:          name: playwright-report          path: playwright-report/          retention-days: 30

Release Automation

Semantic Release

yaml
name: Release
on:  push:    branches: [main]
jobs:  release:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4        with:          fetch-depth: 0  # Full history for changelog
      - uses: actions/setup-node@v4        with:          node-version: '20'
      - run: npm ci
      - run: npx semantic-release        env:          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Create Release with Changelog

yaml
name: Create Release
on:  push:    tags:      - 'v*'
jobs:  release:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4        with:          fetch-depth: 0
      - name: Generate changelog        id: changelog        run: |          # Generate changelog from commits          CHANGELOG=$(git log $(git describe --tags --abbrev=0 HEAD^)..HEAD --pretty=format:"- %s (%h)" --no-merges)          echo "changelog<<EOF" >> $GITHUB_OUTPUT          echo "$CHANGELOG" >> $GITHUB_OUTPUT          echo "EOF" >> $GITHUB_OUTPUT
      - uses: actions/create-release@v1        env:          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}        with:          tag_name: ${{ github.ref_name }}          release_name: Release ${{ github.ref_name }}          body: |            ## Changes            ${{ steps.changelog.outputs.changelog }}          draft: false          prerelease: false

Publish npm Package

yaml
name: Publish to npm
on:  release:    types: [published]
jobs:  publish:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4        with:          node-version: '20'          registry-url: 'https://registry.npmjs.org'
      - run: npm ci
      - run: npm test
      - run: npm publish        env:          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

Security Scanning

CodeQL Analysis

yaml
name: CodeQL
on:  push:    branches: [main]  pull_request:    branches: [main]  schedule:    - cron: '0 0 * * 1'  # Weekly
jobs:  analyze:    runs-on: ubuntu-latest    permissions:      actions: read      contents: read      security-events: write
    strategy:      fail-fast: false      matrix:        language: ['javascript', 'python']
    steps:      - uses: actions/checkout@v4
      - uses: github/codeql-action/init@v3        with:          languages: ${{ matrix.language }}
      - uses: github/codeql-action/autobuild@v3
      - uses: github/codeql-action/analyze@v3

Dependency Scanning

yaml
name: Dependency Check
on:  push:    branches: [main]  schedule:    - cron: '0 0 * * 1'
jobs:  scan:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4        with:          node-version: '20'
      - run: npm audit --audit-level=moderate
      - run: npx snyk test        env:          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}        continue-on-error: true

Trivy Container Scan

yaml
name: Container Security Scan
on:  push:    branches: [main]
jobs:  scan:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4
      - run: docker build -t myapp:${{ github.sha }} .
      - uses: aquasecurity/trivy-action@master        with:          image-ref: 'myapp:${{ github.sha }}'          format: 'sarif'          output: 'trivy-results.sarif'
      - uses: github/codeql-action/upload-sarif@v3        with:          sarif_file: 'trivy-results.sarif'

Composite Actions

Create reusable actions in .github/actions/.

Simple Composite Action

.github/actions/setup-project/action.yml:

yaml
name: 'Setup Project'description: 'Install dependencies and cache'
inputs:  node-version:    description: 'Node.js version'    required: false    default: '20'
runs:  using: 'composite'  steps:    - uses: actions/setup-node@v4      with:        node-version: ${{ inputs.node-version }}        cache: 'npm'
    - run: npm ci      shell: bash

Usage:

yaml
steps:  - uses: actions/checkout@v4  - uses: ./.github/actions/setup-project    with:      node-version: '20'

Reusable Workflows

.github/workflows/reusable-deploy.yml:

yaml
name: Reusable Deploy
on:  workflow_call:    inputs:      environment:        required: true        type: string    secrets:      deploy-token:        required: true
jobs:  deploy:    runs-on: ubuntu-latest    environment: ${{ inputs.environment }}    steps:      - uses: actions/checkout@v4
      - run: ./deploy.sh        env:          DEPLOY_TOKEN: ${{ secrets.deploy-token }}          ENVIRONMENT: ${{ inputs.environment }}

Usage:

yaml
name: Deploy Production
on:  push:    branches: [main]
jobs:  deploy:    uses: ./.github/workflows/reusable-deploy.yml    with:      environment: production    secrets:      deploy-token: ${{ secrets.PRODUCTION_TOKEN }}

Performance Optimization

Dependency Caching

yaml
- uses: actions/cache@v4  with:    path: ~/.npm    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}    restore-keys: |      ${{ runner.os }}-node-

Docker Layer Caching

yaml
- uses: docker/build-push-action@v5  with:    context: .    cache-from: type=gha    cache-to: type=gha,mode=max

Parallelization

yaml
jobs:  lint:    runs-on: ubuntu-latest    steps:      - run: npm run lint
  test-unit:    runs-on: ubuntu-latest    steps:      - run: npm run test:unit
  test-integration:    runs-on: ubuntu-latest    steps:      - run: npm run test:integration
  # All run in parallel

Conditional Job Execution

yaml
jobs:  deploy:    # Skip deploy on draft PRs    if: github.event.pull_request.draft == false    runs-on: ubuntu-latest    steps:      - run: ./deploy.sh

Debugging Workflows

Enable Debug Logging

Set repository secrets:

  • ACTIONS_RUNNER_DEBUG: true
  • ACTIONS_STEP_DEBUG: true

Debug Step

yaml
- name: Debug Info  run: |    echo "Event: ${{ github.event_name }}"    echo "Ref: ${{ github.ref }}"    echo "SHA: ${{ github.sha }}"    echo "Actor: ${{ github.actor }}"    env

Interactive Debugging with tmate

yaml
- name: Setup tmate session  if: failure()  uses: mxschmitt/action-tmate@v3  timeout-minutes: 15

Best Practices

Security

  • Use secrets for sensitive data
  • Pin action versions to SHA: uses: actions/checkout@8e5e7e5a...
  • Minimize token permissions
  • Use environment protection rules
  • Enable branch protection with required checks

Performance

  • Cache dependencies aggressively
  • Use matrix strategies for parallel testing
  • Minimize checkout depth when possible
  • Use artifacts for job-to-job data transfer
  • Optimize Docker builds with multi-stage builds

Maintainability

  • Use reusable workflows for common patterns
  • Create composite actions for repeated steps
  • Document workflow purpose and triggers
  • Use meaningful job and step names
  • Keep workflows focused (single responsibility)

Reliability

  • Set appropriate timeouts
  • Use continue-on-error strategically
  • Implement retry logic for flaky tests
  • Monitor workflow run times
  • Clean up old artifacts and caches

Common Patterns

PR Comment on Failure

yaml
- name: Comment on PR  if: failure() && github.event_name == 'pull_request'  uses: actions/github-script@v7  with:    script: |      github.rest.issues.createComment({        issue_number: context.issue.number,        owner: context.repo.owner,        repo: context.repo.repo,        body: '❌ Tests failed. Please check the workflow logs.'      })

Auto-merge Dependabot PRs

yaml
name: Auto-merge Dependabot
on:  pull_request:    types: [opened, synchronize]
jobs:  auto-merge:    if: github.actor == 'dependabot[bot]'    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4
      - run: npm ci      - run: npm test
      - uses: gh enable-auto-merge --merge        if: success()        env:          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Notify on Deploy

yaml
- name: Slack Notification  if: always()  uses: 8398a7/action-slack@v3  with:    status: ${{ job.status }}    text: 'Deploy to ${{ inputs.environment }}: ${{ job.status }}'    webhook_url: ${{ secrets.SLACK_WEBHOOK }}

Troubleshooting

Common Issues

Workflow not triggering:

  • Check branch filters match actual branch names
  • Verify workflow file is in .github/workflows/
  • Ensure YAML syntax is valid

Job skipped:

  • Check if conditions
  • Verify needs dependencies succeeded
  • Check branch protection rules

Timeout:

  • Default timeout is 360 minutes
  • Set explicit timeout: timeout-minutes: 30
  • Optimize long-running steps

Permission denied:

  • Update workflow permissions:
    yaml
    permissions:  contents: write  pull-requests: write

Secrets not available:

  • Verify secret names match exactly (case-sensitive)
  • Check secret scope (repo, organization, environment)
  • Ensure workflow has access to environment secrets

Local Workflow Patterns (Your Repos)

Python + uv CI (mcp-vector-search)

  • Install uv: astral-sh/setup-uv@v3 and uv python install 3.11.
  • Use uv sync --dev and run uv run ruff, uv run mypy, uv run pytest.
  • Use OS + Python version matrix and upload coverage to Codecov on linux.

Node + pnpm CI (ai-code-review)

  • Use pnpm/action-setup@v4 and actions/setup-node@v4 with pnpm cache.
  • Install with pnpm install --frozen-lockfile, then pnpm run lint, pnpm run build:types, pnpm test.

Release on Tags

  • Trigger on push tags v*.
  • Build, create GitHub Release notes, and publish to npm or PyPI.
  • Use pypa/gh-action-pypi-publish@release/v1 or NODE_AUTH_TOKEN for npm publish.

Homebrew Update Pipeline

  • Trigger on workflow_run after CI success.
  • Run scripts/update_homebrew_formula.py with HOMEBREW_TAP_TOKEN.
  • On failure, open an issue with manual update steps.

Resources

来源与署名

来源:bobmatnyc/claude-mpm-skills位于toolchains/universal/infrastructure/github-actions提交718070a

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架