关于 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 发布和安装包”。
Note
GitHub Actions 工作流使用 REST API 删除和还原包的功能目前为 公共预览版,可能随时更改。
如果令牌具有对包的 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
授予了对父存储库的读取访问权限。 有关详细信息,请参阅“自动令牌身份验证”。
可使用 ${{ secrets.GITHUB_TOKEN }}
上下文在工作流文件中引用 GITHUB_TOKEN
。 有关详细信息,请参阅“自动令牌身份验证”。
关于权限和包访问
范围限定为用户或组织的包
支持精细权限的注册表允许用户在组织级别将包作为独立资源来创建和管理。 包的范围可以限定为组织或个人帐户,你可以自定义与存储库权限分开的每个包访问权限。
访问支持精细权限的注册表的所有工作流都应使用 GITHUB_TOKEN
而不是 personal access token。 有关安全最佳做法的详细信息,请参阅 GitHub Actions 的安全强化。
范围限定为存储库的包
启用 GitHub 操作后,GitHub 会在您的仓库中安装 GitHub 应用程序。 GITHUB_TOKEN
机密是 GitHub 应用安装访问令牌。 您可以使用安装访问令牌代表仓库中安装的 GitHub 应用程序进行身份验证。 令牌的权限仅限于包含您的工作流程的仓库。 有关详细信息,请参阅“自动令牌身份验证”。
使用 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。
Note
- 此工作流使用未通过 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@v4 # 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 "[AUTOTITLE](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds)." - name: Generate artifact attestation uses: actions/attest-build-provenance@v2 with: subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} subject-digest: ${{ steps.push.outputs.digest }} push-to-registry: true
name: Create and publish a Docker image
on:
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-latest
There 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: write
Sets the permissions granted to the GITHUB_TOKEN
for the actions in this job.
steps:
- name: Checkout repository
uses: actions/checkout@v4
- 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-build-provenance@v2
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
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 "使用项目证明确立生成的来源."
#
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@v4
# 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 "[AUTOTITLE](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds)."
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v2
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_TOKEN
时,通过 GitHub Actions 安装 GitHub Packages 托管的包只需极少的配置或额外身份验证。使用操作安装包时,数据传输也是免费的。 有关详细信息,请参阅 关于 GitHub 包的计费。
配置步骤因包客户端而异。 有关为 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 的安全强化。
-
导航到包登陆页面。
-
为了确保包能够访问你的工作流程,必须添加存储库,其中工作流程存储到包。 在“管理 Actions 访问权限”下,击“添加存储库”并搜索要添加的存储库。
Note
将存储库添加到包 :使用包的设置中“管理 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@v4 - 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 Push
on:
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
main
orseed
- A tag starting with "v" is created
- A pull request is created or updated
env:
IMAGE_NAME: ghtoken_product_demo
This creates an environment variable called IMAGE_NAME
with the value ghtoken_product_demo
.
jobs:
push:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
This pushes the image to GitHub Packages.
steps:
- uses: actions/checkout@v4
- 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:$VERSION
This 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@v4
- 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