GitHub Actions 自动化:CI/CD 与工作流定制
GitHub Actions 入门:理解自动化
GitHub Actions 是 GitHub 内置的持续集成与持续交付平台。它允许你在代码仓库中直接创建自动化软件开发生命周期的工作流。无论是构建、测试、部署,还是执行任意脚本,都可以通过简单的事件触发机制实现。
对于初学者来说,可以把工作流想象成一个 “如果……就……” 的规则集合。例如:如果代码被推送到 main 分支,就自动运行测试并部署到服务器。
核心概念速览
- 工作流(Workflow):定义自动化过程的配置文件,存放于
.github/workflows目录,使用 YAML 语法编写。一个仓库可以有多个工作流。 - 事件(Event):触发工作流启动的特定活动,比如
push、pull_request、schedule(定时)或手动触发。 - 作业(Job):工作流中一组在同一个运行器上执行的步骤。默认情况下作业并行执行,但也可配置依赖关系顺序执行。
- 步骤(Step):作业中的独立任务,可以是运行脚本,也可以是使用市场上已有的动作(Action)。
- 动作(Action):可复用的单元代码,用于执行常见任务,如检出代码、设置 Node 环境、登录到云服务等。
- 运行器(Runner):执行作业的服务器,GitHub 提供 Ubuntu、Windows 和 macOS 虚拟环境,也支持自托管运行器。
理解这些概念后,就可以动手编写第一份工作流文件了。
创建第一个工作流
所有工作流必须放在仓库根目录下的 .github/workflows 文件夹内。文件以 .yml 或 .yaml 结尾。
基础工作流结构示例
下面是一个完整的 ci.yml 示例,功能是在每次推送代码到仓库时,自动运行一次简单的脚本。
name: 我的第一个 CI 工作流
# 定义触发事件
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
# 定义作业
jobs:
hello-world-job:
# 指定运行器操作系统
runs-on: ubuntu-latest
# 作业的步骤
steps:
# 第一步:检出仓库代码
- name: 检出代码
uses: actions/checkout@v4
# 第二步:运行 Shell 命令
- name: 打印信息
run: |
echo "🎉 GitHub Actions 工作流启动成功!"
echo "仓库名称: ${{ github.repository }}"
echo "触发分支: ${{ github.ref }}"
关键语法说明:
name:工作流显示名称,可选但推荐填写。on:触发器,支持多种事件,可以使用数组同时监听多个事件。jobs.<job_id>:每个作业的唯一 ID,这里hello-world-job是自定义名称。runs-on:指定运行环境,常用ubuntu-latest、windows-latest、macos-latest。steps:按顺序执行的步骤列表,每个步骤可定义name、uses(引用动作)或run(运行命令)。${{ }}:表达式语法,可以访问上下文变量。例如github.repository是当前仓库的全名。
保存文件并推送到 GitHub,在仓库的 Actions 标签页即可查看运行结果。如果失败,点击红色叉号可以查看详细日志。
实现 CI/CD:构建、测试与部署
GitHub Actions 最典型的应用场景就是 CI/CD 流水线。下面通过一个实际任务说明如何定制多作业工作流——对 Node.js 项目执行安装、测试、构建,并自动部署到 GitHub Pages。
一个完整的 Node.js CI/CD 示例
name: Node.js CI/CD 部署
on:
push:
branches: [ "main" ]
jobs:
# 第一个作业:构建与测试
build-and-test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x, 20.x] # 在不同 Node 版本下运行
steps:
- uses: actions/checkout@v4
- name: 使用 Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: 安装依赖
run: npm ci
- name: 运行单元测试
run: npm test
- name: 构建生产版本
run: npm run build --if-present
# 将构建产物(假设在 build 目录)上传为工件
- name: 上传构建产物
uses: actions/upload-artifact@v4
with:
name: build-output
path: build/
# 第二个作业:部署,依赖上一个作业完成
deploy:
needs: build-and-test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' # 仅 main 分支部署
steps:
- name: 下载构建产物
uses: actions/download-artifact@v4
with:
name: build-output
path: build/
- name: 部署到 GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./build
新增知识点解析
- 矩阵策略(Matrix):
strategy.matrix可以自动生成多个并行作业组合,常用于不同语言版本、操作系统的兼容性测试。 - 缓存(cache):
actions/setup-node中的cache: 'npm'会自动缓存依赖,加速后续安装。 - 工件(Artifact):通过
upload-artifact和download-artifact在作业间传递数据,解决作业隔离的问题。 - 作业依赖:
needs: build-and-test确保部署作业仅在构建测试成功后才运行。 - 条件执行:
if字段可以根据表达式控制步骤或作业是否执行。 - 密钥管理:
${{ secrets.GITHUB_TOKEN }}是 GitHub 自动生成的令牌,用于权限验证。自定义密钥需在仓库设置中添加。
定制你的工作流:触发、环境与变量
深入定制工作流会让自动化更灵活、更安全。以下是一些常见的高级配置手段。
多种事件与路径过滤
on:
# 只有指定路径下文件变动时才触发
push:
paths:
- 'src/**'
- 'package.json'
# 支持定时任务(UTC 时间)
schedule:
- cron: '0 8 * * 1' # 每周一 8:00 运行
# 允许手动触发,并可定义输入参数
workflow_dispatch:
inputs:
logLevel:
description: '日志级别'
required: true
default: 'warning'
- 路径过滤:减少不必要运行,例如只在前端代码变更时触发。
- 定时运行:使用 POSIX cron 语法,注意频率限制(公共仓库最多 5 分钟一次)。
- 手动触发:在 Actions 页面会出现“Run workflow”按钮,可供选择参数。
环境变量与加密密钥
可以在工作流文件的不同层级设置变量:
env:
GLOBAL_VAR: "全局可用"
jobs:
my-job:
runs-on: ubuntu-latest
env:
JOB_VAR: "仅本作业可用"
steps:
- name: 输出变量
env:
STEP_VAR: "仅本步骤可用"
run: |
echo "全局: $GLOBAL_VAR"
echo "作业: $JOB_VAR"
echo "步骤: $STEP_VAR"
密钥使用:敏感信息(API 密钥、密码)绝不能明文写入文件,必须在仓库 Settings > Secrets and variables > Actions 中添加,然后通过 ${{ secrets.SECRET_NAME }} 引用。
创建自定义 Action
当多个工作流需要复用的逻辑时,可以创建自定义 Action。有两种类型:
- JavaScript Action:使用 Node.js 编写,适合复杂逻辑。
- 复合 Action(Composite):将多个步骤组合成一个,复用简单脚本。
最简单的复合 Action 示例,在仓库中创建 action.yml:
name: '打印问候并列出文件'
description: '一个简单的自定义复合动作'
inputs:
greeting:
description: '问候语'
required: true
default: '你好'
runs:
using: "composite"
steps:
- run: echo "${{ inputs.greeting }},当前文件列表:"
shell: bash
- run: ls -la
shell: bash
然后在工作流中,通过相对路径引用:
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/my-custom-action # 假设 action.yml 存放在此目录
with:
greeting: '欢迎使用'
最佳实践与常见问题
优化运行速度
- 合理使用缓存:除了语言生态的缓存,还可手动使用
actions/cache@v4缓存任意目录。 - 按需安装依赖:使用
npm ci或等效命令,避免每次都重新解析依赖树。 - 并行作业与矩阵:拆解独立的测试任务,提高整体流水线速度。
安全注意事项
- 永远不要在日志中打印密钥,使用
::add-mask::动态屏蔽值。 - 限制工作流权限:在仓库设置中,将默认的读写令牌权限改为只读,仅在必要作业中使用
permissions字段提权。 - 审计第三方 Action:锁定 Action 版本(如
@v4),定期审查其源码与安全性。
调试与排错
- 开启 Debug 日志:在仓库设置中添加 key 为
ACTIONS_STEP_DEBUG,值为true的变量,可获取详细运行日志。 - 使用
actions/github-script快速输出上下文信息:- uses: actions/github-script@v7 with: script: | console.log(JSON.stringify(context, null, 2));
常见问题
问:如何在不同作业间共享环境变量?
答:环境变量无法跨作业共享,但可以将变量写入文件,通过工件传递,或者使用作业级别的 outputs 结合 needs 访问。
问:定时工作流没有准时触发?
答:cron 定时器基于 UTC 时间,且在高负载时可能会延迟,通常延迟在 3 到 10 分钟,不属于精确调度。
现在你已经掌握了 GitHub Actions 自动化从概念到实战的全部基础。从今天开始,试着为自己的项目编写第一个 CI 工作流,体验提交代码后自动测试和部署的畅快感受。