跳到主要内容

创建 JavaScript 操作

本指南将指导您如何使用 Actions 工具包构建 JavaScript 操作。

简介

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

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

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

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

警告

创建工作流和操作时,应始终考虑您的代码是否可能会执行来自潜在攻击者的不受信任的输入。某些上下文应被视为不受信任的输入,因为攻击者可能会插入他们自己的恶意内容。有关更多信息,请参阅“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
    

创建操作元数据文件

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输出。它还告诉操作运行器如何开始运行此 JavaScript 操作。

添加 Actions 工具包软件包

Actions 工具包是 Node.js 软件包的集合,允许您更一致地快速构建 JavaScript 操作。

工具包@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文件。

编写操作代码

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

GitHub Actions 提供有关 webhook 事件、Git refs、工作流、操作以及触发工作流的人员的上下文信息。要访问上下文信息,可以使用github软件包。您将编写的操作会将 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软件包记录消息并设置失败的退出代码。更多信息,请参阅“设置操作的退出代码”。

创建自述文件

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

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

  • 对操作功能的详细描述。
  • 必需的输入和输出参数。
  • 可选的输入和输出参数。
  • 操作使用的密钥。
  • 操作使用的环境变量。
  • 如何在工作流中使用您的操作的示例。
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'
```

提交、标记和将您的操作推送到 GitHub

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

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

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

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
    

在工作流中测试您的操作

现在您可以准备在工作流中测试您的操作了。

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

使用公共操作的示例

此示例演示如何从外部代码库中运行新的公共操作。

将以下 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 }}"

触发此工作流时,运行器将从您的公共代码库下载hello-world-javascript-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 }}"

在您的代码库中,单击“**操作**”选项卡,然后选择最新的工作流运行。在“**作业**”下或可视化图表中,单击“**问候作业**”。

单击“**Hello world 操作步骤**”,您应该看到日志中打印的“Hello Mona the Octocat”或您用于who-to-greet输入的名称。要查看时间戳,请单击“**获取输出时间**”。

创建 JavaScript 操作的模板代码库

GitHub 提供了用于创建 JavaScript 和 TypeScript 操作的模板代码库。您可以使用这些模板快速开始创建包含测试、代码风格检查和其他推荐实践的新操作。

GitHub.com 上的 JavaScript 操作示例

您可以在 GitHub.com 上找到许多 JavaScript 操作示例。