跳到主要内容

创建 JavaScript 操作

在本指南中,您将学习如何使用 Actions 工具包构建 JavaScript 操作。

简介

在本指南中,您将了解创建和使用打包的 JavaScript 操作所需的基本组件。为了将本指南的重点放在打包操作所需的组件上,操作代码的功能是最小的。该操作在日志中打印“Hello World”,或者如果您提供自定义名称,则打印“Hello [who-to-greet]”。

本指南使用 GitHub Actions 工具包 Node.js 模块来加快开发速度。有关详细信息,请参阅actions/toolkit存储库。

完成本项目后,你应该了解如何构建你自己的 JavaScript action 并在工作流程中对其进行测试。

为了确保你的 JavaScript actions 与所有 GitHub 托管的 runner(Ubuntu、Windows 和 macOS)兼容,你编写的打包 JavaScript 代码应为纯 JavaScript 代码,并且不依赖于其他二进制文件。JavaScript actions 直接在 runner 上运行,并使用 runner 镜像中已存在的二进制文件。

警告

创建工作流程和 actions 时,应始终考虑你的代码是否可能执行来自潜在攻击者的不受信任的输入。某些上下文应被视为不受信任的输入,因为攻击者可能会插入他们自己的恶意内容。更多信息,请参阅“GitHub Actions 的安全加固”。

先决条件

在开始之前,你需要下载 Node.js 并创建一个公共 GitHub 仓库。

  1. 下载并安装 Node.js 20.x(包含 npm)。

    https://node.org.cn/en/download/

  2. 在 GitHub 上创建一个新的公共仓库,并将其命名为“hello-world-javascript-action”。更多信息,请参阅“创建新的仓库”。

  3. 将你的仓库克隆到你的计算机。更多信息,请参阅“克隆仓库”。

  4. 在你的终端中,将目录更改为你的新仓库。

    Shell
    cd hello-world-javascript-action
    
  5. 在你的终端中,使用 npm 初始化目录以生成一个package.json文件。

    Shell
    npm init -y
    

创建 action 元数据文件

hello-world-javascript-action目录中创建一个名为action.yml的新文件,其中包含以下示例代码。更多信息,请参阅“GitHub Actions 的元数据语法”。

YAML
name: 'Hello World'
description: 'Greet someone and record the time'
inputs:
  who-to-greet:  # id of input
    description: 'Who to greet'
    required: true
    default: 'World'
outputs:
  time: # id of output
    description: 'The time we greeted you'
runs:
  using: 'node20'
  main: 'index.js'

此文件定义了who-to-greet输入和time输出。它还告诉 action runner 如何开始运行此 JavaScript action。

添加 actions 工具包软件包

actions 工具包是一组 Node.js 软件包,允许你更快地构建更一致的 JavaScript actions。

工具包@actions/core软件包提供了一个与工作流程命令、输入和输出变量、退出状态以及调试消息交互的接口。

工具包还提供了一个@actions/github软件包,它返回一个经过身份验证的 Octokit REST 客户端以及对 GitHub Actions 上下文的访问权限。

工具包提供的软件包不仅仅是coregithub。更多信息,请参阅actions/toolkit仓库。

在你的终端中,安装 actions 工具包的coregithub软件包。

Shell
npm install @actions/core
npm install @actions/github

现在你应该会看到一个包含你刚刚安装的模块的node_modules目录,以及一个包含已安装模块依赖项及其版本的package-lock.json文件。

编写 action 代码

此 action 使用工具包获取 action 元数据文件中所需的who-to-greet输入变量,并在日志的调试消息中打印“Hello [who-to-greet]”。接下来,脚本获取当前时间并将其设置为输出变量,以便作业中稍后运行的 actions 可以使用。

GitHub Actions 提供有关 webhook 事件、Git refs、工作流程、action 以及触发工作流程的人员的上下文信息。要访问上下文信息,可以使用github软件包。你将编写的 action 会将 webhook 事件有效负载打印到日志中。

添加一个名为index.js的新文件,其中包含以下代码。

JavaScript
const core = require('@actions/core');
const github = require('@actions/github');

try {
  // `who-to-greet` input defined in action metadata file
  const nameToGreet = core.getInput('who-to-greet');
  console.log(`Hello ${nameToGreet}!`);
  const time = (new Date()).toTimeString();
  core.setOutput("time", time);
  // Get the JSON webhook payload for the event that triggered the workflow
  const payload = JSON.stringify(github.context.payload, undefined, 2)
  console.log(`The event payload: ${payload}`);
} catch (error) {
  core.setFailed(error.message);
}

如果在上面的index.js示例中抛出错误,core.setFailed(error.message);将使用 actions 工具包@actions/core软件包来记录消息并设置失败的退出代码。更多信息,请参阅“设置 actions 的退出代码”。

创建 README

为了让人们知道如何使用你的 action,你可以创建一个 README 文件。当你计划公开共享你的 action 时,README 最有用,但它也是提醒你或你的团队如何使用 action 的好方法。

在你的hello-world-javascript-action目录中,创建一个README.md文件,其中指定以下信息:

  • 对 action 功能的详细描述。
  • 必需的输入和输出参数。
  • 可选的输入和输出参数。
  • action 使用的密钥。
  • action 使用的环境变量。
  • 如何在工作流程中使用你的 action 的示例。
Markdown
# Hello world javascript action

This action prints "Hello World" or "Hello" + the name of a person to greet to the log.

## Inputs

### `who-to-greet`

**Required** The name of the person to greet. Default `"World"`.

## Outputs

### `time`

The time we greeted you.

## Example usage

```yaml
uses: actions/hello-world-javascript-action@e76147da8e5c81eaf017dede5645551d4b94427b
with:
  who-to-greet: 'Mona the Octocat'
```

提交、标记和推送你的 action 到 GitHub

GitHub 在运行时下载工作流程中每次 action 运行,并在你可以使用run等工作流程命令与 runner 机器交互之前将其作为完整的代码包执行。这意味着你必须包含运行 JavaScript 代码所需的任何软件包依赖项。你需要将工具包coregithub软件包检入你的 action 的仓库。

在你的终端中,提交你的action.ymlindex.jsnode_modulespackage.jsonpackage-lock.jsonREADME.md文件。如果你添加了一个列出node_modules.gitignore文件,则需要删除该行才能提交node_modules目录。

最好也为你的 action 的版本添加版本标记。有关你的 action 版本控制的更多信息,请参阅“关于自定义 actions”。

Shell
git add action.yml index.js node_modules/* package.json package-lock.json README.md
git commit -m "My first action is ready"
git tag -a -m "My first action release" v1.1
git push --follow-tags

检入你的node_modules目录可能会导致问题。作为替代方案,你可以使用名为@vercel/ncc的工具来编译你的代码和模块到一个用于分发的文件中。

  1. 通过在你的终端中运行此命令来安装vercel/ncc

    npm i -g @vercel/ncc

  2. 编译你的index.js文件。

    ncc build index.js --license licenses.txt

    你将看到一个新的dist/index.js文件,其中包含你的代码和已编译的模块。你还会看到一个相应的dist/licenses.txt文件,其中包含你正在使用的node_modules的所有许可证。

  3. 更改你的action.yml文件中的main关键字以使用新的dist/index.js文件。

    main: 'dist/index.js'

  4. 如果你已经检入你的node_modules目录,请将其删除。

    rm -rf node_modules/*

  5. 在你的终端中,提交对你的action.ymldist/index.jsnode_modules文件的更新。

    Shell
    git add action.yml dist/index.js node_modules/*
    git commit -m "Use vercel/ncc"
    git tag -a -m "My first action release" v1.1
    git push --follow-tags
    

在工作流程中测试你的 action

现在你可以准备在工作流程中测试你的 action 了。

公共 action 可被任何仓库中的工作流程使用。当 action 位于私有仓库中时,仓库设置决定 action 是否仅在同一仓库中可用,或者也对同一用户或组织拥有的其他仓库可用。更多信息,请参阅“管理仓库的 GitHub Actions 设置”。

使用公共 action 的示例

此示例演示了如何从外部仓库中运行你的新的公共 action。

将以下 YAML 复制到.github/workflows/main.yml中的新文件中,并使用你的用户名和你在上面创建的公共仓库的名称更新uses: octocat/hello-world-javascript-action@1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b行。你也可以将who-to-greet输入替换为你的姓名。

YAML
on: [push]

jobs:
  hello_world_job:
    runs-on: ubuntu-latest
    name: A job to say hello
    steps:
      - name: Hello world action step
        id: hello
        uses: octocat/hello-world-javascript-action@1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b
        with:
          who-to-greet: 'Mona the Octocat'
      # Use the output from the `hello` step
      - name: Get the output time
        run: echo "The time was ${{ steps.hello.outputs.time }}"

触发此工作流程时,runner 将从你的公共仓库下载hello-world-javascript-action action,然后执行它。

使用私有 action 的示例

将工作流程代码复制到 action 仓库中的.github/workflows/main.yml文件中。你也可以将who-to-greet输入替换为你的姓名。

.github/workflows/main.yml

YAML
on: [push]

jobs:
  hello_world_job:
    runs-on: ubuntu-latest
    name: A job to say hello
    steps:
      # To use this repository's private action,
      # you must check out the repository
      - name: Checkout
        uses: actions/checkout@v4
      - name: Hello world action step
        uses: ./ # Uses an action in the root directory
        id: hello
        with:
          who-to-greet: 'Mona the Octocat'
      # Use the output from the `hello` step
      - name: Get the output time
        run: echo "The time was ${{ steps.hello.outputs.time }}"

在你的仓库中,点击**Actions**选项卡,然后选择最新的工作流程运行。在**Jobs**下或可视化图表中,点击**A job to say hello**。

点击**Hello world action step**,你应该会看到日志中打印了“Hello Mona the Octocat”或你用于who-to-greet输入的名称。要查看时间戳,请点击**Get the output time**。

用于创建 JavaScript actions 的模板仓库

GitHub 提供用于创建 JavaScript 和 TypeScript actions 的模板仓库。你可以使用这些模板快速开始创建包含测试、整理和其他推荐实践的新 action。

GitHub.com 上的 JavaScript actions 示例

你可以在 GitHub.com 上找到许多 JavaScript actions 的示例。