GitHub Actions 是 GitHub 提供的原生 CI/CD(持续集成/持续部署)服务,直接集成在代码仓库中。当代码推送、PR 创建、Issue 打开等事件触发时,自动执行预定义的工作流——运行测试、构建应用、部署到服务器。它与 GitHub 生态无缝集成,且对公共仓库完全免费,是独立开发者和团队的首选 CI/CD 工具。
一、核心概念
| 概念 | 说明 |
|---|---|
| Workflow(工作流) | 一个 YAML 文件,定义一组自动化任务,放置在 .github/workflows/ 目录 |
| Event(事件) | 触发工作流的条件:push、pull_request、schedule 等 |
| Job(任务) | 工作流中的一个执行单元,默认并行运行 |
| Step(步骤) | Job 中的执行步骤,按顺序运行 |
| Action(动作) | 可复用的步骤单元,如 actions/checkout@v4 |
| Runner(运行器) | 执行 Job 的虚拟机(Ubuntu/macOS/Windows) |
| Artifact(产物) | Job 间传递的文件(构建结果、测试报告) |
二、工作流设计模式
2.1 最小可运行示例
name: Hello World
on:
push:
branches: [main]
jobs:
greet:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: echo "Hello, GitHub Actions!"
2.2 完整语法速查
name: Comprehensive Workflow
on:
push:
branches: [main, develop]
paths: ['src/**', 'tests/**']
pull_request:
branches: [main]
schedule:
- cron: '0 2 * * *' # 每天凌晨 2 点
workflow_dispatch: # 手动触发
inputs:
environment:
description: '部署环境'
required: true
default: 'staging'
type: choice
options: [staging, production]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true # 新执行取消正在运行的旧执行
env:
NODE_VERSION: '20'
jobs:
lint:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- run: npm ci
- run: npm run lint
test:
needs: lint # 等待 lint 完成后执行
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [18, 20, 22]
os: [ubuntu-latest]
include:
- node: 20
os: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm test
deploy:
needs: [lint, test]
runs-on: ubuntu-latest
environment:
name: Production
url: https://myapp.com
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
2.3 环境变量与 Secrets
jobs:
deploy:
runs-on: ubuntu-latest
env:
PUBLIC_VAR: 'visible' # 普通环境变量
steps:
- name: Use secrets
env:
API_KEY: ${{ secrets.API_KEY }} # 敏感信息
STAGE: ${{ vars.DEPLOY_STAGE }} # 非敏感配置
run: |
echo "Deploying to $STAGE"
npx deploy-cli --key "$API_KEY"
Secrets vs Variables:
- Secrets:加密存储,不可在日志中显示,适合 API Key、密码
- Variables:明文存储,可在日志中显示,适合环境名、Region
三、可复用工作流(Reusable Workflows)
3.1 定义可复用工作流
# .github/workflows/reusable-test.yml
name: Reusable Test Workflow
on:
workflow_call:
inputs:
node-version:
required: true
type: string
default: '20'
run-e2e:
required: false
type: boolean
default: false
secrets:
codecov-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 run test
- if: inputs.run-e2e
run: npm run test:e2e
- if: secrets.codecov-token
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.codecov-token }}
3.2 调用可复用工作流
# .github/workflows/main.yml
jobs:
call-reusable:
uses: ./.github/workflows/reusable-test.yml
with:
node-version: '20'
run-e2e: true
secrets:
codecov-token: ${{ secrets.CODECOV_TOKEN }}
跨仓库调用:
jobs:
call-remote:
uses: my-org/shared-workflows/.github/workflows/test.yml@main
with:
node-version: '20'
四、自制 Action 开发
4.1 Composite Action(组合型)
# .github/actions/setup-node-pnpm/action.yml
name: 'Setup Node + pnpm'
description: 'Setup Node.js with pnpm caching'
inputs:
node-version:
description: 'Node.js version'
required: true
default: '20'
runs:
using: "composite"
steps:
- uses: pnpm/action-setup@v3
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
shell: bash
使用:
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-node-pnpm
with:
node-version: '20'
4.2 JavaScript Action
// .github/actions/my-action/index.js
const core = require('@actions/core');
const github = require('@actions/github');
async function run() {
try {
const name = core.getInput('name');
const greeting = `Hello, ${name}!`;
core.setOutput('greeting', greeting);
core.info(greeting);
} catch (error) {
core.setFailed(error.message);
}
}
run();
# .github/actions/my-action/action.yml
name: 'My Action'
inputs:
name:
required: true
default: 'World'
outputs:
greeting:
description: 'The greeting message'
runs:
using: 'node20'
main: 'index.js'
五、Self-hosted Runner
5.1 配置企业内网 Runner
# 在目标服务器上执行
mkdir actions-runner && cd actions-runner
curl -o actions-runner-linux-x64-2.317.0.tar.gz \
-L https://github.com/actions/runner/releases/download/v2.317.0/actions-runner-linux-x64-2.317.0.tar.gz
tar xzf ./actions-runner-linux-x64-2.317.0.tar.gz
./config.sh --url https://github.com/my-org/my-repo --token <TOKEN>
./run.sh
5.2 使用 Self-hosted Runner
jobs:
deploy-internal:
runs-on: [self-hosted, linux, x64] # 标签匹配
steps:
- uses: actions/checkout@v4
- run: docker-compose up -d
适用场景:
- 需要访问内网资源(私有 Registry、内部 API)
- 需要特殊硬件(GPU、专用网络)
- 数据合规要求(代码不出企业网络)
六、权限安全最佳实践
6.1 最小权限原则
jobs:
deploy:
permissions:
contents: read # 只读代码
packages: write # 推送镜像
id-token: write # OIDC 认证
6.2 OIDC 免密认证(AWS/Azure/GCP)
permissions:
id-token: write
contents: read
jobs:
deploy-aws:
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/GitHubActionsRole
aws-region: us-east-1
# 无需存储 AWS 密钥,使用临时 Token
常见问题(FAQ)
GitHub Actions 免费吗?
公共仓库:完全免费,无限制。私有仓库:每月 2000 分钟(Linux)、500MB Artifact 存储。超出后按使用量计费。
和 GitLab CI / Jenkins 怎么选?
| 工具 | 适用场景 |
|---|---|
| GitHub Actions | GitHub 仓库、快速上手、开源项目 |
| GitLab CI | GitLab 仓库、一体化 DevOps 平台 |
| Jenkins | 企业自托管、复杂 Pipeline、大量插件需求 |
| CircleCI | 需要高级并行、可视化、企业级支持 |
| Travis CI | 简单开源项目 |
如何调试失败的 Workflow?
- 查看 Actions 日志(每个 step 的输出)
- 开启 debug 模式:
ACTIONS_STEP_DEBUG=truesecret - 使用
tmate远程 SSH 到 runner:- uses: mxschmitt/action-tmate@v3 if: failure()
相关阅读
- GitHub Actions Node.js CI 流水线 — 测试、构建、发布
- GitHub Actions Docker CI/CD — 容器化构建与推送
- GitHub Actions 部署到 Vercel — 前端项目自动部署
- Docker 专题 — Dockerfile 最佳实践
- Vercel 专题 — Vercel 平台深度指南
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。
「saas」更多文章
自定义域名接入 Cloudflare:CDN 加速与缓存规则配置实战
手把手讲解自定义域名接入 Cloudflare CDN 的完整流程:NS 接管、SSL/TLS 模式选择、橙云代理与灰云 DNS 的区别,并用 2024 年后的新 Cache Rules 引擎实战配置静态资源长缓存、HTML 不缓存、后台 Bypass,让边缘缓存命中率最大化。
Hugo 部署到 Cloudflare Pages 实战:从 Git 推送到全球边缘上线
详解 Cloudflare Pages 部署 Hugo 静态站的完整流程,涵盖框架预设、HUGO_VERSION 环境变量固定、构建命令、自定义域名、分支预览、_headers 缓存安全头配置及常见构建失败排查,一次推送即可全球边缘上线。
Cloudflare Workers 入门实战:在边缘运行你的第一行代码
一份面向初学者的 cloudflare workers 教程,从 V8 Isolate 运行时模型讲起,手把手演示 wrangler 初始化、路由分发、KV 存储、Cache API 缓存响应与环境变量配置,帮你在 30 分钟内部署第一个生产可用的边缘 Serverless 应用。