在开发项目时,很多开发者都会面临部署的麻烦,每次修改代码后,需要手动打包、上传文件、重启服务。这些步骤重复进行,不仅耗费时间,还容易出错,特别是项目需要频繁迭代时。
而优化这一问题,最直接有效的办法就是引入 CI/CD 流程,把这些重复操作交给自动化工具完成。其中,GitHub Actions 是当前最便捷的选择之一,它直接内置在 GitHub 仓库中,配置简单,免费额度充足,适合大多数个人和小型团队项目。
1 什么是 CI/CD?
CI/CD 可以理解为软件开发的“自动化流水线”。
想象一个工厂生产手机:以前是工人手工组装每个部件、一个个测试、最后手动包装发货。效率低,还容易出次品。现在换成流水线:零件一进工厂,机器自动组装、自动检测质量、检测通过后自动包装并送上货车。
CI/CD 就是这样的流水线:
- CI(持续集成):代码改好推上去后,系统自动构建项目并运行测试,快速发现是否有问题。
- CD(持续部署):测试通过后,系统自动把代码发布到服务器或托管平台,让最新版本直接上线。
这样做的好处是显而易见的:减少手动重复工作,避免人为失误,让开发过程更流畅可靠。
flowchart LR
Code[计划/编码]
subgraph CI[持续集成 CI]
VC[版本控制]
Build[构建&测试]
Check{测试通过?}
end
subgraph CD[持续交付/部署 CD]
Deploy[发布/部署]
Pre[预发布环境]
Online[生产环境]
end
Code --> VC --> Build --> Check
Check -- 否 --> Code
Check -- 是 --> Deploy
Deploy --> Pre
Deploy --> Online
常见的 CI/CD 工具包括 Jenkins、CircleCI、Travis CI、GitLab CI 和 GitHub Actions。这些工具都能实现自动化构建、测试和部署,但实现方式和使用体验有所不同。
在众多 CI/CD 工具中,GitHub Actions 尤其适合个人开发者和小团队。它与 GitHub 仓库天然集成,无需额外平台切换,运行环境由 Github 提供,省去自建和维护成本。再加上免费额度够用、YAML 配置简单且模板丰富,基本可以快速搭建起自动化部署流程。
2 GitHub Actions 核心概念
GitHub Actions 的大部分概念都是 CI/CD 通用概念,适用于任何自动化流程,在此基础上 GitHub Actions 增加了一些独有的术语和操作方式,让其变得实用性更强。
- 工作流(Workflow)
工作流是整个自动化流程的“总蓝图”,定义了一系列自动化任务的执行顺序和规则。可以把它想象成工厂流水线:从原材料进来,到成品出去,整个过程的规划都写在这里。一个仓库可以有多个工作流,每个工作流都用一个 YAML 文件定义(通常放在 .github/workflows/ 目录下),这个文件里会包含触发器、动作等。
- 触发器(Trigger / Event)
触发器就是“启动开关”,决定了工作流的条件或事件。常见的触发事件有:推送代码(push)、创建拉取请求(pull_request)、定时任务(schedule)、手动点击运行(workflow_dispatch)。比如一 push 代码,就相当于拉下开关,流水线立刻启动运转。
- 作业(Job)
作业是流水线上的“独立工段”,它是工作流中的一个独立执行单元。一个工作流可以包含多个作业,可以把它们想象成不同的生产阶段:一个工段负责“组装”(构建项目),另一个工段负责“质检”(运行测试)。作业之间还可以设置依赖关系,比如只有“质检”通过了,才会执行后面的“发货”(部署)。
- 步骤(Step)
步骤是工段里的“具体工序”,一个作业由多个步骤按顺序串联执行。每个步骤可以直接运行一条 shell 命令(比如 npm install),也可以调用一个动作(Action)。就像流水线上一个个紧挨的操作站:拉取代码 - 安装依赖 - 构建项目,环环相扣,缺一不可。
- 动作(Action)
动作是流水线上的“装置设备”,能快速插入封装好的功能。它可以来自 GitHub Marketplace(官方市场),也可以是自己写的。就像流水线上某个位置:需要用机械臂进行操作,不需要自己去制造,直接“买”一个机械臂就可以立刻干活。常见动作有 actions/checkout(拉取代码)、actions/upload-artifact(上传构建产物)等,极大减少重复写命令的麻烦。
- 运行器(Runner)
运行器是整个工段运转的“虚拟车间”,提供计算环境和资源让所有步骤和动作执行起来。GitHub 提供官方托管的车间(GitHub-hosted runner),支持 Ubuntu、Windows、macOS,免费额度内开箱即用,零维护。如果有特殊需求也可以自建车间(self-hosted runner),部署到自己的服务器或云主机上。
掌握了这几个核心概念,就已经能看懂大部分 GitHub Actions 的 YAML 配置了。下面是一个工作流文件示例,可以帮助更清晰里理解:
name: Hello Actions # 工作流的名字,在 GitHub 上会显示这里
on: # 触发器
push: # 当推送代码时触发
branches: # 只针对这些分支
- main
jobs: # 作业
greet: # 作业的名字,叫 greet(随意取)
runs-on: ubuntu-latest # 运行器:用 GitHub 提供的 Ubuntu
steps: # 步骤
- name: Checkout code # 步骤名字(可选,但建议写,便于看日志)
uses: actions/checkout@v4 # 使用动作:自动拉取代码
- name: Say Hello # 另一个步骤
run: echo "Hello" # 直接运行 shell 命令,打印一句话3 入门准备
在开始配置自己的自动化工作流之前,先来熟悉 GitHub Actions 的几个关键操作和设置,会让后续编写 YAML 文件时更得心应手。
在哪里创建和管理 Workflow 文件
Workflow 的配置文件必须放在仓库的 .github/workflows/ 目录下,一个仓库可以有多个 YAML 文件,每个文件就是一个独立的工作流。
创建 Workflow 文件操作步骤:
- 打开一个 GitHub 仓库,点击 Add file > Create new file
- 在文件名输入框中直接输入
.github/workflows/ci.yml(名字随意,后缀必须是 .yml 或 .yaml) - 把 YAML 内容粘贴进去,提交更改到 main 分支

怎么查看运行记录和日志
Workflow 的日志非常有用,绝大数的出错都能在这里找原因,且日志非常清晰,很容易定位到问题所在。
- 仓库顶部导航栏有个 Actions 标签,点进去左边是工作流列表,右边是历史记录
- 点入一条历史记录,左侧选择一个 job,就可以按照 Step 来查看详细日志了


Secrets 在哪里设置
Secrets(密钥) 通常用来存储需要加密的敏感数据,与之对应的还有不加密的 Variables(变量),它们以键值对的结构保存,组成了可重复使用的配置数据。
Secrets 设置路径:
- 打开一个 GitHub 仓库,点击顶部导航栏的 Settings 标签
- 在左侧侧边栏找到 Secrets and variables 并展开,随后点击 Actions
- 点击 New repository secret 创建密钥
- 在 YAML 中引用方式:
${{ secrets.YOUR_SECRET_NAME }}

在哪里找现成的 Action
大部分工作流都会用到写法类似 uses: xxx 的动作,这些动作大部分来自 官方市场。
访问官方市场找到需要的 Actions,点进去你可以在右侧切换版本和查看使用示例,左侧文档里通常还提供更完整的使用方法。

常用官方动作:
actions/checkout@v6拉取仓库代码actions/setup-node@v6安装并配置 Node.js 运行环境actions/cache@v5缓存依赖与构建结果,加速 CIactions/upload-artifact@v6保存构建产物,用于跨 Job 传递文件actions/download-artifact@v6获取构建产物,用于跨 Job 传递文件
免费额度与运行器
GitHub Actions 对于公共仓库是完全免费的(无限分钟和存储),对于私人仓库,免费账户每月提供 2000 分钟的免费运行时间和 500MB 的Artifact 存储配额,对个人开发者和小团队的日常使用已经绰绰有余。
不同运行器存在消耗差异:
ubuntu-latest:消耗 1 倍分钟,默认选择
windows-latest:消耗 2 倍分钟
macos-latest:消耗 10 倍分钟
使用量可以在 用户设置 > * Billing and licensing* 查看
开始第一个 Workflow
在任意仓库 .github/workflows/hello.yml 中写入下面内容并提交:
name: Hello Test
on: push
jobs:
hello:
runs-on: ubuntu-latest
steps:
- run: echo "GitHub Actions 运行成功!"在 Actions 页面看到日志里打印“GitHub Actions 运行成功!”,就说明成功了

4 实战案例
有了前面的入门准备和核心概念,现在进入案例部分,从基础到进阶,逐步覆盖 GitHub Actions 的绝大多数常用功能和知识点。
案例1:Push 时自动运行测试
适用于几乎所有项目的最小化 CI 流程。在代码推送或提交 PR 时自动运行单元测试,尽早发现问题,避免坏代码进入主分支。
# .github/workflows/ci-tests.yml
name: Run Tests
on:
# 代码推送事件(main 或 develop 分支时触发)
push:
branches: [main, develop]
# Pull Request事件(main 分支时触发)
pull_request:
branches: [main]
jobs:
test:
# 指定运行器为 ubuntu-latest
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
# 配置 Node.js 环境(版本 24,启用 npm 缓存)
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '24'
cache: 'npm'
- name: Install dependencies
run: npm ci # 执行命令
- name: Run tests
run: npm testpush 和 pull_request 触发器确保每次代码变更都会自动测试。如果测试失败,GitHub 会标记 commit 为失败并发送通知。非 Node 项目只需更换对应的 setup 动作和命令即可。
知识点总结
- 触发器:
push、pull_request及其分支过滤 - 官方动作:
actions/checkout@v6、actions/setup-node@v6 - 基本步骤结构:
name、uses、run、with - 运行器选择:
runs-on
案例2:矩阵并行,多版本多平台测试
适用于需要同时兼容多个运行环境的项目,一次提交并行验证所有组合。
# .github/workflows/matrix-test.yml
name: Matrix Testing
on: [push, pull_request] # 在代码推送或创建 PR 时触发
jobs:
test:
# 定义矩阵策略,生成多个并行任务
strategy:
matrix:
node-version: [18, 20, 22, 24] # 定义 Node.js 版本矩阵
os: [ubuntu-latest, windows-latest, macos-latest] # 定义操作系统矩阵
fail-fast: false # 一个组合失败不终止其他组合
# 使用矩阵中的操作系统
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v6
# 使用矩阵中的 Node.js 版本
- name: Setup Node ${{ matrix.node-version }}
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm teststrategy.matrix 会自动生成所有组合的 Job 并并行执行。共 4 个 Node 版本 × 3 个操作系统 = 12 个并行测试任务,每个任务独立运行。
知识点总结
strategy.matrix多维度组合测试- 矩阵变量引用(
${{ matrix.xxx }}) fail-fast控制并行失败行为- 跨平台/多版本并行执行加速
案例3:自定义缓存路径与键
适用于需要缓存任意目录或文件(如 node_modules、构建缓存、第三方工具)的项目。相比 setup-node 内置缓存,actions/cache@v4 更灵活,可精确控制缓存键、路径和恢复行为。
# .github/workflows/custom-cache.yml
name: Cache Dependencies
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
# 配置 Node.js 环境(不使用内置缓存)
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '24'
# 自定义缓存 node_modules 和 npm 全局缓存
- name: Cache node_modules
uses: actions/cache@v5
with:
path: |
node_modules
~/.npm
# 缓存键:基于 OS 和 package-lock.json 的哈希
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
# 恢复键:依赖变更时尝试匹配旧缓存
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build使用 hashFiles 生成基于 lockfile 的缓存键,确保依赖变更时自动失效缓存。restore-keys 提供回退匹配。
知识点总结
- 独立缓存动作
actions/cache@v5 - 自定义缓存路径(
path多行支持) - 精确缓存键(
key与hashFiles) - 回退键(
restore-keys)与缓存命中优化
案例4:上传与下载构建产物
适用于构建产物需要在后续 Job 传递或手动下载的场景,实现跨 Job 文件共享。
# .github/workflows/artifact.yml
name: Build & Artifact
on: [push]
jobs:
# build Job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '24'
- name: Install & Build
run: npm ci && npm run build
# 上传构建产物(上传 dist/ 命名为 dist-files)
- name: Upload artifact
uses: actions/upload-artifact@v6
with:
name: dist-files
path: dist/
# deploy Job
deploy:
needs: build # 依赖 build Job(必须等其完成后执行)
runs-on: ubuntu-latest
steps:
# 下载构建产物(名称为 dist-files)
- name: Download artifact
uses: actions/download-artifact@v6
with:
name: dist-files
- name: List files
run: ls -R # 递归列出当前目录下所有文件和子目录Artifact 本质上是一个默认保留 90 天的临时文件存储服务,专门用于工作流中实现跨 Job、跨环境的文件传递。
知识点总结
- 官方动作:
actions/upload-artifact@v6、actions/download-artifact@v6 - Job 依赖关系(needs)
- 跨 Job 文件传递与调试
案例5:跨 Job 传递输出数据
适用于需要将一个 Job 的计算结果(如版本号、commit 信息、动态值)传递给后续 Job 的场景,避免重复计算。
# .github/workflows/job-outputs.yml
name: Job Outputs
on: [push]
jobs:
create-data:
runs-on: ubuntu-latest
# 声明要输出的变量 current_time
outputs:
current_time: ${{ steps.get-time.outputs.time }} # 此处 time 对应 '当前时间是 $(date)'
steps:
- name: Get current time
id: get-time # 给这个步骤起个 ID,方便后面引用
run: echo "time=当前时间是 $(date)" >> $GITHUB_OUTPUT # >> $GITHUB_OUTPUT:把结果保存为这个步骤的输出
use-data:
needs: create-data
runs-on: ubuntu-latest
steps:
- name: Print time
run: echo "打印接收到的时间:${{ needs.create-data.outputs.current_time }}"前一个 Job 生成一个动态时间戳字符串,后一个 Job 直接获取并使用。实际项目中,可将时间戳替换为版本号、commit 信息等轻量数据。
知识点总结
- 步骤输出设置(id 与 $GITHUB_OUTPUT)
- Job 输出声明(outputs)
- 跨 Job 数据引用(
needs.job.outputs.xxx)
案例6:手动触发工作流并条件执行
适用于需要人工确认的敏感操作,提供交互式参数,手动选择或者输入后根据条件执行不同逻辑。
# .github/workflows/manual-deploy.yml
name: Manual Deploy
on:
# 启用手动触发
workflow_dispatch:
# 自定义输入项
inputs:
# env(部署环境)选择器,可选 staging 和 production
env:
type: choice
description: 部署环境
options: [staging, production]
default: staging
# version(版本号)输入框
version:
type: string
description: 版本号
default: latest
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
# 部署测试环境
- name: Deploy Staging
if: github.event.inputs.env == 'staging'
run: echo "Deploy staging ${{ github.event.inputs.version }}"
# 部署生产环境
- name: Deploy Production
if: github.event.inputs.env == 'production'
run: echo "Deploy production ${{ github.event.inputs.version }}"
知识点总结
workflow_dispatch手动触发inputs参数定义(choice、string、boolean 等类型)- 事件上下文引用(
github.event.inputs.xxx) - 步骤/Job 条件执行(
if)
案例7:定时任务(Schedule)
适用于定期自动执行的任务(如依赖更新检查、夜间构建、数据备份),无需代码变更即可定时运行。
# .github/workflows/schedule.yml
name: Scheduled Task
on:
# 定时触发器,使用 cron 语法
schedule:
- cron: '0 3 * * *' # UTC 每天 3:00(北京 11:00)
workflow_dispatch: # 方便手动测试
jobs:
nightly:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '24'
- name: Install dependencies
run: npm ci
- name: Check outdated dependencies
run: npm outdated || echo "所有依赖均为最新"
- name: Run security audit
run: npm audit || echo "安全检查完成"cron 使用 UTC 时区,五个字段分别代表 分 时 日 月 周(具体用法)
知识点总结
schedule触发器- cron 语法格式
- 定时自动化任务场景
案例8:构建并推送 Docker 镜像
适用于将项目容器化并自动发布到镜像仓库,发布版本标签时自动构建镜像并推送。
# .github/workflows/docker-publish.yml
name: Docker Publish
on:
push:
tags: ['v*'] # v* 标签(如 v1.0.0)时触发
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
# 登录 Docker Hub
- name: Login Docker
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }} # Docker Hub 用户名
password: ${{ secrets.DOCKER_TOKEN }} # Docker Hub 生成的 Access Token
# 构建并推送镜像
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true # 推送镜像
tags: | # 多标签推送
${{ secrets.DOCKER_USERNAME }}/myapp:latest
${{ secrets.DOCKER_USERNAME }}/myapp:${{ github.ref_name }}镜像标签 latest 始终指向最新构建、${{ github.ref_name }} 指标签名(如 v1.2.3),实际项目中可根据需要调整标签策略(如预发布不打 latest)。
知识点总结
- 社区动作:
docker/login-action@v3、docker/build-push-action@v6 - Secrets 在部署中的使用
- Docker 镜像多标签推送与版本管理
案例9:构建并上传到服务器
适用于需要将构建产物部署到自有服务器的项目,完成构建后自动上传到服务器,实现零手动部署。
在创建工作流之前,需要先生成密钥对并且在服务器上配置 SSH 无密码登录(具体操作)
# .github/workflows/deploy-server.yml
name: Deploy Server
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '24'
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
# 通过 SSH 上传文件到服务器(使用 rsync 同步)
- name: Deploy to server
uses: easingthemes/ssh-deploy@v5
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} # SSH 私钥
REMOTE_HOST: ${{ secrets.SSH_HOST }} # 服务器 IP 或域名
REMOTE_USER: ${{ secrets.SSH_USERNAME }} # 登录用户名(不建议 root)
SOURCE: "dist/" # 要上传的目录
TARGET: ${{ secrets.TARGET_PATH }} # 服务器目标目录
ARGS: "-avzr --delete" # rsync 参数:压缩、递归、删除多余文件部署成功后,服务器上的目标目录会同步最新构建产物。
知识点总结
- 社区动作:
easingthemes/ssh-deploy@v5 - 远程服务器部署(rsync 同步)
- 生产级传统部署链路
5 高级特性与优化
在实际生产环境中,尤其是团队协作或项目规模增大时,还需要一些高级特性来提升工作流的优雅度和稳定性。
5.1 可复用工作流(Reusable Workflows)
大型项目或多仓库组织中,常常有重复的流程(如测试、构建、部署)。手动复制 YAML 会导致维护困难。GitHub 支持可复用工作流,允许把通用流程抽成模板,跨仓库调用。
# 模板仓库:.github/workflows/reusable-test.yml
name: Reusable Test Workflow
on:
workflow_call: # 关键:表示这是可被调用的工作流
inputs: # 定义输入参数
node-version:
required: true
type: string
cache-enabled:
type: boolean
default: true
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ inputs.node-version }}
cache: ${{ inputs.cache-enabled && 'npm' || '' }}
- run: npm ci
- run: npm test# 项目仓库:.github/workflows/ci.yml
name: Call Reusable Test
on: [push, pull_request]
jobs:
call-test:
uses: [用户名、组织名]/[模板仓库]/.github/workflows/reusable-test.yml@main # 调用路径
with: # 传入参数
node-version: '24'
cache-enabled: trueworkflow_call 用于定义可复用工作流,支持传入参数(inputs)和密钥(secrets),调用只需要 uses 路径@分支。
5.2 环境与部署保护(Environments)
生产环境部署往往需要人工审核、限制并发或特定 Secrets。可以配置比仓库 Secrets 更细粒度的环境级 Secrets,以及两个常用保护规则:
- Required reviewers:必须指定人员审批
- Wait timer:部署前等待一段时间(防止误操作)

jobs:
deploy-prod:
environment: production # 指定环境,触发保护规则
runs-on: ubuntu-latest
steps:
# 环境专属 Secrets 自动可用
- run: deploy-script --token ${{ secrets.PROD_TOKEN }}5.3 自托管运行器(Self-hosted Runners)
GitHub 托管运行器免费但有额度限制,且不支持某些特定环境。自托管运行器可部署到自己的机器或云主机。
快速搭建:
- 仓库 Settings > Actions > Runners > New self-hosted runner
- 按提示下载并运行 runner 应用(支持 Linux/Windows/macOS)
- 配置标签(labels)区分不同机器

jobs:
heavy-build:
runs-on: self-hosted # 自托管运行器
steps:
- run: ./heavy-computation6 写在最后
GitHub Actions 只是 CI/CD 工具中的一员,选择它是因为足够简单且强大,随着项目成长,可能会用到其他工具,如 GitLab CI、Jenkins等,它们的核心思路是相通的:让重复工作自动化,让开发者专注创造价值。
如果你感兴趣,可以在下方深入学习:
- GitHub Actions 文档:https://docs.github.com/zh/actions
- GitLab CI/CD:https://docs.gitlab.com/topics/build_your_application/
- Jenkins Pipeline:https://www.jenkins.io/doc/book/pipeline/
评论
暂无评论,快来发表第一条评论吧!