Skip to main content
We publish frequent updates to our documentation, and translation of this page may still be in progress. For the most current information, please visit the English documentation.

使用 GitHub Actions 发布和安装包

您可以配置 GitHub Actions 中的工作流程以自动发布或安装 GitHub Packages 的包。

GitHub Packages 适用于 GitHub Free、GitHub Pro、面向组织的 GitHub Free、GitHub Team, GitHub Enterprise Cloud, GitHub Enterprise Server 3.0 或更高版本以及 GitHub AE。
GitHub Packages 不适用于使用旧版按仓库计划的帐户所拥有的私有仓库。 此外,使用旧版按仓库计划的帐户无法访问 Container registry,因为这些帐户是按仓库计费的。 有关详细信息,请参阅“GitHub 的产品”。

关于 GitHub Packages 与 GitHub Actions

GitHub Actions 帮助您在您存储代码的同一位置自动执行软件开发工作流程,并协作处理拉取请求和议题。 您可以写入个别任务,称为操作,并结合它们创建一个自定义的工作流程。 通过 GitHub Actions 可直接在仓库中构建端到端持续集成 (CI) 和持续部署 (CD) 功能。 有关详细信息,请参阅“关于 GitHub Actions”。

您可以通过在工作流程中发布或安装包来扩展仓库的 CI 和 CD 功能。

使用精细权限对包注册表进行身份验证

某些 GitHub Packages 注册表支持精细权限。 这意味着你可以选择允许包由用户或组织拥有,或者链接到存储库。 有关支持精细权限的注册表列表,请参阅“关于 GitHub Packages 的权限”。

对于支持精细权限的注册表,如果 GitHub Actions 工作流使用 personal access token 向注册表进行身份验证,则强烈建议更新工作流以使用 GITHUB_TOKEN。 有关更新使用 personal access token 对注册表进行身份验证的工作流的指南,请参阅“升级使用 personal access token 访问注册表的工作流”。

注意:GitHub Actions 工作流使用 REST API 删除和还原包的功能目前提供公共 beta 版本,可能会发生更改。

如果令牌具有对包的 admin 权限,你可以在 GitHub Actions 工作流中使用 GITHUB_TOKEN,通过 REST API 来删除或还原包。 使用工作流发布包的存储库,以及已经显式连接到包的存储库,会自动获得对存储库中包的 admin 权限。

有关 GITHUB_TOKEN 的详细信息,请参阅“工作流中的身份验证”。 有关在操作中使用注册表时的最佳做法的详细信息,请参阅“GitHub Actions 的安全强化”。

使用存储库范围的权限对包注册表进行身份验证

某些 GitHub Packages 注册表仅支持存储库范围的权限,不支持精细权限。 有关这些注册表的列表,请参阅“关于 GitHub Packages 的权限”。

如果要让工作流访问不支持精细权限的 GitHub Packages 注册表,则我们建议使用 GitHub 在你启用 GitHub Actions 时自动为注册表创建的 GITHUB_TOKEN。 应在工作流文件中设置此访问令牌的权限,以授予 contents 范围的读取访问权限,并授予 packages 范围的写入访问权限。 对于分支,向 GITHUB_TOKEN 授予了对父存储库的读取访问权限。 有关详细信息,请参阅“使用 GITHUB_TOKEN 进行身份验证”。

可使用 {{secrets.GITHUB_TOKEN}} 上下文在工作流文件中引用 GITHUB_TOKEN。 有关详细信息,请参阅“使用 GITHUB_TOKEN 进行身份验证”。

关于权限和包访问

范围限定为用户或组织的包

支持精细权限的注册表允许用户在组织级别将包作为独立资源来创建和管理。 包可以归组织或个人帐户所有,你可以自定义与存储库权限分开的每个包访问权限。

访问支持精细权限的注册表的所有工作流都应使用 GITHUB_TOKEN 而不是 personal access token。 有关安全最佳做法的详细信息,请参阅“GitHub Actions 的安全强化”。

范围限定为存储库的包

启用 GitHub 操作后,GitHub 会在您的仓库中安装 GitHub 应用程序。 GITHUB_TOKEN 机密是 GitHub 应用安装访问令牌。 您可以使用安装访问令牌代表仓库中安装的 GitHub 应用程序进行身份验证。 令牌的权限仅限于包含您的工作流程的仓库。 有关详细信息,请参阅“GITHUB_TOKEN 的权限”。

使用 GitHub Packages 能通过可用于 GitHub Actions 工作流的 GITHUB_TOKEN 推送和拉取包。

通过工作流程修改的容器的默认权限和访问设置

当您通过工作流程创建、安装、修改或删除容器时,有一些默认权限和访问设置用于确保管理员能够访问工作流程。 您也可以调整这些访问设置。

例如,默认情况下,如果工作流使用 GITHUB_TOKEN 创建容器,则:

  • 容器继承运行工作流程的仓库的可见性和权限模型。
  • 在创建容器后,工作流程运行的仓库管理员将成为容器的管理员。

以下是管理包的工作流程的默认权限如何运作的更多示例。

GitHub Actions 工作流程任务默认权限和访问权限
下载现有容器- 如果容器是公开的,则任何仓库中运行的任何工作流程都可以下载容器。
- 如果容器是内部的,则在企业帐户拥有的任何存储库中运行的所有工作流都可以下载容器。 对于企业拥有的组织,你可以读取企业中的任何存储库
- 如果容器是专用的,则只有在存储库中运行且具有对该容器的读取权限的工作流才可下载容器。
上传新版本到现有容器- 如果容器是私有、内部或公共的,则只有在该容器上获得写入权限的仓库中运行的工作流程才可将新版本上传到容器中。
删除容器或容器版本- 如果容器是私有、内部或公共的,则只有在该容器上获得管理权限的存储库中运行的工作流才可删除容器的现有版本。

您还可以使用更精细的方式调整对容器的访问,或调整一些默认权限行为。 有关详细信息,请参阅“配置包的访问控制和可见性”。

使用操作发布包

您可以使用 GitHub Actions 在持续集成 (CI) 流程中自动发布包。 如果代码符合您的质量标准,可使用这种持续部署 (CD) 方法自动创建新的包版本。 例如,您可以创建一个每当开发者向特定分支推送代码时运行 CI 测试的工作流程。 如果测试通过,则工作流程可以将新的包版本发布到 GitHub Packages。

配置步骤因包客户端而异。 有关为 GitHub Actions 配置工作流的一般信息,请参阅“配置工作流”。

下面的示例演示如何使用 GitHub Actions 构建应用程序,然后自动创建 Docker 映像并将其发布到 GitHub Packages:

在存储库中创建新的工作流文件(例如 .github/workflows/deploy-image.yml),并添加以下 YAML:

YAML
# 此工作流使用未经 GitHub 认证的操作。
# 它们由第三方提供,并受
# 单独的服务条款、隐私政策和支持
# 文档。

# GitHub 建议将操作固定到提交 SHA。
# 若要获取较新版本,需要更新 SHA。
# 还可以引用标记或分支,但该操作可能会更改而不发出警告。

name: Create and publish a Docker image

on:
 push:
   branches: ['release']

env:
 REGISTRY: ghcr.io
 IMAGE_NAME: ${{ github.repository }}

jobs:
 build-and-push-image:
   runs-on: ubuntu-latest
   permissions:
     contents: read
     packages: write

   steps:
     - name: Checkout repository
       uses: actions/checkout@v3

     - name: Log in to the Container registry
       uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
       with:
         registry: ${{ env.REGISTRY }}
         username: ${{ github.actor }}
         password: ${{ secrets.GITHUB_TOKEN }}

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

     - name: Build and push Docker image
       uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
       with:
         context: .
         push: true
         tags: ${{ steps.meta.outputs.tags }}
         labels: ${{ steps.meta.outputs.labels }}

下表介绍了相关设置: 有关工作流中每个元素的完整详细信息,请参阅“GitHub Actions 的工作流语法”。

```yaml on: push: branches: ['release'] ``` 配置 Create and publish a Docker image 工作流,以便在每次向名为 release 的分支推送更改时运行。
env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}
为工作流程定义两个自定义环境变量。 这些是用于 Container registry 域以及此工作流程生成的 Docker 映像的名称。
jobs:
  build-and-push-image:
    runs-on: ubuntu-latest
此工作流程中有单个作业。 它已配置为运行最新版本的 Ubuntu。
```yaml permissions: contents: read packages: write ``` 为此作业中的操作设置授予 GITHUB_TOKEN 的权限。
```yaml - name: Log in to the Container registry uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} ``` 创建一个名为 Log in to the Container registry 的步骤,以使用将发布包的帐户和密码登录到注册表。 发布后,包归此处定义的帐户所有。
```yaml - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} ``` 此步骤使用 docker/metadata-action 提取将应用于指定映像的标记和标签。 id“meta”使此步骤的输出可在随后的步骤中被引用。 images 值提供标记和标签的基本名称。
```yaml - name: Build and push Docker image ``` 新建一个名为 Build and push Docker image 的步骤。 此步骤在 build-and-push-image 作业中运行。
```yaml uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc ``` 使用 Docker build-push-action 操作生成基于存储库的 Dockerfile 的映像。 如果构建成功,它会将映像推送到 GitHub Packages。
```yaml with: ``` 将所需的参数发送到 build-push-action 操作。 这些将在后面的行中定义。
```yaml context: . ``` 将构建的上下文定义为位于指定路径中的文件集。 有关详细信息,请参阅“用法”。
```yaml push: true ``` 此映像如已成功构建,则推送至注册表。
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
添加在 "meta" 步骤中提取的标记和标签。

每次将更改推送到存储库中名为 release 的分支时,这个新工作流都会自动运行。 可在“操作”选项卡中查看进度。

工作流程完成几分钟后,新包将在您的仓库中可见。 要查找可用的包,请参阅“查看存储库的包”。

使用操作安装包

您可以使用 GitHub Actions 将安装包作为 CI 流程的一部分。 例如,您可以配置一个工作流程:每当开发者向拉取请求推送代码时,该工作流程就会通过下载并安装 GitHub Packages 托管的包来解析依赖项。 然后,该工作流程就可以运行需要这些依赖项的 CI 测试。

使用 GITHUB_TOKEN 时,通过 GitHub Actions 安装 GitHub Packages 托管的包只需极少的配置或额外身份验证。使用操作安装包时,数据传输也是免费的。 有关详细信息,请参阅“关于 GitHub Packages 的计费”。

配置步骤因包客户端而异。 有关为 GitHub Actions 配置工作流的一般信息,请参阅“配置工作流”。

升级使用 personal access token 访问注册表的工作流

GitHub Packages 支持用 GITHUB_TOKEN 在你的工作流中进行简单和安全的身份验证。 如果使用的是支持精细权限的注册表,且工作流使用 personal access token 向注册表进行身份验证,则强烈建议更新工作流以使用 GITHUB_TOKEN

有关 GITHUB_TOKEN 的详细信息,请参阅“工作流中的身份验证”。

使用 GITHUB_TOKEN 而不是 personal access token (classic)(包括 repo 范围),可提高存储库的安全性,因为无需使用长期 personal access token,以免提供对运行工作流的存储库的不必要的访问权限。 有关安全最佳做法的详细信息,请参阅“GitHub Actions 的安全强化”。

  1. 导航到包登陆页面。

  2. 在左侧边栏中,单击“操作访问”。 左侧菜单中的“操作访问”选项

  3. 为了确保您的容器包能够访问您的工作流程,您必须添加仓库,其中工作流程存储到您的容器。 单击“添加存储库”并搜索要添加的存储库。 “添加存储库”按钮

    注意:通过“操作访问”菜单选项将存储库添加到容器不同于将容器连接到存储库 。 有关详细信息,请参阅“确保工作流访问你的包”和“将存储库连接到包”。

  4. (可选)使用“role(角色)”下拉菜单,选择您希望仓库访问您的容器映像所必须拥有的默认访问权限。 授予存储库的权限访问级别

  5. 打开工作流程文件。 在登录注册表的行上,将 personal access token 替换为 ${{ secrets.GITHUB_TOKEN }}

例如,此工作流将一个 Docker 映像发布到 Container registry 并使用 ${{ secrets.GITHUB_TOKEN }} 进行身份验证。

YAML
name: Demo Push

on:
  push:
    # Publish `master` as Docker `latest` image.
    branches:
      - master
      - seed

    # Publish `v1.2.3` tags as releases.
    tags:
      - v*

  # Run tests for any PRs.
  pull_request:

env:
  IMAGE_NAME: ghtoken_product_demo

jobs:
  # Push image to GitHub Packages.
  # See also https://docs.docker.com/docker-hub/builds/
  push:
    runs-on: ubuntu-latest
    permissions:
      packages: write
      contents: read

    steps:
      - uses: actions/checkout@v3

      - name: Build image
        run: docker build . --file Dockerfile --tag $IMAGE_NAME --label "runnumber=${GITHUB_RUN_ID}"

      - name: Log in to registry
        # This is where you will update the personal access token to GITHUB_TOKEN
        run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin

      - name: Push image
        run: |
          IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME

          # Change all uppercase to lowercase
          IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
          # Strip git ref prefix from version
          VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
          # Strip "v" prefix from tag name
          [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
          # Use Docker `latest` tag convention
          [ "$VERSION" == "master" ] && VERSION=latest
          echo IMAGE_ID=$IMAGE_ID
          echo VERSION=$VERSION
          docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
          docker push $IMAGE_ID:$VERSION