GitHub Actions 是 GitHub 于 2018 年推出的 CI/CD 平台,允许开发者在 GitHub 仓库中直接自动化构建、测试和部署流程。GitHub Actions 采用 事件驱动模型,与 GitHub 生态深度集成。
GitHub Actions 的核心定位是 GitHub 原生的 CI/CD 平台。它提供了:
# .github/workflows/ci.yml
name: CI
# 触发条件
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
schedule:
- cron: "0 2 * * *" # 每天凌晨 2 点
# 工作流级别环境变量
env:
NODE_VERSION: "18"
# 作业
jobs:
# 作业 1: 构建和测试
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16, 18, 20]
steps:
# 检出代码
- name: Checkout code
uses: actions/checkout@v4
# 设置 Node.js
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: "npm"
# 安装依赖
- name: Install dependencies
run: npm ci
# 运行 Lint
- name: Run Lint
run: npm run lint
# 运行测试
- name: Run tests
run: npm test
# 上传测试报告
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results-${{ matrix.node-version }}
path: test-results/
# 作业 2: 部署(依赖 build)
deploy:
runs-on: ubuntu-latest
needs: build
if: github.ref == "refs/heads/main"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Deploy to staging
run: |
echo "Deploying to staging..."
# 部署脚本
# .github/workflows/deploy.yml
name: Deploy
on:
push:
tags:
- "v*"
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
deploy-staging:
runs-on: ubuntu-latest
needs: build-and-push
environment:
name: staging
url: https://staging.example.com
steps:
- name: Deploy to staging
run: |
echo "Deploying to staging..."
# kubectl apply -f k8s/staging/
deploy-production:
runs-on: ubuntu-latest
needs: deploy-staging
environment:
name: production
url: https://example.com
steps:
- name: Deploy to production
run: |
echo "Deploying to production..."
# kubectl apply -f k8s/production/
# 条件执行
jobs:
test:
runs-on: ubuntu-latest
steps:
# 仅在 main 分支运行
- name: Integration tests
if: github.ref == "refs/heads/main"
run: npm run test:integration
# 仅在 PR 中运行
- name: PR checks
if: github.event_name == "pull_request"
run: npm run test:pr
# 跳过特定条件
- name: Skip on docs change
if: ${{ !contains(github.event.head_commit.message, "[skip ci]") }}
run: echo "Running..."
# 矩阵构建(多版本、多平台)
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.9", "3.10", "3.11"]
exclude:
- os: windows-latest
python-version: "3.9"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Run tests
run: python -m pytest
# 缓存依赖
steps:
- name: Cache npm dependencies
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles("**/package-lock.json") }}
restore-keys: |
${{ runner.os }}-node-
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Cache pip packages
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles("**/requirements.txt") }}
restore-keys: |
${{ runner.os }}-pip-
# .github/actions/setup-project/action.yml
name: "Setup Project"
description: "Setup Node.js and install dependencies"
inputs:
node-version:
description: "Node.js version"
required: true
default: "18"
cache-dependency-path:
description: "Path to dependency file"
required: false
default: "package-lock.json"
runs:
using: "composite"
steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: "npm"
cache-dependency-path: ${{ inputs.cache-dependency-path }}
- name: Install dependencies
run: npm ci
shell: bash
# 使用复合 Action
steps:
- name: Setup project
uses: ./.github/actions/setup-project
with:
node-version: "20"
- name: Run tests
run: npm test
# 常用第三方 Action
# 部署到 AWS
- name: Deploy to AWS
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-west-2
# 部署到 Azure
- name: Deploy to Azure
uses: azure/webapps-deploy@v2
with:
app-name: "my-app"
publish-profile: ${{ secrets.AZURE_PUBLISH_PROFILE }}
package: "."
# 部署到 Vercel
- name: Deploy to Vercel
uses: amondnet/vercel-action@v20
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
# 创建 Release
- name: Create Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
# 发送 Slack 通知
- name: Notify Slack
uses: slackapi/slack-github-action@v1.24.0
with:
payload: |
{
"text": "Workflow ${{ github.workflow }} completed!",
"blocks": [...]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
# 构建和推送 Docker 镜像
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: |
${{ secrets.DOCKER_USERNAME }}/my-app:latest
${{ secrets.DOCKER_USERNAME }}/my-app:${{ github.sha }}
ghcr.io/${{ github.repository }}:latest
ghcr.io/${{ github.repository }}:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
# 使用 Secrets
jobs:
deploy:
runs-on: ubuntu-latest
steps:
# 使用 GitHub Secrets
- name: Use secret
env:
API_KEY: ${{ secrets.API_KEY }}
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
run: |
echo "Deploying with API key..."
# 使用 $API_KEY 和 $DEPLOY_TOKEN
# 使用环境 Secrets(分环境)
- name: Deploy to production
env:
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
API_KEY: ${{ secrets.API_KEY }}
run: ./deploy.sh
# 环境配置(在 GitHub 界面中设置)
# 每个环境可以有独立的 Secrets
# 触发条件示例
on:
# Push 事件
push:
branches:
- main
- develop
paths:
- "src/**"
- "tests/**"
- "package.json"
- "Dockerfile"
tags:
- "v*"
# Pull Request 事件
pull_request:
types: [opened, synchronize, reopened, labeled]
branches:
- main
paths-ignore:
- "**.md"
- "docs/**"
# 定时触发(Cron)
schedule:
- cron: "0 2 * * *" # 每天 2:00
- cron: "0 6 * * 1" # 每周一 6:00
# Issue 事件
issues:
types: [opened, closed, labeled]
# 手动触发
workflow_dispatch:
inputs:
environment:
description: "部署环境"
required: true
default: "staging"
type: choice
options:
- staging
- production
version:
description: "版本号"
required: false
type: string
# 外部事件(Webhook)
repository_dispatch:
types: [deploy-request]
# 定时任务(废弃代码)
workflow_run:
workflows: ["CI"]
types: [completed]
| 对比项 | GitHub Actions | Jenkins | GitLab CI |
|---|---|---|---|
| 托管方式 | 云托管/自托管 | 自托管 | 云托管/自托管 |
| 免费额度 | 2000 分钟/月 | 无限 | 400 分钟/月 |
| 学习曲线 | 平缓 | 陡峭 | 中等 |
| 生态 | GitHub 生态 | 1800+ 插件 | GitLab 生态 |
| 适用场景 | GitHub 项目 | 复杂流水线 | GitLab 项目 |
GitHub Actions 概念、YAML 语法、第一个工作流
事件触发、矩阵构建、条件执行、缓存优化
复合 Action、自托管运行器、环境管理、安全配置
Docker 构建、云部署、自动化发布、CI/CD 流水线设计
GitHub Actions 是 GitHub 原生的自动化引擎。
它用 事件驱动、YAML 配置、免费额度 让 CI/CD 变得简单而强大。GitHub Actions 是现代开源项目和 GitHub 用户的最佳 CI/CD 选择。
"GitHub Actions 让自动化触手可及。" ⚡