1675 字
8 分钟
GitHub Actions 完整指南:从入门到实践
什么是 GitHub Actions?
GitHub Actions 是 GitHub 提供的强大 CI/CD 服务,让你可以直接在 GitHub 仓库中创建自动化工作流。无论是代码构建、测试、部署,还是其他任何可以自动化的任务,GitHub Actions 都能帮你轻松实现。
核心概念
- 工作流 (Workflow):一个可配置的自动化过程,由一个或多个作业组成
- 作业 (Job):工作流中的一个执行单元,包含一系列步骤
- 步骤 (Step):作业中的单个任务,可以运行命令或使用 Action
- 事件 (Event):触发工作流运行的特定活动
- 运行器 (Runner):执行工作流的服务器环境
基本语法和配置
文件位置
所有工作流文件都必须放在仓库的 .github/workflows/ 目录下,使用 .yml 或 .yaml 扩展名。
基本结构
name: 工作流名称
# 触发条件on: push: branches: [ main ] pull_request: branches: [ main ]
# 权限设置permissions: contents: read
# 作业定义jobs: job-name: runs-on: ubuntu-latest steps: - name: 步骤名称 uses: actions/checkout@v4 - name: 运行命令 run: echo "Hello World"触发器详解
常用触发事件
on: # 代码推送时触发 push: branches: [ main, develop ] paths: [ 'src/**', 'package.json' ] # 只有这些路径变化时才触发
# 拉取请求时触发 pull_request: branches: [ main ] types: [ opened, synchronize, reopened ]
# 定时触发(使用 cron 语法) schedule: - cron: '0 2 * * 1-5' # 工作日凌晨2点
# 手动触发 workflow_dispatch: inputs: environment: description: '部署环境' required: true default: 'staging' type: choice options: ['staging', 'production'] version: description: '版本号' required: false type: string
# Release 发布时触发 release: types: [ published ]手动触发的高级用法
workflow_dispatch: inputs: deploy_target: description: '部署目标' required: true type: choice options: ['staging', 'production', 'development'] skip_tests: description: '跳过测试' required: false type: boolean default: false custom_message: description: '自定义消息' required: false type: string default: 'Manual deployment'并发控制
防止同一分支上的工作流同时运行,避免资源冲突:
concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true权限管理
为工作流设置最小权限原则:
permissions: contents: read # 读取仓库内容 issues: write # 写入 Issues pull-requests: write # 写入 PR actions: read # 读取 Actions checks: write # 写入检查状态构建矩阵
在多个环境下并行测试:
jobs: test: strategy: matrix: # 基础矩阵 node-version: [18, 20, 22] os: [ubuntu-latest, windows-latest, macos-latest]
# 排除特定组合 exclude: - os: windows-latest node-version: 18
# 包含特定组合 include: - os: ubuntu-latest node-version: 16 experimental: true
runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.experimental == true }}
steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm ci - run: npm test环境变量和 Secrets
环境变量
env: # 工作流级别的环境变量 NODE_ENV: production APP_VERSION: v1.0.0
jobs: build: env: # 作业级别的环境变量 BUILD_TARGET: web
steps: - name: 构建应用 run: npm run build env: # 步骤级别的环境变量 GENERATE_SOURCEMAP: false REACT_APP_API_URL: ${{ secrets.API_URL }}Secrets 使用
在 GitHub 仓库设置中添加 Secrets,然后在工作流中引用:
steps: - name: 部署到云服务 run: | echo "部署到生产环境..." ./deploy.sh env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} DATABASE_URL: ${{ secrets.DATABASE_URL }} API_KEY: ${{ secrets.API_KEY }}实际项目示例
Node.js 项目 CI/CD 完整流程
name: Node.js CI/CD Pipeline
on: push: branches: [ main, develop ] pull_request: branches: [ main ] workflow_dispatch: inputs: deploy_env: description: '部署环境' required: true default: 'staging' type: choice options: ['staging', 'production']
concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true
permissions: contents: read checks: write pull-requests: write
jobs: # 代码质量检查 lint-and-type-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm'
- run: npm ci
- name: 代码格式检查 run: npm run lint
- name: 类型检查 run: npm run type-check
# 单元测试 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
- name: 运行测试 run: npm test -- --coverage
- name: 上传覆盖率报告 uses: codecov/codecov-action@v3 if: matrix.node-version == '20' with: token: ${{ secrets.CODECOV_TOKEN }}
# 构建应用 build: needs: [lint-and-type-check, test] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm'
- run: npm ci
- name: 构建生产版本 run: npm run build env: NODE_ENV: production
- name: 上传构建产物 uses: actions/upload-artifact@v4 with: name: dist path: dist/ retention-days: 30
# 部署到 staging deploy-staging: if: github.ref == 'refs/heads/develop' needs: build runs-on: ubuntu-latest environment: staging steps: - name: 下载构建产物 uses: actions/download-artifact@v4 with: name: dist path: dist/
- name: 部署到 Staging run: | echo "部署到 Staging 环境..." # 这里添加实际的部署脚本 env: DEPLOY_KEY: ${{ secrets.STAGING_DEPLOY_KEY }} SERVER_HOST: ${{ secrets.STAGING_SERVER_HOST }}
# 部署到 production deploy-production: if: github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' needs: build runs-on: ubuntu-latest environment: production steps: - name: 下载构建产物 uses: actions/download-artifact@v4 with: name: dist path: dist/
- name: 部署到 Production run: | echo "部署到生产环境..." echo "部署环境: ${{ github.event.inputs.deploy_env || 'production' }}" # 这里添加实际的部署脚本 env: DEPLOY_KEY: ${{ secrets.PROD_DEPLOY_KEY }} SERVER_HOST: ${{ secrets.PROD_SERVER_HOST }}常用 Actions
官方 Actions
steps: # 检出代码 - uses: actions/checkout@v4 with: fetch-depth: 0 # 获取完整历史记录
# 设置 Node.js 环境 - uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' registry-url: 'https://registry.npmjs.org'
# 设置 Python 环境 - uses: actions/setup-python@v4 with: python-version: '3.11' cache: 'pip'
# 缓存依赖 - uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
# 上传/下载构建产物 - uses: actions/upload-artifact@v4 with: name: build-files path: dist/
- uses: actions/download-artifact@v4 with: name: build-files path: ./dist第三方 Actions
steps: # Docker 构建和推送 - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }}
- uses: docker/build-push-action@v5 with: push: true tags: myapp:latest
# Slack 通知 - uses: 8398a7/action-slack@v3 with: status: ${{ job.status }} channel: '#deployments' env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}最佳实践
1. 工作流优化
# 使用缓存加速构建- uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-npm-
# 并行执行作业jobs: test: # 测试作业 lint: # 代码检查作业 build: needs: [test, lint] # 依赖前面的作业2. 安全实践
# 最小权限原则permissions: contents: read
# 使用 Secrets 存储敏感信息env: API_KEY: ${{ secrets.API_KEY }}
# 环境保护规则environment: production # 需要手动审批3. 错误处理
steps: - name: 可能失败的步骤 run: npm test continue-on-error: true
- name: 条件执行 if: failure() # 只有前面步骤失败时才执行 run: echo "Tests failed, sending notification..."4. 调试和监控
steps: - name: 调试信息 run: | echo "Runner OS: ${{ runner.os }}" echo "GitHub Event: ${{ github.event_name }}" echo "Branch: ${{ github.ref }}"
- name: 设置输出 id: build-info run: echo "version=$(npm version --json | jq -r .version)" >> $GITHUB_OUTPUT
- name: 使用输出 run: echo "Built version ${{ steps.build-info.outputs.version }}"总结
GitHub Actions 提供了强大而灵活的 CI/CD 解决方案。通过合理使用触发器、构建矩阵、环境变量和 Secrets,你可以创建高效、安全、可维护的自动化工作流。
关键要点:
- 合理设计工作流结构 - 将相关任务分组到不同作业中
- 使用构建矩阵 - 在多环境下并行测试
- 管理好 Secrets - 保护敏感信息安全
- 优化性能 - 使用缓存和并行执行
- 遵循最佳实践 - 最小权限、错误处理、监控调试
通过这些实践,你可以构建出稳定可靠的 DevOps 流水线。
GitHub Actions 完整指南:从入门到实践
https://fuwari.vercel.app/posts/github-actions/