GitHub Actions 是 GitHub 提供的持续集成 (CI) 和持续部署 (CD) 服务,它可以帮助开发者自动化软件开发生命周期中的各种任务,例如代码构建、测试、部署,甚至代码审查和发布管理。通过 GitHub Actions,你可以在代码仓库中定义一系列自动化工作流,让你的开发过程更加高效、可靠。

“好的工具能让开发者专注于创造,而不是重复劳动。GitHub Actions 就是这样的工具。”


一、什么是 GitHub Actions?

GitHub Actions 是一种事件驱动的自动化平台。这意味着当 GitHub 仓库中发生特定事件(例如 push 代码、pull_request 创建、issue 开启等)时,它可以自动触发预定义的工作流(Workflow)执行。

核心优势:

  • 与 GitHub 深度集成:直接在 GitHub 仓库中管理 CI/CD,无需外部工具。
  • 事件驱动:灵活配置触发事件,覆盖开发流程的各个环节。
  • 丰富生态:拥有庞大的 Actions 市场,提供各种预构建的自动化任务块。
  • 云原生:在云端虚拟机上运行,无需维护自己的 CI 服务器。
  • 免费额度:为开源项目和个人用户提供免费的构建时间。

二、核心概念

在深入使用 GitHub Actions 之前,理解以下核心概念至关重要:

  1. Workflow (工作流)

    • 一个工作流是一个可配置的自动化过程。它由一个或多个作业(Job)组成。
    • 工作流使用 YAML 文件定义,存储在 .github/workflows/ 目录下。
    • 每个工作流文件代表一个独立的自动化流程,例如一个用于测试,一个用于部署。
  2. Event (事件)

    • 触发工作流运行的特定活动。
    • 常见的事件包括 push(代码推送到仓库)、pull_request(PR 被创建、打开、同步等)、schedule(定时任务)、workflow_dispatch(手动触发)、issue_comment 等。
    • 你可以在工作流文件中指定一个或多个事件来触发它。
  3. Job (作业)

    • 一个作业是在一个新的虚拟机环境中执行的一系列步骤(Step)。
    • 一个工作流可以包含多个作业。这些作业可以并行运行,也可以按顺序依赖关系运行。
    • 每个作业都独立运行,拥有自己的虚拟机环境。
  4. Step (步骤)

    • 作业中的单个任务单元。
    • 一个步骤可以是一个 run 命令(执行 shell 脚本),也可以是一个 uses 操作(使用一个预定义的 Action)。
    • 步骤的执行是顺序的。
  5. Action (操作)

    • GitHub Actions 平台中可重用的代码单元,是实现特定任务的基础组件。
    • 一个 Action 可以是一个 Shell 脚本、一个 Docker 容器,或者一个 JavaScript 程序。
    • Action 通常由社区或 GitHub 官方提供,可以在 GitHub Marketplace 中找到。
    • 例如:actions/checkout@v4 用于拉取仓库代码,actions/setup-node@v4 用于设置 Node.js 环境。
  6. Runner (运行器)

    • 执行工作流的服务器。
    • GitHub 提供 GitHub-hosted runners (托管运行器),支持 Linux、Windows、macOS 等操作系统环境。
    • 你也可以搭建 Self-hosted runners (自托管运行器),在自己的服务器上运行工作流,适用于特殊环境或私有网络需求。

三、工作流文件 (.yml) 结构详解

工作流文件是 GitHub Actions 的核心配置文件,采用 YAML 格式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# .github/workflows/ci.yml

# 1. workflow 名称
name: CI Build and Test

# 2. 触发事件
on:
# 在 push 到 main 分支时触发
push:
branches:
- main
# 在 pull request 目标为 main 分支时触发
pull_request:
branches:
- main
# 允许手动触发
workflow_dispatch:

# 3. 定义一个或多个作业 (Jobs)
jobs:
# 第一个作业:build
build:
# 运行此作业的操作系统环境
runs-on: ubuntu-latest

# 步骤 (Steps) 列表
steps:
# 步骤 1: 打印一条消息
- name: Say Hi
run: echo "Hello, GitHub Actions!"

# 步骤 2: 拉取代码 (使用官方 action)
- name: Checkout Code
uses: actions/checkout@v4 # 使用 actions/checkout@v4 这个 Action

# 步骤 3: 设置 Node.js 环境 (使用官方 action)
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20' # 指定 Node.js 版本

# 步骤 4: 安装依赖
- name: Install dependencies
run: npm install

# 步骤 5: 运行构建
- name: Run build
run: npm run build

# 第二个作业:test
test:
# 这个作业依赖于 build 作业,只有 build 成功后才运行
needs: build
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install dependencies
run: npm install

# 运行测试
- name: Run tests
run: npm test

# 第三个作业:deploy (仅在 push 到 main 分支时,且 test 成功后才运行)
deploy:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: test # 依赖 test 作业
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v4

# ... 部署相关的步骤,例如登录云平台、上传文件等
- name: Deploy to Production
run: echo "Deploying to production..."

关键配置项详解:

  • name:工作流的名称,显示在 GitHub UI 中。
  • on:定义触发工作流的事件。
    • push: 当代码 push 到指定分支时触发。
      • branches: 指定分支列表。
      • paths: 指定文件路径,只有这些文件发生变化才触发。
      • tags: 指定触发的 Git 标签。
    • pull_request: 当 PR 发生变化时触发。
    • schedule: 使用 cron 语法定义定时触发。
    • workflow_dispatch: 允许从 GitHub UI 手动触发。
    • repository_dispatch: 允许从外部 webhook 触发。
  • jobs:工作流中的一系列作业。
    • job_id:每个作业的唯一标识符(如 build, test, deploy)。
    • runs-on:指定运行作业的执行环境,例如 ubuntu-latest, windows-latest, macos-latest 或自定义的 self-hosted 标签。
    • steps:作业中的一系列步骤,按顺序执行。
      • name:步骤的名称。
      • run:执行 shell 命令或脚本。
      • uses:使用一个 Action。格式通常是 owner/repo@ref (如 actions/checkout@v4)。你可以传递 with 参数给 Action。
      • env:在当前步骤中设置环境变量。
      • with:向 Action 或 run 命令传递输入参数。
      • if:条件表达式,用于决定是否执行该步骤。
    • needs:指定当前作业依赖的其他作业的 job_id。依赖的作业会先运行,并且成功后才会运行当前作业。
    • timeout-minutes: 作业超时时间,单位分钟。
    • strategy: 定义矩阵策略,用于并行运行多个变体配置的作业(如多个 Node 版本或操作系统)。
    • env: 在整个作业范围内设置环境变量。
  • env:在整个工作流范围内设置环境变量。
  • defaults: 为工作流或作业中的所有 run 命令设置默认的 shell 或工作目录。

四、事件类型与表达式

1. 常见事件

  • push: 代码推送到仓库。
  • pull_request: PR 的各种活动(opened, synchronize, closed, reopened)。
  • schedule: 定时任务,使用 cron 语法(0 0 * * * 表示每天午夜)。
  • workflow_dispatch: 手动触发,可以在 UI 界面输入参数。
  • issue_comment: 当 issue 收到评论时触发。
  • release: 发布新的 release 时触发。

2. 条件表达式 (if)

if 关键字允许你基于特定条件来决定是否执行某个 Job 或 Step。它可以使用 GitHub Contexts 来获取工作流运行时的各种信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
jobs:
conditional_job:
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/main' # 只有 push 到 main 分支时才运行
steps:
- run: echo "This runs only on main branch pushes."

another_conditional_job:
runs-on: ubuntu-latest
steps:
- name: Conditional Step
if: success() # 只有前一个步骤成功才运行
run: echo "Previous step was successful."

常用的上下文 (Contexts):

  • github: 包含仓库信息、触发事件、提交信息等。
    • github.event_name, github.ref, github.sha, github.actor
  • env: 环境变量。
  • job: 当前作业的信息。
  • steps: 步骤的输出信息。
  • runner: 运行器信息。
  • secrets: 存储的敏感信息。

五、Actions 市场与自定义 Actions

1. Actions 市场 (GitHub Marketplace)

GitHub Actions 市场是一个巨大的宝库,你可以在其中找到各种预构建的 Action,用于:

  • 代码仓库操作 (checkout, upload artifact)
  • 环境设置 (setup-node, setup-python, setup-go, setup-java)
  • 构建工具 (npm, yarn, gradle, maven)
  • 测试工具 (jest, cypress)
  • 通知 (slack, teams)
  • 部署 (to AWS, Azure, GCP, Heroku, Netlify)
  • 代码扫描、安全检查等

使用 Action 非常简单,只需在 uses 关键字后指定其路径和版本。

1
2
3
4
5
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }} # 使用 Secrets 传递敏感信息
flags: unittest # optional

2. 自定义 Actions

如果你在市场上找不到满足需求的 Action,或者想要封装自己的逻辑,可以编写自定义 Actions。自定义 Actions 可以是:

  • JavaScript Actions:用 JavaScript 编写,推荐用于复杂逻辑。
  • Docker Container Actions:用 Docker 容器封装环境和逻辑。
  • Composite Actions: 将多个 run 步骤和 uses 步骤组合成一个可复用的 Action。

六、Secrets (秘密)

在 CI/CD 流程中,经常需要使用敏感信息,如 API 密钥、数据库凭证等。GitHub Actions 提供了 Secrets 机制来安全地存储和使用这些信息。

  • 存储位置:在 GitHub 仓库的 Settings -> Secrets and variables -> Actions 中配置。
  • 使用方式:通过 ${{ secrets.SECRET_NAME }} 表达式在工作流中引用。
  • 安全性:Secrets 在日志中会被自动遮盖,不会明文显示。
1
2
3
4
5
6
- name: Deploy to AWS
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
aws s3 sync ./build s3://${{ secrets.S3_BUCKET_NAME }}

七、神器:Artifacts (构件)

Artifacts 允许你在不同的 Job 之间共享数据,例如:

  • 构建产物:在一个 Job 中构建的二进制文件、打包文件可以作为 Artifact 上传。
  • 测试报告:测试结果报告可以作为 Artifact 上传。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
jobs:
build:
runs-on: ubuntu-latest
steps:
# ... 构建代码
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: my-app-bundle
path: ./dist # 将 dist 目录作为构件上传

deploy:
runs-on: ubuntu-latest
needs: build
steps:
- name: Download build artifact
uses: actions/download-artifact@v4
with:
name: my-app-bundle # 下载名为 my-app-bundle 的构件
path: ./deploy_tmp # 下载到 deploy_tmp 目录

- name: Deploy
run: ls -l ./deploy_tmp && echo "Now deploying..."

八、实践场景举例

GitHub Actions 可以应用于广泛的开发场景:

  • 代码质量检查:每次 Push 代码时,自动运行 ESLint、Prettier、单元测试。
  • 自动化测试:PR 被创建或更新时,自动运行单元测试、集成测试、端到端测试。
  • 构建与打包:每次 Push 到 main 分支时,自动构建 Docker 镜像、打包前端应用。
  • 持续部署 (CD):代码合并到 main 分支并通过所有测试后,自动部署到开发、测试或生产环境。
  • 发布管理:当创建新的 Git Tag 时,自动生成发布日志、创建 GitHub Release、发布到 NPM 或 Docker Hub。
  • 任务自动化:定时清理不活跃的 Issues、自动回复 PR 评论等。

九、总结与展望

GitHub Actions 提供了一个强大、灵活且与 GitHub 平台深度集成的自动化解决方案。通过 YAML 文件配置工作流,你可以轻松地将各种自动化任务集成到你的开发流程中。

掌握 GitHub Actions 不仅能提升你的个人开发效率,也能帮助团队构建更健壮、更高效的 CI/CD 管道。随着云原生技术和 DevOps 理念的普及,自动化工具的重要性日益增加,GitHub Actions 无疑是这个领域中的一颗璀璨明星。

开始尝试编写你的第一个 .github/workflows/*.yml 文件吧,将你的重复性任务交给自动化,专注于更有创造性的编码工作!