动手实践 - 第一个动作

GitHub Actions 的强大之处在于其可重用性,因此了解如何创建和使用 Actions 非常重要。在这个动手练习中,你将创建一个容器 action,它将在 Docker 容器中运行。

你可以在 https://docs.github.com/en/actions/creating-actions/creating-a-dockercontainer-action 找到这个示例,并可以从那里复制和粘贴文本文件的内容。如果你愿意,也可以使用模板仓库 https://github.com/actions/container-action 并点击 Use this template。它会为你创建一个包含所有文件的仓库。

步骤如下:

  1. 创建一个名为 hello-world-docker-action 的新仓库,并将其克隆到你的工作站。

  2. 打开终端并导航到该仓库:

    $ cd hello-world-docker-action
  3. 创建一个名为 Dockerfile 的文件,不带扩展名。将以下内容添加到该文件中:

    # 容器镜像,运行你的代码
    FROM alpine:3.10
    # 将你的代码文件从 action 仓库复制到容器的文件系统路径 '/'
    COPY entrypoint.sh /entrypoint.sh
    # 容器启动时执行的代码文件 ('entrypoint.sh')
    ENTRYPOINT ["/entrypoint.sh"]

    这个 Dockerfile 定义了你的容器 —— 本例中使用的是基于 Alpine Linux 3.10 的镜像。然后,它会将 entrypoint.sh 文件复制到容器中。如果容器被执行,它将运行 entrypoint.sh

  4. 创建一个名为 action.yml 的新文件,内容如下:

    # action.yml
    name: 'Hello World'
    description: 'Greet someone and record the time'
    inputs:
    who-to-greet:  # 输入的 ID
    description: 'Who to greet'
    required: true
    default: 'World'
    outputs:
    time:  # 输出的 ID
    description: 'The time we greeted you'
    runs:
    using: 'docker'
    image: 'Dockerfile'
    args:
    - ${{ inputs.who-to-greet }}

    action.yml 文件定义了 action 及其输入和输出参数。

  5. 现在,创建 entrypoint.sh 脚本。这个脚本将在你的容器中运行,并调用其他二进制文件。将以下内容添加到文件中:

    #!/bin/sh -l
    echo "Hello $1"
    time=$(date)
    echo "::set-output name=time::$time"

    输入参数作为参数传递给脚本,并通过 $1 访问。脚本使用 set-output 工作流命令将 time 参数设置为当前时间。

  6. 你必须使 entrypoint.sh 文件可执行。在非 Windows 系统上,你可以运行以下命令,然后添加并提交你的更改:

    $ chmod +x entrypoint.sh
    $ git add .
    $ git commit -m "My first action is ready"

    在 Windows 上,这样做是行不通的。但你可以在将文件添加到索引时标记它为可执行文件:

    $ git add .
    $ git update-index --chmod=+x .\entrypoint.sh
    $ git commit -m "My first action is ready"
  7. Actions 的版本管理是通过 Git 标签进行的。添加一个 v1 标签并推送所有更改到远程仓库:

    $ git tag -a -m "My first action release" v1
    $ git push --follow-tags
  8. 现在你的 action 已经准备好使用了。返回到你在 getting-started 仓库中的工作流文件(.github/workflows/dotnet.yaml)并编辑它。删除 jobs 下的所有内容(第9行),并用以下代码替换:

    hello_world_job:
    runs-on: ubuntu-latest
    name: A job to say hello
    steps:
    - name: Hello world action step
    id: hello
    uses: your-username/hello-world-action@v1
    with:
    who-to-greet: 'your-name'
    - name: Get the output time
    run: echo "The time was ${{ steps.hello.outputs.time }}"

    工作流现在会调用你的 action(uses),并指向你创建的仓库(your-username/hello-world-action),后跟标签(@v1)。它将你的名字作为输入参数传递给 action,并接收当前时间作为输出,然后将其写入控制台。

  9. 保存文件后,工作流会自动运行。查看详细信息,查看日志中的问候语和时间。

    如果你想尝试其他类型的 actions,可以使用现有的模板。如果你想尝试一个 JavaScript action,可以使用 https://github.com/actions/javascript-action。如果你想尝试一个 TypeScript action,可以使用 https://github.com/actions/typescript-action。 复合 action 更容易,因为你只需要一个 action.yml 文件(参见 https://docs.github.com/en/actions/creating-actions/creating-a-composite-action。 处理 actions 的方式是相同的 —— 只是创建的方式不同。