Github action中docker无效的引用格式(标记名)

wbrvyc0a  于 2023-05-06  发布在  Docker
关注(0)|答案(1)|浏览(238)

我正在尝试使用git中的相同标签来构建docker镜像。
下面是Github Action配置

runs-on: ubuntu-latest

steps:
  -
    name: Set up QEMU
    uses: docker/setup-qemu-action@v2
  -
    name: Set up Docker Buildx
    uses: docker/setup-buildx-action@v2
  -
    name: Login to Docker Hub
    uses: docker/login-action@v2
    with:
      username: ${{ secrets.DOCKER_HUB_USERNAME }}
      password: ${{ secrets.DOCKER_HUB_PW }}

  - name: Extract metadata (tags, labels) for Docker
    id: meta
    uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
    with:
      images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

-
  name: Build and push - with version
  uses: docker/build-push-action@v3
  with:
    context: "{{defaultContext}}"
    push: true
    tags: ${{ steps.meta.outputs.tags }}
    labels: ${{ steps.meta.outputs.labels }}

当前的git标签是a0.15.3,但是当操作运行时,它会引发错误

ERROR: invalid tag "/:a0.15.3": invalid reference format

为什么有额外的前缀"/:?是这个前缀导致了错误吗?如何在Github Action Workflow文件中修复此问题?

/usr/bin/docker buildx build --iidfile /tmp/docker-build-push-vwhSgm/iidfile --label org.opencontainers.image.title=XXXX
--label org.opencontainers.image.description=XXXX --label org.opencontainers.image.url=https://github.com/***/XXXX--label org.opencontainers.image.source=https://github.com/***/XXXX--label org.opencontainers.image.version=a0.15.3 --label org.opencontainers.image.created=2023-05-04T04:49:01.011Z --label org.opencontainers.image.revision=d450d4dce21b38b6091e6ebe3bfa8f6ede553816 --label org.opencontainers.image.licenses=BSD-3-Clause --provenance false --secret id=GIT_AUTH_TOKEN,src=/tmp/docker-build-push-vwhSgm/tmp-40371-OFYmqDXttfTp --tag /:a0.15.3 --tag /:latest --metadata-file /tmp/docker-build-push-vwhSgm/metadata-file --push https://github.com/***/XXXX.git#d450d4dce21b38b6091e6ebe3bfa8f6ede553816
ERROR: invalid tag "/:a0.15.3": invalid reference format
Error: buildx failed with: ERROR: invalid tag "/:a0.15.3": invalid reference format
5jvtdoz2

5jvtdoz21#

tl;dr

  • 你不能打破的东西不是真实的的。
  • 有足够的默认值,总是。
  • 处理输入参数的一个行动,错误与审查。

错误消息:

ERROR: invalid tag "/:a0.15.3": invalid reference format

是从docker/metadata-action操作中发出的,并且是由工作流steps条目中的配置问题引起的,该条目具有id"meta",具体来说是以下部分:

images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

对于工作流步骤env上下文,错误消息显示两个上下文属性REGISTRYIMAGE_NAME均为空,导致无效标记“/:a0.15.3”。
然后你认为 “额外的前缀"/: [sic!]" 实际上是工作流的作者命令,即使是空的Docker注册表名称和空的Docker镜像名称(这是测试失败的好场景)。
出乎意料的是,我猜这只是因为层次结构中的jobs.<job_id>.steps[*].env或类似的REGISTRYIMAGE_NAME属性未定义(至少有问题的工作流的摘录-可能是继承的-没有任何这种定义)。
这显然只是docker/metadata-action Microsoft Github Action steps的image配置设置的一个小错误(但仍然是一个),因为它是必需的 * 并且 * 必须包含有效的docker镜像名称,否则该操作无法从中生成有效的docker镜像标记名称。
操作发出的错误消息可以改进,因为在您的情况下,它会造成标记名称错误的印象,而可以清楚地说,图像名称-操作的输入-已经无效。因此,看起来这个操作没有在使用之前验证它的输入,这将其责任推给了它的用户。如果你也有同样的感觉,不要期望这会有所不同,因为动作记录了这种行为,而是使用许可证和contribute back to the project

成功配置Docker元数据Github Action的Docker镜像名称

让我们展开这个小问题,但毕竟仍然是一个配置问题,并检查其内部部分和工作方式,以获得对问题的足够理解,以便就如何配置此工作流和类似的工作流给出一个很好的答案。

Docker Registry配置

您正在登录默认的docker注册表,即"docker.io"¹,因此这是第一个REGISTRY环境参数默认值的含义。它需要被使用,你不能只传递一个空字符串。因此,在为docker元数据操作创建输入时,覆盖默认值,因为我们已经发现它不能很好地处理这种情况:

images: ${{ env.REGISTRY || "docker.io" }}/${{ env.IMAGE_NAME }}
  • 示例:* 在表达式中使用 * 或 * 运算符(|| ²)以fall-through到默认值:

${{ env.REGISTRY || "docker.io" }}:如果env.REGISTRY为空或未定义,则使用"docker.io"³
由于您使用的是默认注册表,因此也可以将其删除,但需要同时删除内部斜杠(“/”)(例如:images: ${{ env.IMAGE_NAME }}),但我不建议在您的问题中使用,因为默认值"docker.io"也可能是非预期的,因此您可以更容易地将其替换为预期的默认值。

Docker镜像名称配置

而且你还没有在你的问题中分享IMAGE_NAME环境参数的默认值是什么。到目前为止,为了让答案完整,我们假设它是 *Github所有者和存储库名称 *,这将完成输入并再次给出如何提供默认值的示例,这次是从github上下文:

images: ${{ env.REGISTRY || "docker.io" }}/${{ env.IMAGE_NAME || github.repository }}

假设你的是Github上的 acme 所有者的 hello-world 仓库,那么在这种情况下,标签前缀为元数据操作的image-name将变成:

docker.io/acme/hello-world:a0.15.3

您可以自然地制定任何其他表达式,而不是使用github.repository表达式作为默认值,只要它是 * docker image name* 中 * docker image name component* 的有效语法字符串(下一个)。

Docker镜像名称组件语法

这是Docker Metadata Github Action和Docker的images的Docker镜像名称组件的语法:
映像名称由斜线分隔的名称组件组成,可以选择以注册表主机名作为前缀。[...]
名称组件可以包含小写字母、数字和分隔符。分隔符定义为句点、一个或两个下划线、一个或多个短划线。名称组件不能以分隔符开头或结尾。[...]

image-name            ::= prefix? name-components
...
name-components       ::= name-component ( "/" name-component )?
name-component        ::= name ( name-separator name )*
name                  ::= [a-z0-9]+
name-separator        ::= ( "." | "_" "_"? | "-"+ )
  • (摘录自:*Docker容器(镜像/标签)名称语法

在您的特定情况下,我可以肯定您已经知道默认名称,只是问题是您希望它已经是IMAGE_NAME环境参数,尚未初始化。

Docker元数据中镜像名称的问题快速修复Microsoft Github Action

因此,您可能希望在这里使用不同的默认值,并且如果它只是用于配置测试的硬编码字符串:

images: ${{ env.REGISTRY || "docker.io" }}/${{ env.IMAGE_NAME || "my-name-of-docker-image" }}

该示例可以快速运行修复程序。然后,将其(映像名称"my-name-of-docker-image")或两者(也是默认注册表"docker.io")替换为相应上下文中的正确默认值。

工作流及其步骤的默认环境

或者首先在env上下文中设置它们的默认值,这需要更多的工作,例如定义工作流的环境变量:

env:
  REGISTRY: docker.io
  IMAGE_NAME: my-name-of-docker-image

在工作流顶层定义env的好处是,环境变量最初是为整个工作流作业设置的,这也包括在您的jobs.<job_id>.steps[*].env上下文中,其中这两个参数(env.REGISTRYenv.IMAGE_NAME)当前未定义或为空。

# safe use of context parameters as defaults are set up before:
      images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

通常,正确的默认值也是自记录的。如果可能,请将它们放置在文件的顶部或引入它们的零件的开头。

tl;dr

  • 你不能打破的东西不是真实的的。
  • 有足够的默认值,总是。
  • 处理输入参数的一个行动,错误与审查。

¹ c.f.answer of "Where Docker default registry URL is configured?"
² c.f. 运算符-表达式(学习GitHub操作)
³ *c.f.*answer of “How to use env variable as default value for input in GitHub actions?“

相关问题