注意: 项目(测试版)目前处于公开测试阶段,可能会有所变化。
简介
您可以添加自动化来帮助管理项目。 项目(测试版)包括可通过 UI 配置的内置工作流程。 此外,您可以使用 GraphQL API 和 GitHub Actions 编写自定义工作流程。
内置工作流程
项目(测试版)包括内置工作流程,可用于根据某些事件更新项的状态。 例如,您可以在项添加到项目时自动将状态设置为待办事项 ,或在议题关闭时将状态设置为完成。
当项目初始化时,默认情况下会启用两个工作流程:当项目中的议题或拉取请求关闭时,其状态设置为完成;项目中的拉取请求合并时,其状态设置为完成。
您可以为项目启用或禁用内置工作流程。
- 导航到您的项目。
- 在右上角,单击 以打开菜单。
- 在菜单中,单击 Workflows(工作流程)。
- 在 Default workflows(默认工作流程)下,单击要编辑的工作流程。
- 如果工作流程可以同时应用于议题和拉取请求,请在 When(何时)旁边,选中要对其执行操作的项类型。
- 在 Set(设置)旁边,选择要将状态设置为的值。
- 如果工作流程已禁用,请单击 Disabled(已禁用)旁边的切换开关以启用工作流程。
GitHub Actions 工作流程
本节说明如何使用 GraphQL API 和 GitHub Actions 向组织项目添加拉取请求。 在示例工作流程中,当拉取请求标记为“准备审核”时,项目中会添加一项“状态”字段设置为“待办”的新任务,并且当前日期添加到自定义的“发布日期”字段中。
您可以复制以下工作流程之一,并按照下表中的说明对其进行修改,以满足您的需求。
项目可以跨越多个仓库,但工作流是特定于仓库的。 将工作流程添加到您希望项目跟踪的每个仓库。 有关创建工作流程文件的更多信息,请参阅“GitHub Actions 快速入门”。
本文假设您基本了解 GitHub Actions。 有关 GitHub Actions 的更多信息,请参阅“GitHub Actions”。
有关可以通过 API 对项目进行的其他更改的更多信息,请参阅“使用 API 管理项目”。
注意: GITHUB_TOKEN
的范围限定为存储库级别,无法访问项目(测试版)。 要访问项目(测试版),可以创建 GitHub 应用程序 (建议用于组织项目)或个人访问令牌(建议用于用户项目)。 下面显示了这两种方法的工作流程示例。
使用 GitHub 应用程序 进行身份验证的示例工作流程
-
创建 GitHub 应用程序 或选择组织拥有的现有 GitHub 应用程序。 更多信息请参阅“创建 GitHub 应用程序”。
-
授予 GitHub 应用程序 对组织项目的读取和写入权限。 更多信息请参阅“编辑 GitHub 应用程序 的权限”。
注意: 您可以控制应用程序对组织项目和存储库项目的权限。 您必须授予读取和写入组织项目的权限;读取和写入存储库项目的权限是不够的。
-
在组织中安装 GitHub 应用程序。 为项目需要访问的所有存储库安装它。 更多信息请参阅“安装 GitHub 应用程序。”
-
将 GitHub 应用程序 的 ID 作为机密存储在存储库或组织中。 在以下工作流程中,将
APP_ID
替换为密钥的名称。 您可以在应用的设置页面上或通过应用 API 找到应用 ID。 更多信息请参阅“应用程序”。 -
为应用生成私钥。 将生成的文件的内容作为机密存储在存储库或组织中。 (存储文件的全部内容,包括
-----BEGIN RSA PRIVATE KEY-----
和-----END RSA PRIVATE KEY-----
)。 在以下工作流程中,将APP_PEM
替换为密钥的名称。 更多信息请参阅“向 GitHub 应用程序 验证”。 -
在以下工作流程中,将
YOUR_ORGANIZATION
替换为组织的名称。 例如octo-org
。 将YOUR_PROJECT_NUMBER
替换为您的项目编号。 要查找项目编号,请查看项目 URL。 例如,https://github.com/orgs/octo-org/projects/5
有一个编号为 5 的项目。
# 此工作流使用未经 GitHub 认证的操作。
# 它们由第三方提供,并受
# 单独的服务条款、隐私政策和支持
# 文档管理。
name: Add PR to project
on:
pull_request:
types:
- ready_for_review
jobs:
track_pr:
runs-on: ubuntu-latest
steps:
- name: Generate token
id: generate_token
uses: tibdex/github-app-token@36464acb844fc53b9b8b2401da68844f6b05ebb0
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.APP_PEM }}
- name: Get project data
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
ORGANIZATION: YOUR_ORGANIZATION
PROJECT_NUMBER: YOUR_PROJECT_NUMBER
run: |
gh api graphql -f query='
query($org: String!, $number: Int!) {
organization(login: $org){
projectNext(number: $number) {
id
fields(first:20) {
nodes {
id
name
settings
}
}
}
}
}' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json
echo 'PROJECT_ID='$(jq '.data.organization.projectNext.id' project_data.json) >> $GITHUB_ENV
echo 'DATE_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Date posted") | .id' project_data.json) >> $GITHUB_ENV
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
echo 'TODO_OPTION_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") |.settings | fromjson.options[] | select(.name=="Todo") |.id' project_data.json) >> $GITHUB_ENV
- name: Add PR to project
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
PR_ID: ${{ github.event.pull_request.node_id }}
run: |
item_id="$( gh api graphql -f query='
mutation($project:ID!, $pr:ID!) {
addProjectNextItem(input: {projectId: $project, contentId: $pr}) {
projectNextItem {
id
}
}
}' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectNextItem.projectNextItem.id')"
echo 'ITEM_ID='$item_id >> $GITHUB_ENV
- name: Get date
run: echo "DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV
- name: Set fields
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
run: |
gh api graphql -f query='
mutation (
$project: ID!
$item: ID!
$status_field: ID!
$status_value: String!
$date_field: ID!
$date_value: String!
) {
set_status: updateProjectNextItemField(input: {
projectId: $project
itemId: $item
fieldId: $status_field
value: $status_value
}) {
projectNextItem {
id
}
}
set_date_posted: updateProjectNextItemField(input: {
projectId: $project
itemId: $item
fieldId: $date_field
value: $date_value
}) {
projectNextItem {
id
}
}
}' -f project=$PROJECT_ID -f item=$ITEM_ID -f status_field=$STATUS_FIELD_ID -f status_value=${{ env.TODO_OPTION_ID }} -f date_field=$DATE_FIELD_ID -f date_value=$DATE --silent
使用个人访问令牌进行身份验证的示例工作流程
- 使用
org:write
范围创建个人访问令牌。 更多信息请参阅“创建个人访问令牌”。 - 将个人访问令牌另存为存储库或组织中的机密。
- 在以下工作流程中,将
YOUR_TOKEN
替换为密码名称。 将YOUR_ORGANIZATION
替换为您的组织名称。 例如octo-org
。 将YOUR_PROJECT_NUMBER
替换为您的项目编号。 要查找项目编号,请查看项目 URL。 例如,https://github.com/orgs/octo-org/projects/5
有一个编号为 5 的项目。
name: Add PR to project
on:
pull_request:
types:
- ready_for_review
jobs:
track_pr:
runs-on: ubuntu-latest
steps:
- name: Get project data
env:
GITHUB_TOKEN: ${{ secrets.YOUR_TOKEN }}
ORGANIZATION: YOUR_ORGANIZATION
PROJECT_NUMBER: YOUR_PROJECT_NUMBER
run: |
gh api graphql -f query='
query($org: String!, $number: Int!) {
organization(login: $org){
projectNext(number: $number) {
id
fields(first:20) {
nodes {
id
name
settings
}
}
}
}
}' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json
echo 'PROJECT_ID='$(jq '.data.organization.projectNext.id' project_data.json) >> $GITHUB_ENV
echo 'DATE_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Date posted") | .id' project_data.json) >> $GITHUB_ENV
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
echo 'TODO_OPTION_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") |.settings | fromjson.options[] | select(.name=="Todo") |.id' project_data.json) >> $GITHUB_ENV
- name: Add PR to project
env:
GITHUB_TOKEN: ${{ secrets.YOUR_TOKEN }}
PR_ID: ${{ github.event.pull_request.node_id }}
run: |
item_id="$( gh api graphql -f query='
mutation($project:ID!, $pr:ID!) {
addProjectNextItem(input: {projectId: $project, contentId: $pr}) {
projectNextItem {
id
}
}
}' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectNextItem.projectNextItem.id')"
echo 'ITEM_ID='$item_id >> $GITHUB_ENV
- name: Get date
run: echo "DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV
- name: Set fields
env:
GITHUB_TOKEN: ${{ secrets.YOUR_TOKEN }}
run: |
gh api graphql -f query='
mutation (
$project: ID!
$item: ID!
$status_field: ID!
$status_value: String!
$date_field: ID!
$date_value: String!
) {
set_status: updateProjectNextItemField(input: {
projectId: $project
itemId: $item
fieldId: $status_field
value: $status_value
}) {
projectNextItem {
id
}
}
set_date_posted: updateProjectNextItemField(input: {
projectId: $project
itemId: $item
fieldId: $date_field
value: $date_value
}) {
projectNextItem {
id
}
}
}' -f project=$PROJECT_ID -f item=$ITEM_ID -f status_field=$STATUS_FIELD_ID -f status_value=${{ env.TODO_OPTION_ID }} -f date_field=$DATE_FIELD_ID -f date_value=$DATE --silent
工作流程说明
下表说明了示例工作流程的各个部分,并向您展示了如何调整工作流程以供自己使用。
|
当仓库中的拉取请求标记为“准备审核”时,此工作流程将运行。 |
GitHub 应用程序 only:
|
使用 tibdex/github-app-token action 从应用 ID 和私钥为应用生成安装访问令牌。 稍后在工作流程中以s ${{ steps.generate_token.outputs.token }} 的形式访问安装访问令牌。
将 APP_ID 替换为包含应用 ID 的密钥的名称。
将 APP_PEM 替换为包含应用私钥的机密的名称。
|
GitHub 应用程序:
Personal access token:
|
为此步骤设置环境变量。
如果使用的是个人访问令牌,请将 YOUR_TOKEN 替换为包含个人访问令牌的机密的名称。
将 YOUR_ORGANIZATION 替换为组织名称。 例如 octo-org 。
将 YOUR_PROJECT_NUMBER 替换为项目编号。 要查找项目编号,请查看项目 URL。 例如,https://github.com/orgs/octo-org/projects/5 有一个编号为 5 的项目。
|
|
使用 GitHub CLI 查询项目 ID 的 API 以及项目前 20 个字段的 ID、名称和设置。 响应存储在一个名为 project_data.json 的文件中。
|
|
解析 API 查询的响应,并将相关 ID 存储为环境变量。 修改此选项以获取不同字段或选项的 ID。 例如:
|
GitHub 应用程序:
Personal access token:
|
为此步骤设置环境变量。 GITHUB_TOKEN 如上所述。 PR_ID 是触发此工作流程的拉取请求的 ID。
|
|
使用 GitHub CLI 和 API 将触发此工作流程的拉取请求添加到项目。 jq 标志解析了获取已创建项的 ID 的响应。
|
|
将已创建项的 ID 存储为环境变量。 |
|
以 yyy-mm-dd 格式保存当前日期为环境变量。
|
GitHub 应用程序:
Personal access token:
|
为此步骤设置环境变量。 GITHUB_TOKEN 如上所述。
|
|
将 Status 字段的值设置为 Todo 。 设置 Date posted 字段的值。
|