关于GitHub Packages 和 GitHub Actions
GitHub Actions 帮助您在您存储代码的同一位置自动执行软件开发工作流程,并协作处理拉取请求和议题。 您可以写入个别任务,称为操作,并结合它们创建一个自定义的工作流程。 通过 GitHub Actions 可直接在仓库中构建端到端持续集成 (CI) 和持续部署 (CD) 功能。 有关详细信息,请参阅 撰写工作流程。
您可以通过在工作流程中发布或安装包来扩展仓库的 CI 和 CD 功能。
使用细粒度权限对包注册表进行身份验证
某些 GitHub Packages 注册表支持精细权限。 这意味着你可以选择允许包的范围限定为用户或组织,或者链接到存储库。 有关支持精细权限的注册表的列表,请参阅 关于 GitHub Packages 的权限。
对于支持精细权限的注册表,如果 GitHub Actions 工作流使用 personal access token 向注册表进行身份验证,则强烈建议更新工作流以使用 GITHUB_TOKEN。 有关如何更新通过 personal access token 向注册表进行身份验证的工作流的指南,请参阅 使用 GitHub Actions 发布和安装包。
注意
GitHub Actions 工作流使用 REST API 删除和还原包的功能目前为 公开预览,可能随时更改。
如果令牌具有对包的 admin 权限,可以在 GitHub Actions 工作流中使用 GITHUB_TOKEN,通过 REST API 来删除或还原包。 使用工作流发布包的存储库,以及已经显式连接到包的存储库,会自动获得对存储库中包的 admin 权限。
有关 GITHUB_TOKEN 的详细信息,请参阅 在工作流中使用 GITHUB_TOKEN 进行身份验证。 有关在操作中使用注册表时的最佳做法的详细信息,请参阅 安全使用指南。
使用存储库范围的权限对包注册表进行身份验证
某些 GitHub Packages 注册表仅支持存储库范围的权限,不支持精细权限。 有关这些注册表的列表,请参阅 关于 GitHub Packages 的权限。
如果希望工作流访问GitHub Packages不支持精细权限的注册表,则建议在启用GITHUB_TOKEN时使用GitHubGitHub Actions自动为存储库创建的注册表。 应在工作流文件中设置此访问令牌的权限,以授予 contents 范围的读取访问权限,并授予 packages 范围的写入访问权限。 对于分支,向 GITHUB_TOKEN 授予了对父存储库的读取访问权限。 有关详细信息,请参阅“在工作流中使用 GITHUB_TOKEN 进行身份验证”。
您可以在工作流文件中使用${{ secrets.GITHUB_TOKEN }}上下文来引用GITHUB_TOKEN。 有关详细信息,请参阅“在工作流中使用 GITHUB_TOKEN 进行身份验证”。
关于权限和包访问
范围限定为用户或组织的包
支持精细权限的注册表允许用户在组织级别将包作为独立资源来创建和管理。 包的范围可以限定为组织或个人帐户,你可以自定义与存储库权限分开的每个包访问权限。
访问支持精细权限的注册表的所有工作流都应使用GITHUB_TOKEN而不是 .personal access token 有关安全最佳做法的详细信息,请参阅 安全使用指南。
范围限定为存储库的包
启用 GitHub 操作后,GitHub 会在您的仓库中安装 GitHub 应用程序。
GITHUB_TOKEN 机密是 GitHub 应用安装访问令牌。 您可以使用安装访问令牌代表仓库中安装的 GitHub 应用程序进行身份验证。 令牌的权限仅限于包含您的工作流程的仓库。 有关详细信息,请参阅“在工作流中使用 GITHUB_TOKEN 进行身份验证”。
GitHub Packages允许你通过可用于GitHub Actions工作流的GITHUB_TOKEN推送和拉取包。
通过工作流程修改的包的默认权限和访问设置
对于支持精细权限的注册表中的包,当你通过工作流程创建、安装、修改或删除包时,有一些默认权限和访问设置用于确保管理员能够访问工作流程。 您也可以调整这些访问设置。 有关支持精细权限的注册表的列表,请参阅 关于 GitHub Packages 的权限。
例如,默认情况下,如果工作流使用 GITHUB_TOKEN 创建包,则:
- 包继承运行工作流程的存储库的可见性和权限模型。
- 在创建包后,工作流程运行的存储库管理员将成为包的管理员。
以下是管理包的工作流程的默认权限如何运作的更多示例。
| GitHub Actions 工作流任务 | 默认权限和访问权限 |
|---|---|
| 下载现有项 | - 如果包是公开的,则任何存储库中运行的任何工作流程都可以下载包。 - 如果包是内部的,则在企业帐户拥有的任何存储库中运行的所有工作流都可以下载包。 对于企业拥有的组织,你可以读取企业中的任何存储库 - 如果包是专用的,则只有在存储库中运行且具有对该包的读取权限的工作流才可下载包。 如果授予公共存储库对专用包的访问权限,存储库的分支可能能够访问专用包。 |
| 上传新版本到现有包 | - 如果包是私有、内部或公共的,则只有在该包上获得写入权限的存储库中运行的工作流程才可将新版本上传到包中。 |
| 删除包或包的版本 | - 如果包是私有、内部或公共的,则只有在该容器上获得管理权限的存储库中运行的工作流才可删除包的现有版本。 |
还可以使用更精细的方式调整对包的访问,或调整一些默认权限行为。 有关详细信息,请参阅“配置包的访问控制和可见性”。
使用操作发布软件包
您可以使用 GitHub Actions 作为持续集成(CI)流程的一部分来自动发布软件包。 如果代码符合您的质量标准,可使用这种持续部署 (CD) 方法自动创建新的包版本。 例如,您可以创建一个每当开发者向特定分支推送代码时运行 CI 测试的工作流程。 如果测试通过,工作流可以将新的包版本发布到 GitHub Packages。
配置步骤因包客户端而异。 有关为 GitHub Actions 配置工作流的一般信息,请参阅 撰写工作流程。
以下示例演示了如何使用GitHub Actions构建并测试您的应用,然后自动创建 Docker 镜像并将其发布到GitHub Packages。 代码中解释了相关设置。 有关工作流中每个元素的完整详细信息,请参阅 GitHub Actions 的工作流语法。
在存储库中创建新的工作流文件(例如 .github/workflows/deploy-image.yml),并添加以下 YAML。
注意
- 此工作流使用未通过 GitHub 认证的操作。 这些操作由第三方提供,并受单独的服务条款、隐私政策和支持文档的管辖。
- GitHub 建议将操作固定到提交 SHA。 若要获取较新版本,需要更新 SHA。 还可以引用标记或分支,但该操作可能会更改而不发出警告。
#
name: Create and publish a Docker image
# Configures this workflow to run every time a change is pushed to the branch called `release`.
on:
push:
branches: ['release']
# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
jobs:
build-and-push-image:
runs-on: ubuntu-latest
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
permissions:
contents: read
packages: write
attestations: write
id-token: write
#
steps:
- name: Checkout repository
uses: actions/checkout@v6
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see [Usage](https://github.com/docker/build-push-action#usage) in the README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
- name: Build and push Docker image
id: push
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see [Using artifact attestations to establish provenance for builds](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds).
- name: Generate artifact attestation
uses: actions/attest@v4
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
name: Create and publish a Docker imageon:
push:
branches: ['release']Configures this workflow to run every time a change is pushed to the branch called release.
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
jobs:
build-and-push-image:
runs-on: ubuntu-latestThere is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
permissions:
contents: read
packages: write
attestations: write
id-token: writeSets the permissions granted to the GITHUB_TOKEN for the actions in this job.
steps:
- name: Checkout repository
uses: actions/checkout@v6 - name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}Uses the docker/login-action action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}This step uses docker/metadata-action to extract tags and labels that will be applied to the specified image. The id "meta" allows the output of this step to be referenced in a subsequent step. The images value provides the base name for the tags and labels.
- name: Build and push Docker image
id: push
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}This step uses the docker/build-push-action action to build the image, based on your repository's Dockerfile. If the build succeeds, it pushes the image to GitHub Packages.
It uses the context parameter to define the build's context as the set of files located in the specified path. For more information, see Usage in the README of the docker/build-push-action repository.
It uses the tags and labels parameters to tag and label the image with the output from the "meta" step.
- name: Generate artifact attestation
uses: actions/attest@v4
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: trueThis step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see Using artifact attestations to establish provenance for builds.
#
name: Create and publish a Docker image
# Configures this workflow to run every time a change is pushed to the branch called `release`.
on:
push:
branches: ['release']
# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
jobs:
build-and-push-image:
runs-on: ubuntu-latest
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
permissions:
contents: read
packages: write
attestations: write
id-token: write
#
steps:
- name: Checkout repository
uses: actions/checkout@v6
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see [Usage](https://github.com/docker/build-push-action#usage) in the README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
- name: Build and push Docker image
id: push
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see [Using artifact attestations to establish provenance for builds](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds).
- name: Generate artifact attestation
uses: actions/attest@v4
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
每次将更改推送到存储库中名为 release 的分支时,这个新工作流都会自动运行。 可在“操作”选项卡中查看进度。
工作流程完成几分钟后,新包将在您的存储库中可见。 若要查找可用的包,请参阅 查看包。
通过操作安装包
你可以使用 GitHub Actions 作为 CI 流程的一部分来安装软件包。 例如,可以配置工作流,以便每当开发人员将代码推送到拉取请求时,工作流就会通过下载并安装托管的 GitHub Packages包来解析依赖项。 然后,该工作流程就可以运行需要这些依赖项的 CI 测试。
使用GitHub Packages时,安装通过GitHub Actions托管的GITHUB_TOKEN包需要最少的配置或其他身份验证。 当操作安装包时,数据传输也是免费的。 有关详细信息,请参阅 GitHub程序包计费。
配置步骤因包客户端而异。 有关为 GitHub Actions 配置工作流的一般信息,请参阅 撰写工作流程。
升级使用personal access token访问注册表的工作流
GitHub Packages 支持 GITHUB_TOKEN 在工作流中轻松安全地进行身份验证。 如果您使用的是支持细粒度权限的注册表,并且您的工作流正在使用 personal access token 向该注册表进行身份验证,那么我们强烈建议您将工作流更新为使用 GITHUB_TOKEN。
有关 GITHUB_TOKEN 的详细信息,请参阅 在工作流中使用 GITHUB_TOKEN 进行身份验证。
使用 GITHUB_TOKEN 而不是具有 repo 作用域的 personal access token (classic),可以提高存储库的安全性,因为这样无需使用长期有效的 personal access token,从而避免向运行工作流的存储库授予不必要的访问权限。 有关安全最佳做法的详细信息,请参阅 安全使用指南。
-
导航到包登陆页面。
-
为了确保你的包能够访问你的工作流程,必须将存储工作流程的代码库添加到包中。 在“管理 Actions 访问权限”下,击“添加存储库”并搜索要添加的存储库。

注意
将存储库添加到包 :使用包的设置中“管理 Actions 访问”下的“添加存储库”**** 按钮 不同于将包连接到存储库。 有关详细信息,请参阅 配置包的访问控制和可见性 和 将仓库连接到软件包。
-
(可选)使用 使用“角色”下拉菜单,选择你希望存储库访问你的包所拥有的默认访问级别。
-
打开工作流程文件。 在登录到注册表的那一行中,将你的 personal access token 替换为
${{ secrets.GITHUB_TOKEN }}。
例如,此工作流将 Docker 镜像发布到 Container registry,并使用 ${{ secrets.GITHUB_TOKEN }} 进行身份验证。 有关详细信息,请参阅 Docker 文档中的设置自动生成。
#
name: Demo Push
# This workflow runs when any of the following occur:
# - A push is made to a branch called `main` or `seed`
# - A tag starting with "v" is created
# - A pull request is created or updated
on:
push:
branches:
- main
- seed
tags:
- v*
pull_request:
# This creates an environment variable called `IMAGE_NAME ` with the value `ghtoken_product_demo`.
env:
IMAGE_NAME: ghtoken_product_demo
#
jobs:
# This pushes the image to GitHub Packages.
push:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
#
steps:
- uses: actions/checkout@v6
- name: Build image
run: docker build . --file Dockerfile --tag $IMAGE_NAME --label "runnumber=${GITHUB_RUN_ID}"
- name: Log in to registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
#
- name: Push image
run: |
IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
# This changes all uppercase characters to lowercase.
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
# This strips the git ref prefix from the version.
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
# This strips the "v" prefix from the tag name.
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
# This uses the Docker `latest` tag convention.
[ "$VERSION" == "main" ] && VERSION=latest
echo IMAGE_ID=$IMAGE_ID
echo VERSION=$VERSION
docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
docker push $IMAGE_ID:$VERSION
name: Demo Pushon:
push:
branches:
- main
- seed
tags:
- v*
pull_request:This workflow runs when any of the following occur:
- A push is made to a branch called
mainorseed - A tag starting with "v" is created
- A pull request is created or updated
env:
IMAGE_NAME: ghtoken_product_demoThis creates an environment variable called IMAGE_NAME with the value ghtoken_product_demo.
jobs: push:
runs-on: ubuntu-latest
permissions:
packages: write
contents: readThis pushes the image to GitHub Packages.
steps:
- uses: actions/checkout@v6
- name: Build image
run: docker build . --file Dockerfile --tag $IMAGE_NAME --label "runnumber=${GITHUB_RUN_ID}"
- name: Log in to registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - name: Push image
run: |
IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')This changes all uppercase characters to lowercase.
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')This strips the git ref prefix from the version.
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')This strips the "v" prefix from the tag name.
[ "$VERSION" == "main" ] && VERSION=latest
echo IMAGE_ID=$IMAGE_ID
echo VERSION=$VERSION
docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
docker push $IMAGE_ID:$VERSIONThis uses the Docker latest tag convention.
#
name: Demo Push
# This workflow runs when any of the following occur:
# - A push is made to a branch called `main` or `seed`
# - A tag starting with "v" is created
# - A pull request is created or updated
on:
push:
branches:
- main
- seed
tags:
- v*
pull_request:
# This creates an environment variable called `IMAGE_NAME ` with the value `ghtoken_product_demo`.
env:
IMAGE_NAME: ghtoken_product_demo
#
jobs:
# This pushes the image to GitHub Packages.
push:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
#
steps:
- uses: actions/checkout@v6
- name: Build image
run: docker build . --file Dockerfile --tag $IMAGE_NAME --label "runnumber=${GITHUB_RUN_ID}"
- name: Log in to registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
#
- name: Push image
run: |
IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
# This changes all uppercase characters to lowercase.
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
# This strips the git ref prefix from the version.
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
# This strips the "v" prefix from the tag name.
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
# This uses the Docker `latest` tag convention.
[ "$VERSION" == "main" ] && VERSION=latest
echo IMAGE_ID=$IMAGE_ID
echo VERSION=$VERSION
docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
docker push $IMAGE_ID:$VERSION