跳至主要内容

创建 Docker 容器操作

本指南向您展示了构建 Docker 容器操作所需的最小步骤。

简介

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

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

自托管运行器必须使用 Linux 操作系统并安装 Docker 才能运行 Docker 容器 action。有关自托管运行器要求的更多信息,请参阅“关于自托管运行器”。

警告

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

先决条件

创建 Dockerfile

在您的新 hello-world-docker-action 目录中,创建一个新的 Dockerfile 文件。如果您遇到问题,请确保您的文件名大小写正确(使用大写 D 但不要使用大写 f)。有关更多信息,请参阅“GitHub Actions 的 Dockerfile 支持”。

Dockerfile

Dockerfile
# Container image that runs your code
FROM alpine:3.10

# Copies your code file from your action repository to the filesystem path `/` of the container
COPY entrypoint.sh /entrypoint.sh

# Code file to execute when the docker container starts up (`entrypoint.sh`)
ENTRYPOINT ["/entrypoint.sh"]

创建 action 元数据文件

在您上面创建的 hello-world-docker-action 目录中创建一个新的 action.yml 文件。有关更多信息,请参阅“GitHub Actions 的元数据语法”。

action.yml

YAML
# action.yml
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: 'docker'
  image: 'Dockerfile'
  args:
    - ${{ inputs.who-to-greet }}

此元数据定义了一个 who-to-greet 输入和一个 time 输出参数。要将输入传递到 Docker 容器,您应该使用 inputs 声明输入并在 args 关键字中传递输入。您在 args 中包含的所有内容都将传递到容器,但为了更好地提高您 action 用户的可发现性,我们建议使用输入。

GitHub 将从您的 Dockerfile 构建映像,并使用此映像在新容器中运行命令。

编写 action 代码

您可以选择任何基本 Docker 映像,因此,您可以为您的 action 选择任何语言。以下 shell 脚本示例使用 who-to-greet 输入变量在日志文件中打印“Hello [who-to-greet]”。

接下来,脚本获取当前时间并将其设置为输出变量,以便稍后在作业中运行的 action 可以使用它。为了让 GitHub 识别输出变量,您必须将它们写入 $GITHUB_OUTPUT 环境文件:echo "<output name>=<value>" >> $GITHUB_OUTPUT。有关更多信息,请参阅“GitHub Actions 的工作流命令”。

  1. hello-world-docker-action 目录中创建一个新的 entrypoint.sh 文件。

  2. 将以下代码添加到您的 entrypoint.sh 文件中。

    entrypoint.sh

    Shell
    #!/bin/sh -l
    
    echo "Hello $1"
    time=$(date)
    echo "time=$time" >> $GITHUB_OUTPUT
    
    

    如果 entrypoint.sh 执行没有错误,则 action 的状态将设置为 success。您也可以在 action 的代码中显式设置退出代码以提供 action 的状态。有关更多信息,请参阅“设置 action 的退出代码”。

  3. 使您的 entrypoint.sh 文件可执行。Git 提供了一种方法来显式更改文件的权限模式,以便每次克隆/分叉时都不会重置它。

    Shell
    git add entrypoint.sh
    git update-index --chmod=+x entrypoint.sh
    
  4. 可选地,要检查 git 索引中文件的权限模式,请运行以下命令。

    Shell
    git ls-files --stage entrypoint.sh
    

    100755 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 entrypoint.sh 这样的输出表示该文件具有可执行权限。在此示例中,755 表示可执行权限。

创建 README

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

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

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

README.md

Markdown
# Hello world docker 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

uses: actions/hello-world-docker-action@v2
with:
  who-to-greet: 'Mona the Octocat'

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

从您的终端,提交您的 action.ymlentrypoint.shDockerfileREADME.md 文件。

最佳实践还包括为 action 的版本添加版本标记。有关 action 版本控制的更多信息,请参阅“关于自定义 action”。

Shell
git add action.yml entrypoint.sh Dockerfile README.md
git commit -m "My first action is ready"
git tag -a -m "My first action release" v1
git push --follow-tags

在工作流中测试你的 action

现在您可以准备好在一个工作流中测试您的 action 了。

  • 公共 action 可以被任何仓库中的工作流使用。

使用公共 action 的示例

以下工作流代码使用公共 actions/hello-world-docker-action 仓库中已完成的 hello world action。将以下工作流示例代码复制到 .github/workflows/main.yml 文件中,但将 actions/hello-world-docker-action 替换为您自己的仓库和 action 名称。您还可以将 who-to-greet 输入替换为您自己的姓名。即使公共 action 未发布到 GitHub Marketplace,也可以使用它们。有关更多信息,请参阅“在 GitHub Marketplace 中发布 action”。

.github/workflows/main.yml

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: actions/hello-world-docker-action@v2
        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 }}"

使用私有 action 的示例

将以下示例工作流代码复制到 action 仓库中的 .github/workflows/main.yml 文件中。您还可以将 who-to-greet 输入替换为您自己的姓名。此私有 action 无法发布到 GitHub Marketplace,只能在此仓库中使用。

.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**。

访问容器 action 创建的文件

当容器 action 运行时,它将自动将运行器上的默认工作目录 (GITHUB_WORKSPACE) 与容器上的 /github/workspace 目录映射。添加到容器上此目录中的任何文件都将可用于同一作业中的任何后续步骤。例如,如果您有一个构建项目的容器 action,并且您希望将构建输出上传为构件,则可以使用以下步骤。

workflow.yml

YAML
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      # Output build artifacts to /github/workspace on the container.
      - name: Containerized Build
        uses: ./.github/actions/my-container-action

      - name: Upload Build Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: workspace_artifacts
          path: ${{ github.workspace }}

有关将构建输出上传为构件的更多信息,请参阅“存储和共享工作流数据”。

GitHub.com 上的 Docker 容器 action 示例

您可以在 GitHub.com 上找到许多 Docker 容器 action 的示例。