CI/CD Pipeline技能使用说明
2026-03-28
新闻来源:网淘吧
围观:18
电脑广告
手机广告
CI/CD 流水线(GitHub Actions)
使用 GitHub Actions 设置和管理 CI/CD 流水线。涵盖工作流创建、测试、部署、发布自动化和调试。
使用场景
- 在推送代码或发起合并请求时设置自动化测试
- 创建部署流水线(预发布环境、生产环境)
- 通过变更日志和标签自动化发布流程
- 调试失败的 CI 工作流
- 设置矩阵构建以进行跨平台测试
- 在 CI 中管理密钥和环境变量
- 通过缓存和并行优化 CI
快速入门:为项目添加 CI
Node.js 项目
# .github/workflows/ci.yml
name: CI
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
cache: npm
- run: npm ci
- run: npm test
- run: npm run lint
Python 项目
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- run: pip install -r requirements.txt
- run: pytest
- run: ruff check .
Go 项目
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.22"
- run: go test ./...
- run: go vet ./...
Rust 项目
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo test
- run: cargo clippy -- -D warnings
常见模式
矩阵构建(跨版本/操作系统测试)
jobs:
test:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [18, 20, 22]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test
条件性任务
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
deploy:
needs: test
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./deploy.sh
依赖项缓存
# Node.js (automatic with setup-node)
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm # or yarn, pnpm
# Generic caching
- uses: actions/cache@v4
with:
path: |
~/.cache/pip
~/.cargo/registry
node_modules
key: ${{ runner.os }}-deps-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-deps-
制品(保存构建输出)
- uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
retention-days: 7
# Download in another job
- uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
按计划运行(cron)
on:
schedule:
- cron: "0 6 * * 1" # Every Monday at 6 AM UTC
workflow_dispatch: # Also allow manual trigger
部署工作流
在标签发布时部署到生产环境
name: Release
on:
push:
tags:
- "v*"
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run build
- run: npm test
# Create GitHub release
- uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: |
dist/*.js
dist/*.css
部署到多个环境
name: Deploy
on:
push:
branches: [main, staging]
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- run: |
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
./deploy.sh production
else
./deploy.sh staging
fi
env:
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
Docker 构建与推送
name: Docker
on:
push:
branches: [main]
tags: ["v*"]
jobs:
build:
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
push: true
tags: |
ghcr.io/${{ github.repository }}:latest
ghcr.io/${{ github.repository }}:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
发布时进行 npm 发布
name: Publish
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
permissions:
id-token: write
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 --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
密钥管理
通过 CLI 设置密钥
# Set a repository secret
gh secret set DEPLOY_TOKEN --body "my-secret-value"
# Set from a file
gh secret set SSH_KEY < ~/.ssh/deploy_key
# Set for a specific environment
gh secret set DB_PASSWORD --env production --body "p@ssw0rd"
# List secrets
gh secret list
# Delete a secret
gh secret delete OLD_SECRET
在工作流中使用密钥
env:
# Available to all steps in this job
DATABASE_URL: ${{ secrets.DATABASE_URL }}
steps:
- run: echo "Deploying..."
env:
# Available to this step only
API_KEY: ${{ secrets.API_KEY }}
环境保护规则
通过 GitHub UI 或 API 设置:
- 部署前需要审核者
- 等待计时器
- 分支限制
- 自定义部署分支策略
# View environments
gh api repos/{owner}/{repo}/environments | jq '.environments[].name'
工作流调试
重新运行失败的任务
# List recent workflow runs
gh run list --limit 10
# View a specific run
gh run view <run-id>
# View failed job logs
gh run view <run-id> --log-failed
# Re-run failed jobs only
gh run rerun <run-id> --failed
# Re-run entire workflow
gh run rerun <run-id>
使用 SSH 调试(使用 tmate)
# Add this step before the failing step
- uses: mxschmitt/action-tmate@v3
if: failure()
with:
limit-access-to-actor: true
常见故障与修复
脚本出现“权限被拒绝”
- run: chmod +x ./scripts/deploy.sh && ./scripts/deploy.sh
“未找到 Node 模块”
# Make sure npm ci runs before npm test
- run: npm ci # Install exact lockfile versions
- run: npm test # Now node_modules exists
“集成无法访问资源”
# Add permissions block
permissions:
contents: write
packages: write
pull-requests: write
缓存未恢复
# Check cache key matches - use hashFiles for lockfile
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
# NOT: key: ${{ runner.os }}-node-${{ hashFiles('package.json') }}
工作流未触发
- 检查:工作流文件是否在默认分支上?
- 检查:触发事件是否匹配?(
推送对比拉取请求) - 检查:分支过滤器是否正确?
# Manually trigger a workflow
gh workflow run ci.yml --ref main
工作流验证
推送前本地验证
# Check YAML syntax
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci.yml'))" && echo "Valid"
# Use actionlint (if installed)
actionlint .github/workflows/ci.yml
# Or via Docker
docker run --rm -v "$(pwd):/repo" -w /repo rhysd/actionlint:latest
以图形视图查看工作流
# List all workflows
gh workflow list
# View workflow definition
gh workflow view ci.yml
# Watch a running workflow
gh run watch
高级模式
可重用工作流
# .github/workflows/reusable-test.yml
name: Reusable Test
on:
workflow_call:
inputs:
node-version:
required: false
type: string
default: "20"
secrets:
npm-token:
required: false
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- run: npm ci
- run: npm test
# .github/workflows/ci.yml - caller
name: CI
on: [push, pull_request]
jobs:
test:
uses: ./.github/workflows/reusable-test.yml
with:
node-version: "20"
并发控制(防止重复运行)
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true # Cancel previous runs for same branch
路径过滤器(仅针对相关变更运行)
on:
push:
paths:
- "src/**"
- "package.json"
- "package-lock.json"
- ".github/workflows/ci.yml"
paths-ignore:
- "docs/**"
- "*.md"
单体仓库:仅测试变更的包
jobs:
changes:
runs-on: ubuntu-latest
outputs:
api: ${{ steps.filter.outputs.api }}
web: ${{ steps.filter.outputs.web }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
api:
- 'packages/api/**'
web:
- 'packages/web/**'
test-api:
needs: changes
if: needs.changes.outputs.api == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cd packages/api && npm ci && npm test
test-web:
needs: changes
if: needs.changes.outputs.web == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cd packages/web && npm ci && npm test
提示
- 在每个工作流中使用
workflow_dispatch以便在调试期间手动触发 - 为保障供应链安全,将操作版本固定为SHA哈希值:
用途:actions/checkout@b4ffde... - 使用
continue-on-error: true适用于非关键步骤(例如代码检查) - 设置
timeout-minutes在作业上,以防止构建过程失控(默认值为360分钟) - 使用作业输出在作业之间传递数据:
outputs: result: ${{ steps.step-id.outputs.value }} - 对于自托管运行器:
runs-on: self-hosted配合标签以定位特定机器
文章底部电脑广告
手机广告位-内容正文底部
上一篇:amap技能使用说明
下一篇:Stock Price Query技能使用说明


微信扫一扫,打赏作者吧~