GitHub Actions 教程:手把手带你入门
自动化是现代软件开发流程中不可或缺的一部分。它可以帮助我们自动执行重复性的任务,如构建代码、运行测试、部署应用等,从而提高效率、减少错误并加速交付。在众多自动化工具中,GitHub Actions 作为 GitHub 原生集成的 CI/CD(持续集成/持续部署)服务,因其便捷性、灵活性和与 GitHub 生态系统的紧密结合而受到广泛欢迎。
本教程将带你从零开始,深入理解 GitHub Actions 的核心概念,并通过实际案例学习如何创建和运行你的第一个自动化工作流。无论你是一名开发者、运维工程师,还是对自动化充满好奇的新手,都能从中获益。
预计阅读时间: 约 30-40 分钟
目标读者: 对 GitHub Actions 零基础或了解不多的用户
目录
- 什么是 GitHub Actions?为什么使用它?
- CI/CD 的概念
- GitHub Actions 的定位与优势
- 核心概念解析
- Workflow(工作流)
- Event(事件)
- Job(任务)
- Step(步骤)
- Action(动作)
- Runner(运行器)
- 环境准备:你的第一个 GitHub 仓库
- 手把手创建你的第一个 Workflow
- 创建
.github/workflows
目录 - 编写 YAML 工作流文件
- 理解基础 YAML 结构
- 实战:运行一个简单的命令
- 提交并查看运行结果
- 创建
- 进阶示例:构建和测试一个简单的项目
- 创建一个简单的 Node.js 项目
- 编写构建和测试的工作流
- 使用 Marketplace 中的 Action
- 设置 Node.js 环境
- 安装依赖
- 运行构建和测试命令
- 理解
on: [push, pull_request]
- 深入理解 YAML 语法与常用指令
name
:工作流名称on
:触发事件jobs
:任务集合runs-on
:指定运行器steps
:步骤集合uses
:引用一个 Actionrun
:执行命令行命令with
:向 Action 或步骤传递参数env
:设置环境变量if
:条件判断
- 探索 GitHub Actions 的高级特性(快速了解)
- Secrets:处理敏感信息
- Artifacts:保存构建产物
- Matrix Strategy:构建矩阵
- Manual Triggers:手动触发
- Scheduled Events:定时触发
- Reusable Workflows:可复用工作流
- GitHub Marketplace:发现更多 Action
- 故障排除与调试
- 查看工作流运行日志
- 常见的错误及解决方法
- 如何测试工作流
- 最佳实践
- 保持工作流文件简洁
- 使用明确的名称
- 固定 Action 版本
- 善用 Secrets
- 从小处着手,逐步完善
- 总结与展望
1. 什么是 GitHub Actions?为什么使用它?
在深入学习之前,我们先来了解一下 GitHub Actions 是什么,以及它在软件开发中的作用。
CI/CD 的概念
- 持续集成 (Continuous Integration, CI): 开发者频繁地(通常每天多次)将代码集成到共享仓库主分支。每次集成都会触发自动化的构建(编译、打包)和测试过程。目标是尽早发现和解决集成冲突和代码缺陷。
- 持续部署/交付 (Continuous Deployment/Delivery, CD): 在 CI 的基础上,将通过所有测试的代码自动部署到生产环境(CDep, 持续部署)或准备好随时手动部署(CDel, 持续交付)。目标是快速、可靠地将新功能和修复推向用户。
CI/CD 是敏捷开发和 DevOps 文化的核心实践之一。它通过自动化减少了人工干预,加快了发布周期,提高了软件质量。
GitHub Actions 的定位与优势
GitHub Actions 是 GitHub 平台提供的一项 CI/CD 服务。它允许你在 GitHub 仓库中定义一系列自动化工作流,这些工作流可以在特定的事件发生时(如代码推送、创建 Pull Request、发布 Release 等)自动执行。
使用 GitHub Actions 的主要优势包括:
- 深度集成 GitHub: 作为 GitHub 原生服务,Actions 与 GitHub 仓库、Pull Requests、Issues、Releases 等功能无缝集成,使用体验流畅自然。无需额外的第三方账号或复杂的集成配置。
- 易于上手: 使用 YAML 语法定义工作流,结构清晰,易于阅读和编写。GitHub 提供了直观的图形界面来查看工作流运行状态和日志。
- 丰富的 Actions Marketplace: GitHub Marketplace 上有大量的预置 Action,涵盖了从代码检查、构建、测试到各种云服务部署等几乎所有常见的自动化需求。你可以轻松引用这些 Action,而无需从零开始编写脚本。
- 灵活的自定义能力: 除了使用现有的 Action,你也可以编写自己的 Action(基于 Docker 容器或 JavaScript),或者直接在工作流中运行任意的 shell 命令。
- 多平台支持: GitHub 提供的托管运行器支持多种操作系统(Ubuntu, Windows, macOS),满足不同项目的构建需求。
- 免费额度: 对于公共仓库,GitHub Actions 提供免费的无限使用额度。对于私有仓库,也提供了慷慨的免费额度(取决于账户类型),超出部分按量付费,成本通常也很合理。
简而言之,GitHub Actions 是一个强大、灵活且与 GitHub 紧密结合的自动化工具,是构建现代 CI/CD 流水线的优秀选择。
2. 核心概念解析
在开始编写工作流之前,理解 GitHub Actions 的一些核心概念至关重要。
-
Workflow (工作流): 这是 GitHub Actions 的最高层概念。一个工作流是一个可配置的自动化过程,定义了在特定事件发生时需要执行的一系列任务。工作流定义文件使用 YAML 格式,存储在仓库的
.github/workflows
目录下。一个仓库可以有多个工作流文件,用于不同的自动化目的(例如,一个用于 CI,一个用于 CD,一个用于生成文档等)。 -
Event (事件): 事件是触发工作流运行的特定活动。常见的事件包括:
push
: 代码被推送到仓库的某个分支时。pull_request
: 创建、更新或关闭 Pull Request 时。schedule
: 基于 Cron 语法定时触发。workflow_dispatch
: 手动在 GitHub 界面上触发。release
: 发布、编辑、删除或标记 Release 时。- 还有很多其他事件,如 Issue 评论、Package 发布等。
-
Job (任务): 一个工作流由一个或多个任务组成。每个任务都在一个独立的虚拟机环境(Runner)中执行。任务之间默认是并行运行的,但你也可以配置它们按顺序执行(通过指定
needs
关键字)。每个任务都有一个唯一的 ID。 -
Step (步骤): 一个任务由一系列步骤组成。步骤是任务中最小的执行单元。一个步骤可以是一个 Action,也可以是一个 shell 命令。步骤按照在 YAML 文件中定义的顺序依次执行。如果任何一个步骤执行失败,整个任务通常会被标记为失败(除非配置了
if
条件或continue-on-error
)。 -
Action (动作): Action 是 GitHub Actions 平台中可复用的自动化单元。它可以是一个简单的脚本,也可以是一个复杂的程序。Action 可以执行特定的任务,比如检出代码(
actions/checkout
)、设置特定环境(actions/setup-node
)、运行 Docker 容器等。Action 可以由 GitHub 官方提供、社区共享(在 Marketplace 上)或由你自己创建。使用 Action 可以大大简化工作流的编写。 -
Runner (运行器): Runner 是执行工作流任务的环境。它可以是 GitHub 托管的虚拟机,也可以是你自己搭建的服务器(自托管运行器)。
- GitHub 托管运行器: GitHub 提供了一系列的虚拟机镜像,预装了许多常用软件和工具。你只需要在工作流中指定
runs-on
关键字即可使用。这些运行器每次运行任务时都会启动一个全新的、干净的环境,并在任务结束后销毁。支持的操作系统包括 Ubuntu Linux、Windows 和 macOS。这是最常用和方便的方式。 - 自托管运行器: 如果你有特定的硬件或网络需求,或者想节省 GitHub 托管运行器的费用,可以在自己的服务器上安装并配置一个自托管运行器。
- GitHub 托管运行器: GitHub 提供了一系列的虚拟机镜像,预装了许多常用软件和工具。你只需要在工作流中指定
这六个概念构成了 GitHub Actions 的基础框架。理解它们之间的关系是编写工作流的关键:一个 Workflow 由一个 Event 触发,包含一个或多个 Job,每个 Job 在一个 Runner 上运行,由一系列 Step 组成,而 Step 可以是运行命令行或调用一个可复用的 Action。
3. 环境准备:你的第一个 GitHub 仓库
要开始使用 GitHub Actions,你需要一个 GitHub 账号和一个 GitHub 仓库。
- 如果你还没有 GitHub 账号,请访问 github.com 注册一个。
- 登录你的 GitHub 账号。
- 创建一个新的仓库。你可以创建一个全新的空仓库,或者 Fork 一个现有的项目来练习。为了教程的方便,创建一个新的空仓库是最直接的方式。
- 点击页面右上角的 “+” 号,选择 “New repository”。
- 输入仓库名称(例如
my-actions-tutorial
)。 - 选择仓库的可见性(Public 或 Private)。
- 可以选择添加 README 文件或
.gitignore
。 - 点击 “Create repository”。
现在,你拥有了一个可以用来实践 GitHub Actions 的仓库。
4. 手把手创建你的第一个 Workflow
好了,理论知识储备完毕,我们来动手实践!我们的第一个目标是创建一个简单的 Workflow,当代码被推送到仓库时,它会自动运行一个简单的 shell 命令,比如打印一句问候语。
步骤 1:进入你的 GitHub 仓库并创建工作流文件
- 打开你在上一步创建的仓库页面。
- 在仓库文件列表上方,找到并点击 “Actions” 标签页。
- 如果你是第一次进入 Actions 页面,GitHub 会提供一些流行的 Workflow 模板供你选择。你可以滚动到底部,选择 “set up a workflow yourself”(设置一个你自己的工作流),或者点击页面上的相应按钮。这将引导你创建一个新的工作流文件。
步骤 2:编写 YAML 工作流文件
点击 “set up a workflow yourself” 后,GitHub 会自动为你创建一个名为 main.yml
(文件名可更改,但后缀必须是 .yml
或 .yaml
)的文件,并将其放置在 .github/workflows/
目录下。这个目录是 GitHub Actions 工作流文件的唯一存放位置。
编辑器中会显示一个基本的 YAML 模板。我们将修改它来编写我们的第一个工作流。
清空默认内容,输入以下 YAML 代码:
“`yaml
name: My First Workflow
on: [push]
jobs:
greet_the_world:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Say Hello
run: echo "Hello, GitHub Actions from ${{ github.repository }}!"
- name: List files
run: ls -l
“`
理解基础 YAML 结构
让我们逐行解析上面这段 YAML 代码:
-
name: My First Workflow
: 定义了工作流的名称。这个名称会显示在 GitHub Actions 的界面中,方便你识别不同的工作流。这是一个可选字段,但强烈建议添加。 -
on: [push]
: 定义了触发这个工作流运行的事件。这里的[push]
表示当有代码被推送到仓库中的任何分支时,工作流都会被触发。你可以指定特定的分支,例如on: push: branches: [main, develop]
。使用方括号[]
表示这是一个列表,你可以列出多个触发事件。 -
jobs:
: 这是一个必需的关键字,表示工作流中包含的任务集合。在其下方缩进的部分定义了所有的任务。 -
greet_the_world:
: 定义了一个任务(Job)。greet_the_world
是这个任务的唯一 ID。你可以自定义任务 ID,但必须是唯一的,并且遵循 YAML 键名规则(通常是小写字母、数字和下划线)。 -
runs-on: ubuntu-latest
: 指定了运行这个任务的运行器环境。ubuntu-latest
是 GitHub 托管的 Ubuntu Linux 最新版本运行器。你也可以使用windows-latest
或macos-latest
。 -
steps:
: 这是一个必需的关键字,定义了当前任务中需要执行的一系列步骤。其下方缩进的部分是一个列表,每个列表项(以-
开头)代表一个步骤。 -
- name: Checkout code
: 定义了第一个步骤。name
是步骤的名称,同样是可选但推荐添加,用于在日志中标识步骤。 -
uses: actions/checkout@v4
: 这是第一个步骤的具体执行内容。uses
关键字表示这个步骤将使用一个预定义的 Action。actions/checkout@v4
是一个由 GitHub 官方提供的 Action,它的作用是将你的仓库代码克隆到运行器环境中,以便后续的步骤可以访问代码文件。@v4
表示使用这个 Action 的第 4 个主要版本。固定版本号是最佳实践,可以避免因 Action 更新带来的潜在兼容性问题。 -
- name: Say Hello
: 定义了第二个步骤的名称。 -
run: echo "Hello, GitHub Actions from ${{ github.repository }}!"
: 这是第二个步骤的具体执行内容。run
关键字表示这个步骤将执行一个 shell 命令。echo "..."
是一个标准的 Linux shell 命令,用于打印字符串。$ {{ github.repository }}
是一个 GitHub Actions 的表达式,用于访问上下文信息。github.repository
会返回仓库的名称(例如your_username/your_repository_name
)。这个表达式会在运行时被替换为实际的值。 -
- name: List files
: 定义了第三个步骤的名称。 -
run: ls -l
: 执行另一个 shell 命令ls -l
,用于列出当前工作目录下的文件和文件夹,验证代码是否成功检出。
YAML 注意事项:
- 缩进至关重要! YAML 使用缩进来表示层级关系。每个层级必须使用相同数量的空格进行缩进。通常使用 2 个空格作为一级缩进。绝对不要使用 Tab 键! 混合使用 Tab 和空格会导致解析错误。
- 列表项以
-
(横杠加空格)开头。
步骤 3:提交工作流文件
- 在 GitHub 的在线编辑器界面,点击右上角的 “Start commit” 按钮。
- 输入提交信息,例如 “feat: add my first github actions workflow”。
- 选择直接提交到
main
分支(或你的默认分支)。 - 点击 “Commit changes” 按钮。
步骤 4:查看工作流运行结果
提交代码后,因为我们在 on
字段中设置了 push
事件触发,GitHub 会自动检测到代码推送,并开始运行你的工作流。
- 提交完成后,页面会跳转回仓库的文件列表。
- 点击仓库顶部的 “Actions” 标签页。
- 在左侧导航栏中,你会看到你的工作流名称 “My First Workflow”。点击它。
- 在右侧的主区域,你会看到工作流运行的历史记录。顶部最新的一条通常就是你刚刚触发的运行,状态可能是 “queued”(排队中)、”in progress”(进行中)或 “success”/”failure”(成功/失败)。
- 点击最新的运行记录(通常是提交信息作为标题)。
- 进入运行详情页,你会看到你的任务列表。我们只有一个任务,ID 是
greet_the_world
。点击它。 - 进入任务详情页,你会看到任务中所有步骤的执行列表。点击每个步骤,可以展开查看该步骤的详细日志输出。
- 点击 “Say Hello” 步骤,你应该能在日志中看到输出
Hello, GitHub Actions from your_username/your_repository_name!
。 - 点击 “List files” 步骤,你应该能看到类似
drwxr-xr-x 3 runner docker 4096 Mar 18 08:00 your-repository-name
的输出,证明代码已被检出。
恭喜你!你已经成功创建并运行了你的第一个 GitHub Actions 工作流。这标志着你迈出了自动化构建的第一步。
5. 进阶示例:构建和测试一个简单的项目
仅仅运行一个简单的 echo
命令显然不足以体现 GitHub Actions 的强大。接下来,我们将创建一个更接近实际用途的工作流:当有新的代码提交或 Pull Request 时,自动设置 Node.js 环境,安装项目依赖,并运行构建和测试命令。
我们将创建一个简单的 Node.js 项目作为示例。如果你不熟悉 Node.js,不必担心,重点在于理解工作流的结构和如何使用 Action。
步骤 1:在仓库中添加项目文件
在你的 GitHub 仓库根目录(可以通过 GitHub 网页界面直接创建文件),创建以下文件:
-
package.json
: Node.js 项目的配置文件,包含项目信息和依赖。json
{
"name": "my-simple-app",
"version": "1.0.0",
"description": "A simple app for GH Actions tutorial",
"main": "index.js",
"scripts": {
"build": "echo 'Building...' && exit 0",
"test": "echo 'Testing...' && exit 0"
},
"keywords": [],
"author": "",
"license": "ISC"
}
* 这里的build
和test
脚本都非常简单,只是打印一条信息并以成功(exit 0
)退出。在实际项目中,你会在这里运行真正的构建命令(如webpack
,babel
)和测试命令(如jest
,mocha
)。 -
index.js
: 一个简单的 JavaScript 文件。javascript
console.log("App started.");
* 这个文件在我们的示例中并没有被构建或测试脚本真正用到,但它可以让仓库看起来更像一个实际的代码项目。
提交这两个文件到仓库。
步骤 2:创建新的工作流文件
回到仓库的 “Actions” 标签页,点击 “New workflow”。选择 “set up a workflow yourself”。创建一个名为 node-ci.yml
的文件。
输入以下 YAML 代码:
“`yaml
name: Node.js CI
on:
push:
branches: [ “main” ] # 当代码推送到 main 分支时触发
pull_request:
branches: [ “main” ] # 当 Pull Request 目标是 main 分支时触发
jobs:
build_and_test:
runs-on: ubuntu-latest # 在最新的 Ubuntu 环境下运行
steps:
- name: Checkout code # 步骤1: 检出代码
uses: actions/checkout@v4 # 使用官方的 checkout action
- name: Setup Node.js environment # 步骤2: 设置 Node.js 环境
uses: actions/setup-node@v4 # 使用官方的 setup-node action
with:
node-version: '20.x' # 指定 Node.js 版本,这里使用 20.x 的最新版本
- name: Install dependencies # 步骤3: 安装项目依赖
run: npm install # 执行 npm install 命令
- name: Run build script # 步骤4: 运行构建脚本
run: npm run build # 执行 package.json 中定义的 build 脚本
- name: Run test script # 步骤5: 运行测试脚本
run: npm test # 执行 package.json 中定义的 test 脚本
“`
理解这个工作流
name: Node.js CI
: 工作流名称。on: ...
: 触发事件。这里我们设置了两个触发事件:push: branches: [ "main" ]
: 当有代码直接推送到main
分支时触发。pull_request: branches: [ "main" ]
: 当有 Pull Request 被创建或更新,并且其目标分支是main
时触发。这对于在合并前检查代码非常有用。
jobs: ...
: 任务集合。我们定义了一个任务build_and_test
。runs-on: ubuntu-latest
: 任务运行环境。steps: ...
: 步骤集合。Checkout code
: 依然是使用actions/checkout@v4
检出代码。这是几乎所有需要访问仓库代码的工作流的第一个步骤。Setup Node.js environment
: 这是新引入的步骤,使用actions/setup-node@v4
Action。这个 Action 的作用是在运行器环境中安装指定版本的 Node.js 和 npm(或 yarn/pnpm)。with:
: 用于向 Action 传递参数。node-version: '20.x'
指定了要安装的 Node.js 版本。你可以指定精确版本(如'20.10.0'
),或者版本范围(如'18.x'
,'20.x'
)。
Install dependencies
: 使用run: npm install
执行安装依赖的 shell 命令。这是标准的 Node.js 项目流程。Run build script
: 使用run: npm run build
执行在package.json
中定义的build
脚本。Run test script
: 使用run: npm test
执行在package.json
中定义的test
脚本。
步骤 3:提交工作流文件
像之前一样,提交 node-ci.yml
文件到你的仓库。
步骤 4:查看工作流运行结果
提交后,GitHub Actions 会再次自动触发这个新的工作流(因为有 push
到 main
分支的事件)。
- 前往仓库的 “Actions” 标签页。
- 在左侧选择 “Node.js CI” 工作流。
- 点击最新的运行记录。
- 点击
build_and_test
任务。 - 展开每个步骤查看日志。你会看到 Node.js 环境被设置、依赖被安装、以及 “Building…” 和 “Testing…” 的输出。
这次,你的工作流执行了一个更实际的任务流程。这为你后续构建、测试和部署更复杂的项目奠定了基础。
6. 深入理解 YAML 语法与常用指令
我们已经接触了一些常用的 YAML 关键字和指令,这里我们更系统地回顾和补充一些重要的用法。
工作流文件的基本结构如下:
“`yaml
name: <工作流名称>
on: <触发事件或事件列表>
jobs:
<任务ID>:
name: <任务名称> # 可选
runs-on: <运行器类型>
steps:
– name: <步骤名称> # 可选
uses:
with: # 向 Action 传递参数
<参数名>: <参数值>
– name: <步骤名称> # 可选
run:
env: # 为当前步骤设置环境变量
<变量名>: <变量值>
– name: <步骤名称> # 可选
if: <条件表达式> # 条件判断,决定是否执行该步骤
…
needs: [<其他任务ID>] # 可选,指定该任务依赖于哪些其他任务先完成
<另一个任务ID>:
…
“`
常用指令详解:
-
name
:- 用于工作流 (
name: <工作流名称>
) 或步骤 (name: <步骤名称>
)。 - 提供了人类可读的标识符,方便在 GitHub UI 中查看。
- 用于工作流 (
-
on
:- 定义工作流的触发事件。
- 可以是单个事件字符串(如
push
),也可以是事件列表(如[push, pull_request]
)。 - 可以配置特定事件的详细选项,例如:
yaml
on:
push:
branches:
- main # 仅当推送到 main 分支时
- 'releases/**' # 支持 glob 模式匹配分支
tags:
- v1.* # 仅当创建 v1 开头的 tag 时
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * *' # 每天午夜定时运行 (使用 UTC 时间)
workflow_dispatch: # 允许手动触发
release:
types: [published] # 仅当发布新的 Release 时
-
jobs
:- 包含一个或多个任务的映射。每个键是任务的 ID。
- 任务 ID 必须唯一。
-
<任务ID>
:- 定义一个具体的任务。
- 任务 ID 用于在
needs
字段中引用。
-
runs-on
:- 指定任务将在哪种类型的运行器上运行。
- 常用的 GitHub 托管运行器:
ubuntu-latest
,windows-latest
,macos-latest
。也可以指定更具体的版本,如ubuntu-20.04
。 - 如果是自托管运行器,需要指定其配置的标签。
-
steps
:- 一个列表,定义了任务中按顺序执行的步骤。
-
uses
:- 用于引用一个 Action。
- 格式通常是
owner/action-name@version
。例如actions/checkout@v4
。 - Action 可以是来自 GitHub、Marketplace 或你自己的仓库。
-
run
:- 用于执行命令行脚本。
- 默认在 Linux 上是
bash
,Windows 上是powershell
。 - 可以执行单行命令,也可以执行多行脚本(使用
|
符号)。
“`yaml- name: Run multi-line script
run: |
echo “First line”
echo “Second line”
npm –version
“`
- name: Run multi-line script
-
with
:- 用于向
uses
引用的 Action 或run
步骤传递参数。 - 对于 Action (
uses
),with
下的键值对会作为 Action 的输入。具体的输入参数取决于 Action 本身的定义,需要查阅其文档。例如,actions/setup-node
的node-version
参数。 - 对于
run
步骤,with
可以用来设置工作目录或其他运行选项,但这并不常用,更常见的是使用env
。
- 用于向
-
env
:- 设置环境变量。
- 可以在工作流级别、任务级别或步骤级别设置。作用域越小,优先级越高。
- 在
run
步骤中,可以通过$VAR_NAME
(Linux/macOS) 或$env:VAR_NAME
(Windows PowerShell) 访问。
yaml
jobs:
my_job:
runs-on: ubuntu-latest
env: # 任务级别的环境变量
MY_TASK_VAR: 'task_value'
steps:
- name: Step with env
env: # 步骤级别的环境变量
MY_STEP_VAR: 'step_value'
run: |
echo "Task var: $MY_TASK_VAR" # 可以访问任务级别的变量
echo "Step var: $MY_STEP_VAR" # 可以访问步骤级别的变量
# echo "Workflow var: $MY_WORKFLOW_VAR" # 不能直接访问工作流级别的变量,需要特殊语法
-
if
:- 条件表达式,用于决定是否执行某个任务或步骤。
- 表达式通常包含 GitHub Actions 的上下文信息(如
github.event_name
,github.ref
,runner.os
等)、状态检查函数(如success()
,failure()
,cancelled()
,always()
)以及其他比较操作。 - 例如:
“`yaml- name: Deploy only on main branch success
if: success() && github.ref == ‘refs/heads/main’
run: echo “Deploying…”
``
main
这个步骤只有在前一个步骤成功并且当前分支是时才会执行。
success()是一个函数,表示前面的所有步骤是否都成功了(对于 Job 级别的
if则是指前面的所有 Job 是否都成功,如果配置了
needs`)。
- name: Deploy only on main branch success
-
needs
:- 用于指定任务的依赖关系。一个任务只有在其
needs
列出的所有任务都成功完成后才会开始执行。 - 如果被依赖的任务失败,当前任务默认会被跳过。
- 例如:
yaml
jobs:
build:
# ... build steps ...
test:
needs: [build] # test 任务依赖于 build 任务
# ... test steps ...
deploy:
needs: [test] # deploy 任务依赖于 test 任务
# ... deploy steps ...
这样就形成了一个串行执行的流水线:build -> test -> deploy。
- 用于指定任务的依赖关系。一个任务只有在其
掌握这些常用的指令和 YAML 语法,你就能开始编写各种复杂的自动化工作流了。
7. 探索 GitHub Actions 的高级特性(快速了解)
GitHub Actions 提供了许多高级特性,可以满足更复杂的自动化需求。这里快速介绍一些重要的:
-
Secrets (机密信息): 用于存储敏感信息,如 API 密钥、密码、云服务凭证等。你可以在仓库设置中配置 Secrets,然后在工作流中通过
secrets.MY_SECRET_NAME
的方式引用它们。Secrets 在日志中会被自动屏蔽,不会泄露。
“`yaml- name: Use a secret
run: echo “Using API key: ${{ secrets.API_KEY }}”
# 注意:尽管 secrets 在日志中被屏蔽,但如果在 echo 后面直接输出,仍然可能短暂显示,
# 更好的做法是将 secret 作为环境变量传递给脚本或命令 - name: Pass secret as env var
env:
API_TOKEN: ${{ secrets.MY_API_TOKEN }}
run: |
echo “API token is passed as env var”
# 你的脚本或命令可以使用 $API_TOKEN
“`
- name: Use a secret
-
Artifacts (构建产物): 允许你在工作流运行结束后保存生成的产物,如编译后的二进制文件、打包的应用程序、测试报告、日志文件等。可以使用
actions/upload-artifact
Action 上传,使用actions/download-artifact
Action 下载。
“`yaml- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: my-app-build
path: ./dist # 指定要上传的目录或文件
“`
- name: Upload build artifact
-
Matrix Strategy (矩阵策略): 允许你在一个 Job 中定义一个参数矩阵,GitHub Actions 会为矩阵中的每个参数组合创建一个独立的 Job 运行。这对于在多种操作系统、多种软件版本或不同配置下并行测试代码非常有用。
yaml
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [18.x, 20.x]
steps:
- uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
这个例子会创建 4 个 Job:Ubuntu/Node 18, Ubuntu/Node 20, Windows/Node 18, Windows/Node 20。 -
Manual Triggers (
workflow_dispatch
): 前面提到过,通过在on
中包含workflow_dispatch:
,你可以在 GitHub UI 中手动触发工作流运行。你还可以定义输入参数,在手动触发时填写。
yaml
on:
workflow_dispatch:
inputs:
version:
description: 'Release version to deploy'
required: true
default: '1.0.0'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Get version
run: echo "Deploying version ${{ github.event.inputs.version }}" -
Scheduled Events (
schedule
): 使用标准的 Cron 语法定时触发工作流,例如每天执行一次代码清理、定时备份等。
yaml
on:
schedule:
- cron: '0 0 * * *' # 每天午夜 UTC 时间触发 -
Reusable Workflows (可复用工作流): 如果你发现多个工作流中有很多重复的任务或步骤,可以将这些通用部分提取出来作为一个独立的可复用工作流。其他工作流可以通过
uses: owner/repository/.github/workflows/reusable-workflow.yml@ref
的方式来调用它,实现 DRY (Don’t Repeat Yourself) 原则。 -
GitHub Marketplace: 这是一个发现、使用和贡献 Action 的平台。你可以在这里找到大量由 GitHub、第三方服务提供商或社区成员创建的 Action,涵盖了从各种语言的构建、测试到部署到各种云平台的服务。使用 Marketplace 中的 Action 可以极大地加速工作流的开发。
这些高级特性让 GitHub Actions 能够处理更广泛和更复杂的自动化场景。
8. 故障排除与调试
在编写工作流的过程中,遇到错误是很正常的。GitHub Actions 提供了详细的日志来帮助你诊断问题。
-
查看工作流运行日志: 这是最重要的调试手段。在 “Actions” 标签页,点击失败的运行记录,然后点击失败的任务或步骤。展开的日志会显示具体的错误信息,包括命令的输出、错误堆栈等。仔细阅读日志,通常能找到问题的根源。
-
常见的错误及解决方法:
- YAML 语法错误: 通常是缩进问题。GitHub 的在线编辑器或一些 IDE 插件会提示 YAML 语法错误。检查你的缩进是否一致使用了空格(而不是 Tab)。
command not found
: 运行器环境中没有安装你尝试执行的命令。确认你是否使用了正确的setup-*
Action 来安装必要的工具链(如setup-node
,setup-python
,setup-go
等)。或者你的命令路径不正确。- 文件或目录找不到: 确认你是否在
run
步骤之前使用了actions/checkout
Action 来检出代码。检查文件路径是否正确,注意大小写。 - 权限问题: 工作流在运行器环境中以一个特定的用户身份运行。确保你的脚本或命令有足够的权限访问文件或目录。
- Secret 引用错误: 确保你在工作流中引用的 Secret 名称与你在仓库设置中配置的完全一致,并且引用语法是正确的
${{ secrets.MY_SECRET_NAME }}
。检查 Secret 是否已经被正确添加到仓库的 Secrets 设置中。 - Action 版本问题: 尝试使用 Action 的不同版本,有时新版本引入了兼容性问题,或者你正在使用的版本有已知 bug。
-
如何测试工作流:
- 小步快跑: 不要一次性写一个非常复杂的工作流。先从简单的触发和步骤开始,逐步增加功能。
- 使用不同的触发事件:
push
到特定分支: 可以创建一个专门用于测试工作流的分支(例如actions-test
),只将工作流的修改提交到这个分支进行测试,避免影响主分支或其他开发者。workflow_dispatch
: 添加手动触发,这样你可以在不提交代码的情况下反复运行工作流进行调试。结合inputs
可以测试不同参数对工作流的影响。
- 在本地模拟运行: 有一些第三方工具(如
act
)可以尝试在本地模拟 GitHub Actions 环境运行工作流,但这并不能完全替代在 GitHub 上的实际运行,因为本地环境与 GitHub 托管运行器环境可能存在差异。 - 使用
dump
步骤查看上下文: 在工作流中添加一个步骤,打印出 GitHub 上下文对象,这对于理解事件数据、运行器信息等非常有用。
“`yaml- name: Dump GitHub context
run: echo “${{ toJSON(github) }}”
“`
注意:JSON 输出中可能包含敏感信息,谨慎在公共仓库中使用或仔细检查日志。
- name: Dump GitHub context
通过以上方法,你可以有效地诊断和解决工作流中遇到的各种问题。
9. 最佳实践
为了编写高效、可维护且健壮的 GitHub Actions 工作流,遵循一些最佳实践非常重要:
- 保持工作流文件简洁: 一个工作流文件只关注一个主要目的(例如 CI, CD, Linting)。如果一个文件变得非常庞大和复杂,考虑拆分成多个工作流或使用可复用工作流。
- 使用明确的名称: 给工作流、任务和步骤起一个有意义的名称,方便快速了解其作用,尤其是在查看运行历史和日志时。
- 固定 Action 版本: 始终使用 Action 的具体版本(例如
@v4
或@v4.0.0
),而不是使用@latest
。这可以确保你的工作流不会因为 Action 的不兼容更新而突然中断。定期检查并更新 Action 版本。 - 善用 Secrets: 任何敏感信息(API 密钥、密码、私钥等)都应该存储在 Secrets 中,绝对不要硬编码到工作流文件里。
- 从小处着手,逐步完善: 开始时,只实现最核心的功能。例如,先实现代码检出和简单的构建命令,确认工作流能够成功运行,然后再逐步添加测试、部署等步骤。
- 使用
if
条件控制步骤执行: 根据需要使用if
条件来跳过或执行特定步骤,例如只在main
分支上执行部署,或者只在 Pull Request 源分支不是main
时运行特定的代码检查。 - 优化构建速度: 对于需要安装依赖的项目,考虑使用缓存 Action(如
actions/cache
)来缓存依赖项,减少重复安装时间,从而加快工作流运行速度。 - 利用
needs
管理任务依赖: 合理设置任务的依赖关系,确保任务按正确的顺序执行,并控制并行度。 - 测试你的工作流修改: 在合并到主分支之前,在一个测试分支上提交工作流的修改并验证其是否按预期工作。
- 查阅官方文档和社区资源: GitHub Actions 的文档非常详细,涵盖了所有功能和最新的更新。遇到问题时,官方文档是最佳参考。同时,积极参与社区讨论,学习其他人的经验和技巧。
遵循这些最佳实践,可以帮助你构建更可靠、更易于管理和优化的自动化流水线。
10. 总结与展望
恭喜你!通过本教程的学习,你已经了解了 GitHub Actions 的核心概念,掌握了如何创建和运行一个基本的工作流,并触及了一些进阶特性。从简单的命令执行到实际的项目构建和测试,你已经具备了利用 GitHub Actions 开始自动化你的开发流程的能力。
GitHub Actions 是一个功能强大且不断发展的平台。本教程只是一个起点。接下来,你可以:
- 尝试自动化你的代码格式化和 Linting 检查。
- 配置自动化的代码部署到你的服务器或云平台(如 AWS, Azure, GCP, Netlify, Vercel 等)。
- 探索 GitHub Marketplace 中更多有趣的 Action,比如发送通知、集成第三方服务等。
- 学习如何创建自己的 Action。
- 深入研究矩阵策略、缓存等高级特性,优化你的工作流。
自动化是提升效率、保障质量的利器。掌握 GitHub Actions,将为你和你的团队带来巨大的便利。不断实践,不断探索,让自动化成为你工作流程中的一部分吧!
希望这篇教程能帮助你顺利迈出 GitHub Actions 的第一步。如果在学习过程中遇到任何问题,不要犹豫查阅官方文档或在社区寻求帮助。
祝你自动化愉快!