自动将软件包发布到 pub.dev
您可以自动发布来自
- GitHub Actions,
- Google Cloud Build 或
- 使用 GCP 服务帐号 的任何其他地方。
以下部分说明如何配置自动发布,以及如何根据您的偏好自定义发布流程。
配置自动发布时,您无需创建复制到自动部署环境中的长期密钥。相反,身份验证依赖于由 GitHub Actions(请参阅 GitHub Actions 的 OIDC)或 Google Cloud IAM 签名的临时 OpenID Connect 令牌。
您可以为不存在身份服务的部署环境使用导出的服务帐号密钥。此类导出的服务帐号密钥是长期密钥,在某些环境中可能更容易使用,但如果意外泄露也会带来更大的风险。
使用 GitHub Actions 发布软件包
#您可以使用 GitHub Actions 配置自动发布。这包括
在 pub.dev 上启用自动发布,指定
- GitHub 存储库,以及
- 必须匹配才能允许发布的标签模式。
创建用于发布到 pub.dev 的 GitHub Actions 工作流。
推送要发布的版本的 git 标签。
以下部分概述如何完成这些步骤。
配置从 GitHub Actions 自动发布到 pub.dev
#要启用从 GitHub Actions 到 pub.dev
的自动发布,您必须是
- 软件包上的上传者,或
- 发布者的管理员(如果软件包由发布者拥有)。
如果您具有足够的权限,则可以通过以下方式启用自动发布
导航到“管理”选项卡(
pub.dev/packages/<package>/admin
)。找到“自动发布”部分。
单击“启用从 GitHub Actions 发布”,这将提示您指定
- 存储库(
<组织>/<存储库>
,例如:dart-lang/pana
), - 标签模式(包含
{{version}}
的字符串)。
- 存储库(
存储库是 GitHub 上的 <组织>/<存储库>
。例如,如果您的存储库是 https://github.com/dart-lang/pana
,则必须在存储库字段中指定 dart-lang/pana
。
标签模式是一个必须包含 {{version}}
的字符串。只有由与此标签模式匹配的标签推送触发的 GitHub Actions 才允许发布您的软件包。
示例:像 v{{version}}
这样的标签模式允许 GitHub Actions(由 git tag v1.2.3 && git push v1.2.3
触发)发布您软件包的版本 1.2.3
。因此,pubspec.yaml
中的 version
键也必须与此版本号匹配。
如果您的存储库包含多个软件包,请为每个软件包提供单独的标签模式。考虑对名为 my_package_name
的软件包使用类似 my_package_name-v{{version}}
的标签模式。
配置用于发布到 pub.dev 的 GitHub Action 工作流
#在 pub.dev 上启用从 GitHub Actions 自动发布后,您可以创建一个用于发布的 GitHub Actions 工作流。这是通过创建如下的 .github/workflows/publish.yml
文件来完成的
# .github/workflows/publish.yml
name: Publish to pub.dev
on:
push:
tags:
# must align with the tag-pattern configured on pub.dev, often just replace
# {{version}} with [0-9]+.[0-9]+.[0-9]+
- 'v[0-9]+.[0-9]+.[0-9]+' # tag-pattern on pub.dev: 'v{{version}}'
# If you prefer tags like '1.2.3', without the 'v' prefix, then use:
# - '[0-9]+.[0-9]+.[0-9]+' # tag-pattern on pub.dev: '{{version}}'
# If your repository contains multiple packages consider a pattern like:
# - 'my_package_name-v[0-9]+.[0-9]+.[0-9]+'
# Publish using the reusable workflow from dart-lang.
jobs:
publish:
permissions:
id-token: write # Required for authentication using OIDC
uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1
# with:
# working-directory: path/to/package/within/repository
确保 on.push.tags
中的模式与 pub.dev 上指定的标签模式匹配。否则,GitHub Action 工作流将无法工作。如果从同一存储库发布多个软件包,请使用每个软件包的标签模式(如 my_package_name-v{{version}}
),并为每个软件包创建一个单独的工作流文件。
上面的工作流文件使用 dart-lang/setup-dart/.github/workflows/publish.yml
来发布软件包。这是一个可重用的工作流,它允许 Dart 团队维护发布逻辑,并使 pub.dev 知道软件包是如何发布的。强烈建议使用此可重用的工作流。
如果您的软件包中需要生成的代码,则最好将此生成的代码检入到您的存储库中。这简化了验证 pub.dev 上发布的文件是否与您存储库中的文件匹配。如果将生成或构建的工件检入到您的存储库中是不合理的,您可以创建一个类似于以下的自定义工作流
# .github/workflows/publish.yml
name: Publish to pub.dev
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+' # tag pattern on pub.dev: 'v{{version}'
# Publish using custom workflow
jobs:
publish:
permissions:
id-token: write # Required for authentication using OIDC
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dart-lang/setup-dart@v1
- name: Install dependencies
run: dart pub get
# Here you can insert custom steps you need
# - run: dart tool/generate-code.dart
- name: Publish
run: dart pub publish --force
该工作流使用临时的 GitHub 签名的 OIDC 令牌向 pub.dev
进行身份验证,该令牌是在 dart-lang/setup-dart
步骤中创建和配置的。要发布到 pub.dev,后续步骤可以运行 dart pub publish --force
。
从 GitHub Actions 触发自动发布
#在 pub.dev
上配置自动发布并创建 GitHub Actions 工作流后,您可以发布软件包的新版本。要发布,请推送与配置的标签模式匹配的 git 标签。
$ cat pubspec.yaml
package: my_package_name
version: 1.2.3 # must match the version number used in the git tag
environment:
sdk: ^2.19.0
$ git tag v1.2.3 # assuming my tag pattern is: 'v{{version}}'
$ git push origin v1.2.3 # triggers the action that publishes my package.
推送后,请在 https://github.com/<organization>/<repository>/actions
上查看工作流日志。
如果操作未触发,请检查在 .github/workflows/publish.yml
中配置的模式是否与推送的 git 标签匹配。如果操作失败,日志可能会包含失败原因的线索。
发布后,您可以在 pub.dev
上的 audit-log
中看到发布事件。 audit-log
条目应包含指向发布软件包版本的 GitHub Action 运行的链接。
如果您不喜欢使用 git
CLI 创建标签,您可以在 GitHub 上从 https://github.com/<组织>/<仓库>/releases/new
创建发布版本。要了解更多信息,请查看 GitHub 上的 在仓库中管理发布版本。
使用 GitHub 上的标签保护规则加强安全性
#从 GitHub Actions 配置自动发布允许任何可以向您的仓库推送标签的人触发向 pub.dev 的发布。您可以使用 GitHub 上的 标签保护规则 来限制谁可以向您的仓库推送标签。
通过限制谁可以创建与您的标签模式匹配的标签,您可以限制谁可以发布软件包。
目前,标签保护规则缺乏灵活性。您可能希望使用 GitHub 部署环境来限制谁可以触发发布,如下一节所述。
使用 GitHub 部署环境加强安全性
#在 pub.dev 上从 GitHub Actions 配置自动发布时,您可以要求一个 GitHub Actions 环境。要为发布要求一个GitHub Actions 环境,您必须
- 导航到 Admin 选项卡 (
pub.dev/packages/<package>/admin
)。 - 找到“自动发布”部分。
- 点击 Require GitHub Actions environment。
- 指定一个 Environment 名称,(
pub.dev
通常是一个不错的名称)
当 pub.dev 上需要一个环境时,除非它们有 environment: pub.dev
,否则 GitHub Actions 将无法发布。因此,您必须
- 在 GitHub 上创建一个具有相同名称的环境(通常为
pub.dev
) - 修改您的
.github/workflows/publish.yml
工作流程文件以指定environment: pub.dev
,如下所示
# .github/workflows/publish.yml
name: Publish to pub.dev
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+' # for tags like: 'v1.2.3'
jobs:
publish:
permissions:
id-token: write # Required for authentication using OIDC
uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1
with:
# Specify the github actions deployment environment
environment: pub.dev
# working-directory: path/to/package/within/repository
该环境反映在用于与 pub.dev 进行身份验证的临时 GitHub 签名的 OIDC 令牌中。因此,有权推送到您的仓库的用户无法通过修改工作流程文件来规避 环境保护规则。
在 GitHub 仓库设置中,您可以使用 环境保护规则来配置必需的审阅者。如果您配置此选项,GitHub 将阻止具有该环境的操作运行,直到其中一个必需的审阅者批准该运行为止。
从 Google Cloud Build 发布
#您可以从 Google Cloud Build 配置自动发布。这包括
- 注册一个 Google Cloud 项目(或使用现有项目),
- 为发布到 pub.dev 创建一个 服务帐户,
- 在 pub.dev 上软件包的管理选项卡中启用自动发布,指定为发布创建的服务帐户的电子邮件。
- 授予默认的 Cloud Build 服务帐户模拟为发布创建的服务帐户的权限。
- 创建一个
cloudbuild.yaml
文件,该文件获取一个临时的 OIDCid_token
并将其用于发布到 pub.dev - 配置一个 Cloud Build 触发器,用于在 Google Cloud Build 上在您的项目中运行
cloudbuild.yaml
中的步骤。
以下部分概述如何完成这些步骤。
创建用于发布的 Service Account
#对于发布到 pub.dev,您将创建一个被授予在 pub.dev 上发布您的软件包权限的服务帐户。然后,您将授予 Cloud Build 模拟此服务帐户的权限。
如果您没有现有项目,创建一个云项目。
创建一个服务帐户,如下所示
$ gcloud iam service-accounts create pub-dev \ --description='Service account to be impersonated when publishing to pub.dev' \ --display-name='pub-dev'
这将创建一个名为
pub-dev@$PROJECT_ID.iam.gserviceaccount.com
的服务帐户。授予服务帐户发布您的软件包的权限。
要完成此步骤,您必须拥有软件包的上传者权限,或者是拥有该软件包的发布者的管理员。
a. 导航到 Admin 选项卡 (
pub.dev/packages/<package>/admin
)。 a. 点击 Enable publishing with Google Cloud Service account。 a. 在 Service account email 字段中输入服务帐户的电子邮件。您在上一步中创建了这个帐户:pub-dev@$PROJECT_ID.iam.gserviceaccount.com
完成此过程后,任何可以模拟服务帐户的人都可以发布软件包的新版本。请务必查看谁有权模拟服务帐户,并根据需要在云项目中更改权限。
授予 Cloud Build 发布权限
#要从 Cloud Build 发布,您必须授予 默认的 Cloud Build 服务帐户模拟上一节中创建的用于发布的服务帐户的权限。
在云项目中启用 IAM Service Account Credentials API。如果没有此 API,尝试模拟服务帐户将失败。
# Enable IAM Service Account Credentials API $ gcloud services enable iamcredentials.googleapis.com
找到项目编号。
# The PROJECT_NUMBER can be obtained as follows: $ gcloud projects describe $PROJECT_ID --format='value(projectNumber)'
授予模拟发布服务帐户的权限。
# Grant default cloud $ gcloud iam service-accounts add-iam-policy-binding \ pub-dev@$PROJECT_ID.iam.gserviceaccount.com \ --member=serviceAccount:[email protected] \ --role=roles/iam.serviceAccountTokenCreator
编写 Cloud Build 配置文件
#要从 Cloud Build 发布,您必须指定 Cloud Build 的步骤
- 模拟服务帐户以获取临时的 OIDC 令牌。
- 向
dart pub
提供临时的 OIDC 令牌,以便在发布时使用。 - 调用
dart pub publish
来发布软件包。
Google Cloud Build 的步骤在 cloudbuild.yaml
文件中提供,有关格式的完整文档,请参阅 构建配置文件架构。
对于从 Google Cloud Build 发布到 pub.dev,如下所示的 cloudbuild.yaml
文件可以做到
# cloudbuild.yaml
steps:
- id: Create temporary token
name: gcr.io/cloud-builders/gcloud
volumes:
- name: temporary-secrets
path: /secrets
script: |
gcloud auth print-identity-token \
--impersonate-service-account=pub-dev@$PROJECT_ID.iam.gserviceaccount.com \
--audiences=https://pub.dev \
--include-email > /secrets/temporary-pub-token.txt
env:
- PROJECT_ID=$PROJECT_ID
- id: Publish to pub.dev
name: dart
volumes:
- name: temporary-secrets
path: /secrets
script: |
cat /secrets/temporary-pub-token.txt | dart pub token add https://pub.dev
dart pub publish --force
gcloud auth print-identity-token
创建一个模拟指定服务帐户的 OIDC id_token
。此 id_token
由 Google 签名,签名在 1 小时内过期。audiences 参数让 pub.dev 知道它是令牌的预期接收者。--include-email
选项对于 pub.dev 识别服务帐户是必需的。
创建 id_token
后,它将被写入驻留在卷中的文件;此机制用于 在步骤之间传递数据。不要将令牌存储在 /workspace
中。由于 /workspace
是检出您要发布的仓库的位置。不使用 /workspace
存储令牌会降低在发布时意外将其包含在软件包中的风险。
创建 Cloud Build 触发器
#配置服务帐户并在仓库中配置 cloudbuild.yaml
文件后,您可以使用 console.cloud.google.com 仪表板创建 Cloud Build 触发器。要创建构建触发器,您需要连接到源仓库并指定哪些事件应触发构建。您可以使用 GitHub、Cloud Source Repository 或 其他选项之一。要了解如何配置Cloud Build 触发器,请查看 创建和管理构建触发器。
要使用上一步中的 cloudbuild.yaml
,请将Cloud Build 触发器类型配置为位于 /cloudbuild.yaml
文件中仓库中的“Cloud Build Configuration”。不要为要触发的构建指定服务帐户。相反,您应该使用 Cloud Build 的默认服务帐户。
在配置 Cloud Build 触发器时,请考虑谁可以触发构建。因为触发构建可能会发布软件包的新版本。请考虑仅允许手动构建或使用 Cloud Build 审批来控制构建,如下一节所述。
使用 Cloud Build Approvals 加强安全性
#在配置 Cloud Build 触发器时,您可以选择 require approval before build executes。如果 Cloud Build 触发器需要审批,则在触发时不会运行。相反,它将等待批准。这可用于限制谁可以发布软件包的新版本。
只有具有 Cloud Build Approver 角色的用户才能给出批准。在给出批准时,批准者可以指定 URL 和评论。
您还可以配置待批准通知。要了解更多信息,请查看 通过批准控制构建。
使用 Service Account 从任何位置发布
#要允许在 GitHub Actions 之外进行自动发布,您可以使用类似于 Cloud Build 的方式使用服务帐户进行身份验证。
这通常包括
- 创建一个用于发布的服务帐户,
- 通过以下两种方式之一模拟发布服务帐户
- 工作负载身份联合
- 导出的服务帐户密钥
Cloud Build 部分概述了如何 创建一个用于发布的服务帐户。这应该提供一个服务帐户,例如 pub-dev@$PROJECT_ID.iam.gserviceaccount.com
。
使用 Workload Identity Federation 发布
#在支持 OIDC 或 SAML 的云服务上运行时,您可以使用 工作负载身份联合来模拟 GCP 服务帐户。这使您能够利用云提供商的身份服务。
例如,如果部署在 EC2 上,您可以配置与 AWS 的工作负载身份联合,允许来自 EC2 元数据服务的临时 AWS 令牌模拟服务帐户。要了解如何配置这些流程,请查看工作负载身份联合。
使用导出的 Service Account 密钥发布
#在没有身份服务的自定义系统上运行时,您可以导出服务帐户密钥。导出的服务帐户密钥允许您以该服务帐户的身份进行身份验证。要了解更多信息,请查看如何创建和管理服务帐户密钥。
导出服务帐户密钥
#为现有的服务帐户创建导出的服务帐户密钥。
$ gcloud iam service-accounts keys create key-file.json \ --iam-account=pub-dev@$PROJECT_ID.iam.gserviceaccount.com
保存
key-file.json
文件以供后续使用。
使用导出的服务帐户密钥发布软件包
#要使用导出的服务帐户密钥发布软件包
设置 gcloud 使用
key-file.json
进行身份验证(在上一步中创建)。$ gcloud auth activate-service-account --key-file=key-file.json
为 pub.dev 创建一个临时令牌,并将其传递给
dart pub token add https://pub.dev
。要模拟服务帐户,请包含--include-email
选项。$ gcloud auth print-identity-token \ --audiences=https://pub.dev \ | dart pub token add https://pub.dev
使用临时令牌发布。添加
--force
选项以跳过yes/no
提示。$ dart pub publish --force
除非另有说明,否则本网站上的文档反映了 Dart 3.6.0。页面最后更新于 2024-08-30。 查看源代码 或 报告问题。