惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

A
Arctic Wolf
T
Tenable Blog
T
Troy Hunt's Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Privacy & Cybersecurity Law Blog
NISL@THU
NISL@THU
Application and Cybersecurity Blog
Application and Cybersecurity Blog
H
Hacker News: Front Page
S
Secure Thoughts
AWS News Blog
AWS News Blog
L
LINUX DO - 最新话题
D
Darknet – Hacking Tools, Hacker News & Cyber Security
M
MIT News - Artificial intelligence
T
Tor Project blog
S
Schneier on Security
PCI Perspectives
PCI Perspectives
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
美团技术团队
Google DeepMind News
Google DeepMind News
V
Visual Studio Blog
爱范儿
爱范儿
Google DeepMind News
Google DeepMind News
Cyberwarzone
Cyberwarzone
T
The Exploit Database - CXSecurity.com
罗磊的独立博客
T
Threat Research - Cisco Blogs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
V
V2EX
C
CXSECURITY Database RSS Feed - CXSecurity.com
Stack Overflow Blog
Stack Overflow Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
G
GRAHAM CLULEY
L
LINUX DO - 热门话题
D
Docker
J
Java Code Geeks
GbyAI
GbyAI
H
Heimdal Security Blog
The Hacker News
The Hacker News
MongoDB | Blog
MongoDB | Blog
V
Vulnerabilities – Threatpost
T
Tailwind CSS Blog
Cloudbric
Cloudbric
TaoSecurity Blog
TaoSecurity Blog
C
CERT Recently Published Vulnerability Notes
Y
Y Combinator Blog
Recorded Future
Recorded Future
Cisco Talos Blog
Cisco Talos Blog
T
Threatpost
The Register - Security
The Register - Security
Hacker News - Newest:
Hacker News - Newest: "LLM"

Ray's Blog

Ray's Blog Ray's Blog Ray's Blog Ray's Blog Ray's Blog Ray's Blog Ray's Blog Ray's Blog Ray's Blog Ray's Blog Ray's Blog Ray's Blog Ray's Blog Ray's Blog Ray's Blog Ray's Blog
Ray's Blog
i@mk1.io (Ra · 2025-12-15 · via Ray's Blog

可重用的工作流

在开发项目时,我们经常会遇到需要在多个仓库中使用相似的 CI/CD 工作流的情况。随着项目数量的增加,相同的工作流代码会不断增加,维护这些重复的工作流也会变得越来越繁琐,例如,更新某个步骤时需要在所有相关仓库中进行修改。为了解决这个问题,GitHub Actions 提供了重用工作流的功能,使我们能够将常用的工作流定义为独立的文件,并在其他工作流中引用它们,从而实现代码复用和集中管理。

在介绍如何重用工作流之前,我们先要区分两种不同的复用机制:Composite Actions 和 Reusable Workflows。简单来说:Composite Actions 是复用多个步骤,例如设置运行时、安装依赖等;而 Reusable Workflows 则是复用整个工作流,包括触发条件、作业定义等(例如构建、测试、部署等)。

方面Reusable WorkflowsComposite Actions
位置通常放置在 .github/workflows/ 目录中。通常放置在 .github/actions/ 目录中。
YAML 文件名工作流文件可以有任何名称,例如 reusable-workflow.yml操作文件必须命名为 action.yml
文件结构包含一个定义工作流的单一 YAML 文件,包含 jobssteps包含操作所在目录,包括一个 action.yml 文件,并可包含其他脚本或依赖项文件。
使用方法在其他工作流中使用 uses: <repo>/<path>@<branch>在作业步骤中使用 uses: <repo>/<action-path>@<branch>
组件可以包含多个 jobs,允许复杂的工作流。仅包含 steps;不定义 jobs
输入可以定义类型,默认值可以跟随类型变化不能定义类型,只能使用 string 作为默认值

更多区别可以参见这篇 Medium 文章 和这篇 Dev.to 文章

我们需要先进行准备工作。这里我创建一个新的 GitHub 仓库 so1ve/workflows 来存放可重用的工作流。

在常见的 CI/CD 工作流中,我们经常需要执行一些重复的任务。一个典型的例子是在执行实际的 CI/CD 任务前初始化环境,需要运行的操作包括例如检出代码库、设置 Node.js 环境、安装依赖。这里存在着明显的代码重复:

  • @actions/checkout 有不同的版本,需要在每个工作流中指定版本号,但是版本号可能会过时,而我们的检出逻辑实际上是相同的
  • @actions/setup-node 可以设置不同版本的 Node.js 环境,但是我的项目的支持目标通常是相同的,一旦 Node.js 发布了新版本,我们就需要在所有工作流中更新版本号,此外还有设置缓存等逻辑
  • 安装依赖的命令在不同项目中可能会有所不同(例如 npm installyarn installpnpm install),但是安装依赖的逻辑是相同的,区别只有包管理器

为了解决这些问题,我们可以将这些重复的步骤封装成 Composite Actions,从而实现代码复用。这样,我们只需要在需要初始化环境的地方引用这个 Composite Action 即可,此后如果需要更新逻辑只需要修改一个地方。

so1ve/workflows 仓库中创建一个新的目录 setup-js,并在该目录下创建一个 action.yml 文件。 setup-js 是一个 Composite Action,用于设置 JavaScript 项目的运行环境。action.yml 文件的内容如下:

其中:

  • inputs 定义了 Composite Action 接受的输入参数,例如 node-version 用于指定 Node.js 版本,package-manager 用于指定包管理器等。
  • runs 定义了 Composite Action 的执行逻辑,包含多个步骤,例如检出代码、安装 Node.js、安装依赖等。
    • using 必须为 composite,表示这是一个 Composite Action。
    • steps 定义了具体的执行步骤,每个步骤可以使用其他 Action,或者直接运行 shell 命令。如果是运行 shell 命令,则必须指定 shell 字段。

需要在其他工作流里使用这个 Composite Action 时,只需在作业的步骤中引用它,就像使用 @actions/checkout 那样:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Setup JS
        uses: so1ve/workflows/setup-js@main
        with:
          node-version: "22"
          package-manager: "pnpm"

接下来,我们创建一个 Reusable Workflow,用于执行常见的 CI/CD 任务,例如构建和测试项目。在 so1ve/workflows 仓库中创建一个新的工作流文件 .github/workflows/conventional-ci.yml,内容如下:

其中:

  • on.workflow_call 定义了工作流的触发方式,这里使用 workflow_call,表示这个工作流可以被其他工作流调用。我们还定义了一些输入参数,例如 node-versions 用于指定测试的 Node.js 版本,typechecklintbuildtest 分别用于指定类型检查、代码检查、构建和测试的命令。
  • jobs 定义了工作流的作业,这里包含三个作业: linttypechecktest

注意,这里我们使用了之前创建的 Composite Action so1ve/workflows/setup-js@v1 来初始化 JavaScript 环境。

要在其他工作流中使用这个 Reusable Workflow,也是只需使用 uses 关键字引用它,并传递必要的输入参数。例如,在一个新的工作流文件 .github/workflows/ci.yml 中,我们可以这样使用:

.github/workflows/ci.yml

name: CI

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  conventional-ci:
    uses: so1ve/workflows/.github/workflows/conventional-ci.yml@main
    with:
      node-versions: "22,24"
      skip-typecheck: true
      build-for-lint: true

在使用 Reusable Workflows 和 Composite Actions 时,建议使用版本标签(例如 v1.0.0)而不是分支名称(例如 main)。这样可以确保工作流的稳定性,避免因为主分支的变更导致工作流出现问题。

可以手动打标签,也可以使用其他工具。我使用的是 bumpp

同时还可以把代码推送到特定的分支上,例如 v1, v2,然后在工作流中引用这些分支。

git update-ref refs/heads/v1 refs/heads/main && git push origin v1 --force

然后在工作流中引用:

uses: so1ve/workflows/.github/workflows/conventional-ci.yml@v1