编写 JavaScript Actions
编写属于自己的 GitHub JavaScript Action,用它来自动化你的工作流程。
这是一个交互式课程,需要在 GitHub 上实际操作来完成学习。本页面为静态预览,仅方便您一次性阅读所有步骤内容。
前往 GitHub 开始学习 →课程概览
English | 中文
本课程翻译自 Github Skills,全部课程请点击 这里查看
编写 JavaScript Actions
编写属于自己的 GitHub JavaScript Action,用它来自动化你的工作流程。
Welcome
在这门课程中,你将学习如何编写并发布属于你自己的 JavaScript Action,来定制你的工作流程。
- 目标人群:开发者、GitHub 用户、Git 新手、学生、项目管理者以及团队成员。
- 你将学到:如何在工作流文件中使用现有的 Actions,以及如何创建自定义的 JavaScript Action,并将它发布到 GitHub Marketplace。
- 先决条件:在开始之前,你需要对 GitHub、GitHub Actions 以及持续集成(CI)有基本了解。
- 课程时长:大约需要 1 到 2 小时完成课程。
在本课程中,你将:
- 初始化一个 JavaScript 项目
- 配置一个 Action
- 创建元数据文件
- 编写 JavaScript 脚本
- 在 workflow 文件中添加 Action
- 触发 Action 运行
开始学习本课程
- 右键点击上方 Start course 按钮,选择在新标签页中打开链接。
- 在新页面中根据系统提示新建一个仓库。
- 仓库名称、描述这些字段系统已经帮我们自动填充好了,您可以按需修改。
- 建议选择公开仓库,因为私有仓库有GitHub Actions 分钟数限制。
- 最后点击 Create repository 按钮
- 仓库创建完毕后,等待大约 20 秒(等待Action执行),然后刷新页面。注意是刷新您仓库的页面,不是本课程的页面。如果页面没有变化,请继续等待。然后按照 README 中的步骤一步步进行。
课程步骤

Step 1: 初始化 JavaScript 项目
欢迎来到本课程 🎉
配置工作流
GitHub 仓库默认已经启用了 Actions,但要让它实际运行,还需要告诉仓库“应该执行什么”。具体做法是在仓库中创建一个工作流(workflow)文件来实现。
Workflow 文件用于描述自动化流程,它由 jobs(任务)和 steps(步骤)组成,以及触发执行所需的条件。
一个仓库中可以包含多个 workflow 文件,用于执行不同的任务。因此,在命名工作流文件时,应确保名称能准确反映其执行的任务内容。
在本课程中,我们会为了教学方便,将多个任务都放在同一个 workflow 文件中,这在实际项目中并不推荐。
准备你的开发环境
在接下来的练习中,我们将使用 GitHub ToolKit 来开发 JavaScript Actions。
这是一个外部依赖库,需要通过 npm 安装,因此你的电脑上必须先安装 Node.js。
我们推荐在本地环境中编写 Action,而不是直接在 GitHub 的网页端操作。这样你可以使用自己熟悉的编辑器、插件等让开发更高效。
如果你没有 IDE 偏好,建议使用 Visual Studio Code,它与本课程的演示保持一致。
别忘了准备好你的开发环境
接下来的步骤大部分都需要在本地执行,因此请先确保你在电脑上安装了以下工具:
- Node.js
- Visual Studio Code 或其他编辑器。
- Git
⌨️ 实操环节:初始化一个新的 JavaScript 项目
在本地安装好以上工具后,按照下面的步骤创建你的第一个 Action:
打开终端(macOS / Linux)或命令提示符(Windows)。
克隆当前练习仓库到本地:
git clone <this repository URL>.git进入刚刚克隆的仓库目录:
cd <local folder with cloned repo>切换到
main分支:git switch main创建一个新文件夹,用于存放我们的 Action 文件:
mkdir -p .github/actions/joke-action进入刚创建的
joke-action文件夹:cd .github/actions/joke-action初始化 Node.js 项目(使用默认配置):
npm init -y使用
npm安装所需依赖:GitHub ToolKit 相关包以及请求库:npm install --save request request-promise @actions/core将新增的文件提交到仓库中(我们稍后会处理 node_modules 的上传问题):
git add . git commit -m 'add project dependencies'将修改推送到远程仓库:
git push等待约 20 秒后刷新本页面。GitHub Actions 会自动检测到你的更改,并进入下一步。

Step 2: 配置你的 Action
很好! 继续 🚲
我们已经完成前期准备工作,接下来就来创建我们的 joke-action 吧。
⌨️ 实操环节
接下来的所有步骤都在 .github/actions/joke-action 目录下进行。
我们先定义 Action 所必需的参数,后续随着功能演进,再逐步添加可选参数。
在
.github/actions/joke-action目录下创建一个新文件action.yml打开该文件并添加以下内容:
name: "my joke action" description: "use an external API to retrieve and display a joke" runs: using: "node16" main: "main.js"这段配置的含义是:
name:Action 的名称(这里叫“my joke action”);description:Action 的简单描述;runs:定义运行环境为 Node.js 16,并指定入口文件为main.js。
保存
action.yml文件。将修改提交并推送到
main分支:git add action.yml git commit -m 'create action.yml' git pull git push等待大约 20 秒后刷新本页面。GitHub Actions 会自动检测更新,并跳转到下一步。

Step 3: Action 元数据文件
在上一步中我们已经创建好了 Action 元数据文件,本节我们来完善它。
关于 Action 的元数据
每个 GitHub Action 都必须具有一个 元数据文件(metadata file)。并遵守如下规则:
- 文件名必须为
action.yml. - 无论是 Docker 类型还是 JavaScript 类型的 Action 都需要它。
- 文件内容使用 YAML 语法编写。
这个文件主要定义了 Action 的以下信息:
| 参数 | 说明 | 是否必需 |
|---|---|---|
| Name | Action 的名称,用于在工作流中直观识别。 | ✅ |
| Description | 对 Action 功能的简要描述。 | ✅ |
| Inputs | 输入参数,允许你在运行时向 Action 传入数据。这些参数在运行器中会作为环境变量使用。 | ❌ |
| Outputs | 指定 Action 执行后产生的输出数据,供工作流中后续的步骤使用。 | ❌ |
| Runs | Action 执行时要运行的命令或入口文件。 | ✅ |
| Branding | 可设置图标和颜色,在 GitHub Marketplace 中个性化展示你的 Action。 | ❌ |
想了解更多,请查看 Action 元数据语法说明
⌨️ 实操环节:补充元数据文件
以下步骤都在 .github/actions/joke-action 目录下完成。
我们的 Action 不需要复杂的元数据即可运行。本次我们不会接收任何输入参数,但会定义一个输出参数。
更新元数据文件
.github/actions/joke-action/action.yml,内容如下:name: "my joke action" description: "use an external API to retrieve and display a joke" outputs: joke-output: description: The resulting joke from the icanhazdadjokes API runs: using: "node16" main: "main.js"保存
action.yml文件。提交并推送修改到 GitHub:
git add action.yml git pull git commit -m 'add metadata for the joke action' git push等待大约 20 秒后刷新本页面,GitHub Actions 会自动检测更改并进入下一步。

Step 4: 为你的 Action 编写 JavaScript 代码
元数据文件已经加好了! 💃
文件结构
在 JavaScript(以及其他编程语言)中,我们通常会把代码拆分成多个模块,方便阅读和维护。 由于 JavaScript Actions 本质上也是一段根据特定触发条件运行的 JS 程序,我们同样可以采用模块化的方式组织代码。
在本步骤中,我们将创建两个文件:
joke.js:负责从外部 API 获取一个笑话;main.js:调用上面的模块,并将笑话输出到控制台。
在下一步中,我们还会进一步扩展它的功能。
获取笑话数据
笑话 API
我们首先创建 joke.js 文件,用来从 icanhazdadjoke API 获取笑话。
这个 API 不需要认证,但需要在请求头中设置一些参数。
调用该 API 后,我们会收到一个 JSON 对象,格式如下:
{
"id": "0LuXvkq4Muc",
"joke": "I knew I shouldn't steal a mixer from work, but it was a whisk I was willing to take.",
"status": 200
}
返回的数据包含三个键值对,其中我们只关心 joke 字段,它就是笑话的内容。
笑话模块实现
在 .github/actions/joke-action 目录下创建文件 joke.js,内容如下:
const request = require("request-promise");
const options = {
method: "GET",
uri: "https://icanhazdadjoke.com/",
headers: {
Accept: "application/json",
"User-Agent": "Writing JavaScript action GitHub Skills course.",
},
json: true,
};
async function getJoke() {
const res = await request(options);
return res.joke;
}
module.exports = getJoke;
代码说明:
首先导入我们之前通过
npm安装的request-promise库;定义
options对象,其中包含请求方式、目标 URL 以及请求头;Accept表示希望返回 JSON 格式;User-Agent是 API 要求的标识;
定义一个异步函数
getJoke(),发送请求并获取响应;函数返回 JSON 对象中的
joke字段内容(每次调用都会返回不同的笑话);最后通过
module.exports导出函数,以便在main.js中使用。
创建 Action 的主入口
Main 模块
在同一目录下创建 main.js 文件,内容如下:
const getJoke = require("./joke");
const core = require("@actions/core");
async function run() {
const joke = await getJoke();
console.log(joke);
core.setOutput("joke-output", joke);
}
run();
代码说明:
首先引入我们自己写的
joke.js模块,以及 GitHub 提供的@actions/core库;定义一个异步函数
run():- 调用
getJoke()获取笑话内容并存入变量joke; - 将笑话打印到控制台;
- 使用
core.setOutput()将笑话内容设置为输出参数joke-output(稍后会被其他步骤使用)。
- 调用
最后调用
run()来执行整个流程。
⌨️ 实操环节
创建文件
.github/actions/joke-action/joke.js,内容如下:const request = require("request-promise"); const options = { method: "GET", uri: "https://icanhazdadjoke.com/", headers: { Accept: "application/json", "User-Agent": "Writing JavaScript action GitHub Skills course.", }, json: true, }; async function getJoke() { const res = await request(options); return res.joke; } module.exports = getJoke;保存
joke.js文件。创建文件
.github/actions/joke-action/main.js,内容如下:const getJoke = require("./joke"); const core = require("@actions/core"); async function run() { const joke = await getJoke(); console.log(joke); core.setOutput("joke-output", joke); } run();保存
main.js文件。提交修改并推送到 GitHub:
git add joke.js main.js git commit -m 'creating joke.js and main.js' git pull git push等待大约 20 秒后刷新本页面。GitHub Actions 会自动检测更新,并进入下一步。

Step 5: 在 workflow 文件中引用你的 Action
干得漂亮! 🎉
接下来的步骤会把你刚创建的 Action 添加到仓库中已有的工作流文件 my-workflow.yml 中。
⌨️ 实操环节: 在 workflow 文件中引用自定义 Action
在 my-workflow.yml 文件中添加如下内容:
- name: ha-ha
uses: ./.github/actions/joke-action
完整的 workflow 文件示例如下:
name: JS Actions
on:
issues:
types: [labeled]
jobs:
action:
if: ${{ !github.event.repository.is_template }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: ha-ha
uses: ./.github/actions/joke-action
说明:
- 我们这里使用
issues事件触发,而不是pull_request。 - 移除了之前示例中的
hello-worldAction。 uses: ./.github/actions/joke-action指向本地的自定义 Action 目录。
你可以在浏览器中打开 my-workflow.yml 并直接编辑文件。
记得选择 Commit directly to the main branch 以直接提交更改。
等待大约 20 秒后刷新本页面,GitHub Actions 会自动检测更新,并进入下一步。

Step 6: 触发你的笑话 Action
太棒了! ❤️
现在一切准备就绪,我们可以准备“开怀大笑”了 😄
在本仓库中,你会看到一些与笑话相关的标签(labels)。 实际上,任何标签都会触发我们的工作流,但为了方便跟随课程演示,建议使用推荐的标签。
触发笑话 Action
- 打开 Issues tab页中的 issue #1。
- 给这个 issue 添加标签
first-joke。 - 等几秒钟后,再给同一个 issue 添加标签
second-joke。 - 打开 Actions 标签页,查看
JS Actions工作流的执行结果。 - 等待大约 20 秒后刷新本页面,GitHub Actions 会自动检测更新,并进入下一步。

完成
恭喜你,成功完成了本课程!
在本课程中,你学习了如何使用 JavaScript 和 Actions Toolkit 开发自定义 Action,并将其集成到你的工作流中。
发布你的 Action
将你的 Action 发布到 GitHub Marketplace 是一个很好的方式,不仅能帮助你的团队,也能惠及整个 GitHub 社区。 虽然 Action 并不一定要发布才能使用,但发布后其他人可以更方便地找到并使用它。
Marketplace 上的一些热门 Action 示例:
这仅仅是 Marketplace 上 1600+ 个 Action 的冰山一角。
想要学习如何将你的 Action 发布到 GitHub Marketplace,可以参考官方指南。
接下来可以做什么?
- 继续学习其他 GitHub Skills 课程
- 在我们的 讨论区 分享你对本课程的体验
- 阅读 GitHub 入门文档
- 想找开源项目参与贡献?浏览 GitHub Explore
恭喜你迈出了成为 GitHub Action 开发者的重要一步! 🎉