github-actions
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGitHub Actions CI/CD
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.
GitHub Actions是GitHub原生的CI/CD平台,用于自动化软件工作流。通过YAML文件定义工作流,借助事件驱动的自动化机制,直接从代码仓库中完成代码的构建、测试与部署。
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
- 为每个Pull Request自动执行测试
- 代码合并到main分支时自动构建并部署应用
- 定期调度任务(夜间构建、备份)
- 将包发布到注册中心(npm、PyPI、Docker Hub)
- 运行安全扫描与代码质量检查
- 自动化发布流程与变更日志生成
Quick Start
快速开始
Basic Test Workflow
基础测试工作流
Create :
.github/workflows/test.ymlyaml
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创建:
.github/workflows/test.ymlyaml
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 testComplete GitHub Actions Guide
GitHub Actions 完整指南
Core Concepts
核心概念
Workflows
Workflows
YAML files in that define automation pipelines.
.github/workflows/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 Pipeline
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: echo "Building project"位于目录下的YAML文件,用于定义自动化流水线。
.github/workflows/结构:
- Name: 工作流标识符
- Triggers: 触发工作流的事件
- Jobs: 要执行的一个或多个作业
- Steps: 每个作业中的命令/动作
yaml
name: CI Pipeline
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: echo "Building project"Jobs
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独立的执行单元,默认并行运行。
yaml
jobs:
lint:
runs-on: ubuntu-latest
steps:
- run: npm run lint
test:
runs-on: ubuntu-latest
needs: lint # 等待lint作业完成
steps:
- run: npm test
deploy:
runs-on: ubuntu-latest
needs: [lint, test] # 等待两个作业完成
steps:
- run: ./deploy.shSteps
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作业中的顺序命令或动作。
yaml
steps:
# 使用预构建的Action
- uses: actions/checkout@v4
# 运行Shell命令
- run: npm install
# 带环境变量的命名步骤
- name: Run tests
run: npm test
env:
NODE_ENV: testActions
Actions
Reusable units of code (from marketplace or custom).
yaml
undefined可复用的代码单元(来自市场或自定义)。
yaml
undefinedOfficial action
官方Action
- uses: actions/checkout@v4
- uses: actions/checkout@v4
Third-party action
第三方Action
- uses: docker/build-push-action@v5 with: context: . push: true tags: user/app:latest
- uses: docker/build-push-action@v5 with: context: . push: true tags: user/app:latest
Local action
本地Action
- uses: ./.github/actions/custom-action
undefined- uses: ./.github/actions/custom-action
undefinedWorkflow Syntax
工作流语法
Triggers (on)
触发器(on)
Push Events
推送事件
yaml
on:
push:
branches:
- main
- 'releases/**' # Wildcard pattern
tags:
- 'v*' # All version tags
paths:
- 'src/**'
- '!src/docs/**' # Exclude docsyaml
on:
push:
branches:
- main
- 'releases/**' # 通配符模式
tags:
- 'v*' # 所有版本标签
paths:
- 'src/**'
- '!src/docs/**' # 排除文档目录Pull Request Events
Pull Request事件
yaml
on:
pull_request:
types: [opened, synchronize, reopened]
branches: [main, develop]
paths-ignore:
- '**.md'
- 'docs/**'yaml
on:
pull_request:
types: [opened, synchronize, reopened]
branches: [main, develop]
paths-ignore:
- '**.md'
- 'docs/**'Schedule (Cron)
定时调度(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'yaml
on:
schedule:
# 每天UTC时间2:30执行
- cron: '30 2 * * *'
# 每周一UTC时间9:00执行
- 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'yaml
on:
workflow_dispatch:
inputs:
environment:
description: '部署环境'
required: true
type: choice
options:
- staging
- production
version:
description: '要部署的版本'
required: false
default: 'latest'Multiple Triggers
多触发器
yaml
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * 0' # Weekly
workflow_dispatch: # Manualyaml
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * 0' # 每周执行
workflow_dispatch: # 手动触发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_ENVyaml
env:
NODE_ENV: production
API_URL: https://api.example.com
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo $NODE_ENVJob-level
作业级别
yaml
jobs:
test:
runs-on: ubuntu-latest
env:
TEST_DATABASE: test_db
steps:
- run: pytestyaml
jobs:
test:
runs-on: ubuntu-latest
env:
TEST_DATABASE: test_db
steps:
- run: pytestStep-level
步骤级别
yaml
steps:
- name: Build
run: npm run build
env:
BUILD_TARGET: productionyaml
steps:
- name: Build
run: npm run build
env:
BUILD_TARGET: productionSecrets
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
在仓库设置中存储敏感数据。
yaml
steps:
- name: Deploy
run: ./deploy.sh
env:
API_KEY: ${{ secrets.API_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}最佳实践:
- 切勿将Secrets提交到代码中
- 使用GitHub加密Secrets
- 限制Secrets对特定环境的访问
- 定期轮换Secrets
Contexts
上下文
github Context
github上下文
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 }}"包含仓库与工作流的相关信息。
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
env上下文
Access environment variables.
yaml
env:
BUILD_ID: 12345
steps:
- run: echo "Build ${{ env.BUILD_ID }}"用于访问环境变量。
yaml
env:
BUILD_ID: 12345
steps:
- run: echo "Build ${{ env.BUILD_ID }}"secrets Context
secrets上下文
Access repository secrets.
yaml
- run: echo "Token exists"
env:
TOKEN: ${{ secrets.GITHUB_TOKEN }}用于访问仓库Secrets。
yaml
- run: echo "Token exists"
env:
TOKEN: ${{ secrets.GITHUB_TOKEN }}matrix Context
matrix上下文
Access matrix values.
yaml
strategy:
matrix:
node: [18, 20, 22]
steps:
- run: echo "Testing Node ${{ matrix.node }}"用于访问矩阵值。
yaml
strategy:
matrix:
node: [18, 20, 22]
steps:
- run: echo "Testing Node ${{ matrix.node }}"needs Context
needs上下文
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 }}"用于访问依赖作业的输出。
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
Runners
GitHub-hosted Runners
GitHub托管的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 versionAvailable Runners:
- ,
ubuntu-latest,ubuntu-22.04ubuntu-20.04 - ,
macos-latest,macos-14macos-13 - ,
windows-latest,windows-2022windows-2019
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 # 指定版本可用的Runners:
- ,
ubuntu-latest,ubuntu-22.04ubuntu-20.04 - ,
macos-latest,macos-14macos-13 - ,
windows-latest,windows-2022windows-2019
Self-hosted Runners
自托管Runners
yaml
runs-on: self-hostedyaml
runs-on: self-hostedWith labels
带标签
runs-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 targetingruns-on: [self-hosted, linux, x64, gpu]
**设置步骤**:
1. 进入仓库的Settings → Actions → Runners
2. 点击"New self-hosted runner"
3. 按照平台专属的说明操作
4. 添加自定义标签用于定向触发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 }}在多个版本间进行测试。
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-latestyaml
strategy:
matrix:
node: [18, 20, 22]
os: [ubuntu-latest, windows-latest]
include:
# 添加特定组合
- node: 22
os: macos-latest
experimental: true
exclude:
# 移除特定组合
- node: 18
os: windows-latestFail-fast
快速失败
yaml
strategy:
fail-fast: false # Continue other jobs if one fails
matrix:
node: [18, 20, 22]yaml
strategy:
fail-fast: false # 即使一个作业失败,继续执行其他作业
matrix:
node: [18, 20, 22]Max Parallel
最大并行数
yaml
strategy:
max-parallel: 2 # Run only 2 jobs concurrently
matrix:
node: [18, 20, 22]yaml
strategy:
max-parallel: 2 # 同时仅运行2个作业
matrix:
node: [18, 20, 22]Common Actions
常用Actions
Checkout Code
检出代码
yaml
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for changelog
submodules: true # Include submodulesyaml
- uses: actions/checkout@v4
with:
fetch-depth: 0 # 获取完整历史用于生成变更日志
submodules: true # 包含子模块Setup Node.js
配置Node.js
yaml
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # or 'yarn', 'pnpm'
registry-url: 'https://registry.npmjs.org'yaml
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # 或'yarn'、'pnpm'
registry-url: 'https://registry.npmjs.org'Setup Python
配置Python
yaml
- uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'yaml
- uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'Setup Java
配置Java
yaml
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
cache: 'maven'yaml
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
cache: 'maven'Setup Go
配置Go
yaml
- uses: actions/setup-go@v5
with:
go-version: '1.21'
cache: trueyaml
- uses: actions/setup-go@v5
with:
go-version: '1.21'
cache: trueCache Dependencies
缓存依赖
yaml
- uses: actions/cache@v4
with:
path: |
~/.npm
node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-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: 7yaml
- uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
retention-days: 7Download Artifacts
下载产物
yaml
- uses: actions/download-artifact@v4
with:
name: build-output
path: dist/yaml
- uses: actions/download-artifact@v4
with:
name: build-output
path: dist/Conditional Execution
条件执行
if Conditions
if条件
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"yaml
steps:
- name: 部署到生产环境
if: github.ref == 'refs/heads/main'
run: ./deploy.sh
- name: 部署到预发布环境
if: github.ref == 'refs/heads/develop'
run: ./deploy-staging.sh
- name: 仅在PR时执行
if: github.event_name == 'pull_request'
run: echo "这是一个Pull Request"
- name: 成功时执行
if: success()
run: echo "之前的步骤执行成功"
- name: 失败时执行
if: failure()
run: echo "某个步骤执行失败"
- name: 始终执行
if: always()
run: echo "执行清理任务"Job Conditions
作业条件
yaml
jobs:
deploy:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: ./deploy.shyaml
jobs:
deploy:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: ./deploy.shFramework-Specific Workflows
框架专属工作流
Node.js/TypeScript
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 }}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
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'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
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=maxyaml
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=maxNext.js with Vercel
Next.js + 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'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
Vercel部署
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'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
Netlify部署
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 }}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
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 "/*"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
Docker镜像仓库推送
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 }}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: trueyaml
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: trueIntegration 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:6379yaml
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:6379E2E Tests with Playwright
基于Playwright的E2E测试
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: 30yaml
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: 30Release 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 }}yaml
name: Release
on:
push:
branches: [main]
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # 获取完整历史用于生成变更日志
- 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: falseyaml
name: Create Release
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 生成变更日志
id: changelog
run: |
# 从提交记录生成变更日志
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: |
## 变更内容
${{ steps.changelog.outputs.changelog }}
draft: false
prerelease: falsePublish npm Package
发布npm包
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 }}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
CodeQL分析
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@v3yaml
name: CodeQL
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * 1' # 每周执行
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@v3Dependency 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: trueyaml
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: trueTrivy Container Scan
Trivy容器扫描
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'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
复合Actions
Create reusable actions in .
.github/actions/在目录下创建可复用的Actions。
.github/actions/Simple Composite Action
简单复合Action
.github/actions/setup-project/action.ymlyaml
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: bashUsage:
yaml
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-project
with:
node-version: '20'.github/actions/setup-project/action.ymlyaml
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使用方式:
yaml
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-project
with:
node-version: '20'Reusable Workflows
可复用工作流
.github/workflows/reusable-deploy.ymlyaml
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 }}.github/workflows/reusable-deploy.ymlyaml
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 }}使用方式:
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-yaml
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-Docker Layer Caching
Docker层缓存
yaml
- uses: docker/build-push-action@v5
with:
context: .
cache-from: type=gha
cache-to: type=gha,mode=maxyaml
- uses: docker/build-push-action@v5
with:
context: .
cache-from: type=gha
cache-to: type=gha,mode=maxParallelization
并行化
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 parallelyaml
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
# 所有作业并行运行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.shyaml
jobs:
deploy:
# 草稿PR跳过部署
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- run: ./deploy.shDebugging Workflows
工作流调试
Enable Debug Logging
启用调试日志
Set repository secrets:
- :
ACTIONS_RUNNER_DEBUGtrue - :
ACTIONS_STEP_DEBUGtrue
设置仓库Secrets:
- :
ACTIONS_RUNNER_DEBUGtrue - :
ACTIONS_STEP_DEBUGtrue
Debug Step
调试步骤
yaml
- name: Debug Info
run: |
echo "Event: ${{ github.event_name }}"
echo "Ref: ${{ github.ref }}"
echo "SHA: ${{ github.sha }}"
echo "Actor: ${{ github.actor }}"
envyaml
- name: 调试信息
run: |
echo "事件: ${{ github.event_name }}"
echo "Ref: ${{ github.ref }}"
echo "SHA: ${{ github.sha }}"
echo "执行者: ${{ github.actor }}"
envInteractive Debugging with tmate
使用tmate进行交互式调试
yaml
- name: Setup tmate session
if: failure()
uses: mxschmitt/action-tmate@v3
timeout-minutes: 15yaml
- name: 启动tmate会话
if: failure()
uses: mxschmitt/action-tmate@v3
timeout-minutes: 15Best 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
- 使用Secrets存储敏感数据
- 将Action版本固定到SHA:
uses: actions/checkout@8e5e7e5a... - 最小化令牌权限
- 使用环境保护规则
- 启用分支保护并设置必需检查
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
- 积极缓存依赖
- 使用矩阵策略进行并行测试
- 尽可能最小化检出深度
- 使用产物在作业间传输数据
- 使用多阶段构建优化Docker镜像
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)
- 对通用模式使用可复用工作流
- 为重复步骤创建复合Actions
- 记录工作流的用途与触发器
- 使用有意义的作业和步骤名称
- 保持工作流聚焦(单一职责)
Reliability
可靠性
- Set appropriate timeouts
- Use strategically
continue-on-error - Implement retry logic for flaky tests
- Monitor workflow run times
- Clean up old artifacts and caches
- 设置合理的超时时间
- 策略性使用
continue-on-error - 为不稳定的测试实现重试逻辑
- 监控工作流运行时间
- 清理旧的产物与缓存
Common Patterns
常见模式
PR Comment on Failure
PR失败时添加评论
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.'
})yaml
- name: 在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: '❌ 测试失败,请查看工作流日志。'
})Auto-merge Dependabot PRs
自动合并Dependabot PR
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 }}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 }}yaml
- name: Slack通知
if: always()
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: '部署到${{ 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 conditions
if - Verify dependencies succeeded
needs - 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
工作流未触发:
- 检查分支过滤器与实际分支名称是否匹配
- 验证工作流文件是否位于目录下
.github/workflows/ - 确保YAML语法有效
作业被跳过:
- 检查条件
if - 验证依赖是否执行成功
needs - 检查分支保护规则
超时:
- 默认超时时间为360分钟
- 设置显式超时:
timeout-minutes: 30 - 优化长时间运行的步骤
权限被拒绝:
- 更新工作流权限:
yaml
permissions: contents: write pull-requests: write
Secrets不可用:
- 验证Secret名称是否完全匹配(区分大小写)
- 检查Secret作用域(仓库、组织、环境)
- 确保工作流有权访问环境Secrets
Local Workflow Patterns (Your Repos)
本地工作流模式(你的仓库)
Python + uv CI (mcp-vector-search)
Python + uv CI (mcp-vector-search)
- Install uv: and
astral-sh/setup-uv@v3.uv python install 3.11 - Use and run
uv sync --dev,uv run ruff,uv run mypy.uv run pytest - Use OS + Python version matrix and upload coverage to Codecov on linux.
- 安装uv: 使用和
astral-sh/setup-uv@v3。uv python install 3.11 - 执行,然后运行
uv sync --dev、uv run ruff、uv run mypy。uv run pytest - 使用操作系统+Python版本矩阵,并在Linux上将覆盖率数据上传到Codecov。
Node + pnpm CI (ai-code-review)
Node + pnpm CI (ai-code-review)
- Use and
pnpm/action-setup@v4with pnpm cache.actions/setup-node@v4 - Install with , then
pnpm install --frozen-lockfile,pnpm run lint,pnpm run build:types.pnpm test
- 使用和
pnpm/action-setup@v4并配置pnpm缓存。actions/setup-node@v4 - 执行,然后运行
pnpm install --frozen-lockfile、pnpm run lint、pnpm run build:types。pnpm test
Release on Tags
标签触发发布
- Trigger on tags
push.v* - Build, create GitHub Release notes, and publish to npm or PyPI.
- Use or
pypa/gh-action-pypi-publish@release/v1for npm publish.NODE_AUTH_TOKEN
- 触发条件为标签
push。v* - 构建、创建GitHub发布说明,并发布到npm或PyPI。
- 使用或
pypa/gh-action-pypi-publish@release/v1进行npm发布。NODE_AUTH_TOKEN
Homebrew Update Pipeline
Homebrew更新流水线
- Trigger on after CI success.
workflow_run - Run with
scripts/update_homebrew_formula.py.HOMEBREW_TAP_TOKEN - On failure, open an issue with manual update steps.
- CI成功后通过触发。
workflow_run - 使用运行
HOMEBREW_TAP_TOKEN。scripts/update_homebrew_formula.py - 失败时,创建包含手动更新步骤的Issue。