GitHub Actions 教程:手把手带你入门 – wiki基地


GitHub Actions 教程:手把手带你入门

自动化是现代软件开发流程中不可或缺的一部分。它可以帮助我们自动执行重复性的任务,如构建代码、运行测试、部署应用等,从而提高效率、减少错误并加速交付。在众多自动化工具中,GitHub Actions 作为 GitHub 原生集成的 CI/CD(持续集成/持续部署)服务,因其便捷性、灵活性和与 GitHub 生态系统的紧密结合而受到广泛欢迎。

本教程将带你从零开始,深入理解 GitHub Actions 的核心概念,并通过实际案例学习如何创建和运行你的第一个自动化工作流。无论你是一名开发者、运维工程师,还是对自动化充满好奇的新手,都能从中获益。

预计阅读时间: 约 30-40 分钟
目标读者: 对 GitHub Actions 零基础或了解不多的用户

目录

  1. 什么是 GitHub Actions?为什么使用它?
    • CI/CD 的概念
    • GitHub Actions 的定位与优势
  2. 核心概念解析
    • Workflow(工作流)
    • Event(事件)
    • Job(任务)
    • Step(步骤)
    • Action(动作)
    • Runner(运行器)
  3. 环境准备:你的第一个 GitHub 仓库
  4. 手把手创建你的第一个 Workflow
    • 创建 .github/workflows 目录
    • 编写 YAML 工作流文件
    • 理解基础 YAML 结构
    • 实战:运行一个简单的命令
    • 提交并查看运行结果
  5. 进阶示例:构建和测试一个简单的项目
    • 创建一个简单的 Node.js 项目
    • 编写构建和测试的工作流
    • 使用 Marketplace 中的 Action
    • 设置 Node.js 环境
    • 安装依赖
    • 运行构建和测试命令
    • 理解 on: [push, pull_request]
  6. 深入理解 YAML 语法与常用指令
    • name:工作流名称
    • on:触发事件
    • jobs:任务集合
    • runs-on:指定运行器
    • steps:步骤集合
    • uses:引用一个 Action
    • run:执行命令行命令
    • with:向 Action 或步骤传递参数
    • env:设置环境变量
    • if:条件判断
  7. 探索 GitHub Actions 的高级特性(快速了解)
    • Secrets:处理敏感信息
    • Artifacts:保存构建产物
    • Matrix Strategy:构建矩阵
    • Manual Triggers:手动触发
    • Scheduled Events:定时触发
    • Reusable Workflows:可复用工作流
    • GitHub Marketplace:发现更多 Action
  8. 故障排除与调试
    • 查看工作流运行日志
    • 常见的错误及解决方法
    • 如何测试工作流
  9. 最佳实践
    • 保持工作流文件简洁
    • 使用明确的名称
    • 固定 Action 版本
    • 善用 Secrets
    • 从小处着手,逐步完善
  10. 总结与展望

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 Actions 的基础框架。理解它们之间的关系是编写工作流的关键:一个 Workflow 由一个 Event 触发,包含一个或多个 Job,每个 Job 在一个 Runner 上运行,由一系列 Step 组成,而 Step 可以是运行命令行或调用一个可复用的 Action

3. 环境准备:你的第一个 GitHub 仓库

要开始使用 GitHub Actions,你需要一个 GitHub 账号和一个 GitHub 仓库。

  1. 如果你还没有 GitHub 账号,请访问 github.com 注册一个。
  2. 登录你的 GitHub 账号。
  3. 创建一个新的仓库。你可以创建一个全新的空仓库,或者 Fork 一个现有的项目来练习。为了教程的方便,创建一个新的空仓库是最直接的方式。
    • 点击页面右上角的 “+” 号,选择 “New repository”。
    • 输入仓库名称(例如 my-actions-tutorial)。
    • 选择仓库的可见性(Public 或 Private)。
    • 可以选择添加 README 文件或 .gitignore
    • 点击 “Create repository”。

现在,你拥有了一个可以用来实践 GitHub Actions 的仓库。

4. 手把手创建你的第一个 Workflow

好了,理论知识储备完毕,我们来动手实践!我们的第一个目标是创建一个简单的 Workflow,当代码被推送到仓库时,它会自动运行一个简单的 shell 命令,比如打印一句问候语。

步骤 1:进入你的 GitHub 仓库并创建工作流文件

  1. 打开你在上一步创建的仓库页面。
  2. 在仓库文件列表上方,找到并点击 “Actions” 标签页。
  3. 如果你是第一次进入 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-latestmacos-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:提交工作流文件

  1. 在 GitHub 的在线编辑器界面,点击右上角的 “Start commit” 按钮。
  2. 输入提交信息,例如 “feat: add my first github actions workflow”。
  3. 选择直接提交到 main 分支(或你的默认分支)。
  4. 点击 “Commit changes” 按钮。

步骤 4:查看工作流运行结果

提交代码后,因为我们在 on 字段中设置了 push 事件触发,GitHub 会自动检测到代码推送,并开始运行你的工作流。

  1. 提交完成后,页面会跳转回仓库的文件列表。
  2. 点击仓库顶部的 “Actions” 标签页。
  3. 在左侧导航栏中,你会看到你的工作流名称 “My First Workflow”。点击它。
  4. 在右侧的主区域,你会看到工作流运行的历史记录。顶部最新的一条通常就是你刚刚触发的运行,状态可能是 “queued”(排队中)、”in progress”(进行中)或 “success”/”failure”(成功/失败)。
  5. 点击最新的运行记录(通常是提交信息作为标题)。
  6. 进入运行详情页,你会看到你的任务列表。我们只有一个任务,ID 是 greet_the_world。点击它。
  7. 进入任务详情页,你会看到任务中所有步骤的执行列表。点击每个步骤,可以展开查看该步骤的详细日志输出。
  8. 点击 “Say Hello” 步骤,你应该能在日志中看到输出 Hello, GitHub Actions from your_username/your_repository_name!
  9. 点击 “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"
    }

    * 这里的 buildtest 脚本都非常简单,只是打印一条信息并以成功(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 会再次自动触发这个新的工作流(因为有 pushmain 分支的事件)。

  1. 前往仓库的 “Actions” 标签页。
  2. 在左侧选择 “Node.js CI” 工作流。
  3. 点击最新的运行记录。
  4. 点击 build_and_test 任务。
  5. 展开每个步骤查看日志。你会看到 Node.js 环境被设置、依赖被安装、以及 “Building…” 和 “Testing…” 的输出。

这次,你的工作流执行了一个更实际的任务流程。这为你后续构建、测试和部署更复杂的项目奠定了基础。

6. 深入理解 YAML 语法与常用指令

我们已经接触了一些常用的 YAML 关键字和指令,这里我们更系统地回顾和补充一些重要的用法。

工作流文件的基本结构如下:

“`yaml
name: <工作流名称>

on: <触发事件或事件列表>

jobs:
<任务ID>:
name: <任务名称> # 可选
runs-on: <运行器类型>
steps:
– name: <步骤名称> # 可选
uses: # 使用 Action
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
        “`
  • with:

    • 用于向 uses 引用的 Action 或 run 步骤传递参数。
    • 对于 Action (uses),with 下的键值对会作为 Action 的输入。具体的输入参数取决于 Action 本身的定义,需要查阅其文档。例如,actions/setup-nodenode-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`)。
  • 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
      “`
  • 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 # 指定要上传的目录或文件
      “`
  • 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 提供了详细的日志来帮助你诊断问题。

  1. 查看工作流运行日志: 这是最重要的调试手段。在 “Actions” 标签页,点击失败的运行记录,然后点击失败的任务或步骤。展开的日志会显示具体的错误信息,包括命令的输出、错误堆栈等。仔细阅读日志,通常能找到问题的根源。

  2. 常见的错误及解决方法:

    • 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。
  3. 如何测试工作流:

    • 小步快跑: 不要一次性写一个非常复杂的工作流。先从简单的触发和步骤开始,逐步增加功能。
    • 使用不同的触发事件:
      • push 到特定分支: 可以创建一个专门用于测试工作流的分支(例如 actions-test),只将工作流的修改提交到这个分支进行测试,避免影响主分支或其他开发者。
      • workflow_dispatch 添加手动触发,这样你可以在不提交代码的情况下反复运行工作流进行调试。结合 inputs 可以测试不同参数对工作流的影响。
    • 在本地模拟运行: 有一些第三方工具(如 act)可以尝试在本地模拟 GitHub Actions 环境运行工作流,但这并不能完全替代在 GitHub 上的实际运行,因为本地环境与 GitHub 托管运行器环境可能存在差异。
    • 使用 dump 步骤查看上下文: 在工作流中添加一个步骤,打印出 GitHub 上下文对象,这对于理解事件数据、运行器信息等非常有用。
      “`yaml

      • name: Dump GitHub context
        run: echo “${{ toJSON(github) }}”
        “`
        注意:JSON 输出中可能包含敏感信息,谨慎在公共仓库中使用或仔细检查日志。

通过以上方法,你可以有效地诊断和解决工作流中遇到的各种问题。

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 的第一步。如果在学习过程中遇到任何问题,不要犹豫查阅官方文档或在社区寻求帮助。

祝你自动化愉快!

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部