自动化项目(测试版)

You can use built-in workflows or the API and GitHub Actions to manage your projects.

Note: Projects (beta) is currently in public beta and subject to change.

简介

You can add automation to help manage your project. Projects (beta) includes built-in workflows that you can configure through the UI. Additionally, you can write custom workflows with the GraphQL API and GitHub Actions.

Built-in workflows

Projects (beta) includes built-in workflows that you can use to update the Status of items based on certain events. For example, you can automatically set the status to Todo when an item is added to your project or set the status to Done when an issue is closed.

When your project initializes, two workflows are enabled by default: When issues or pull requests in your project are closed, their status is set to Done, and when pull requests in your project are merged, their status is set to Done.

You can enable or disable the built-in workflows for your project.

  1. In your project, click .
  2. Under Default workflows, click on the workflow that you want to edit.
  3. If the workflow can apply to both issues and pull requests, next to When, check the item type(s) that you want to act on.
  4. Next to Set, choose the value that you want to set the status to.
  5. If the workflow is disabled, click the toggle next to Disabled to enable the workflow.

GitHub Actions workflows

This section demonstrates how to use the GraphQL API and GitHub Actions to add a pull request to an organization project. In the example workflows, when the pull request is marked as "ready for review", a new task is added to the project with a "Status" field set to "Todo", and the current date is added to a custom "Date posted" field.

You can copy one of the workflows below and modify it as described in the table below to meet your needs.

项目可以跨越多个仓库,但工作流是特定于仓库的。 Add the workflow to each repository that you want your project to track. 有关创建工作流程文件的更多信息,请参阅“GitHub Actions 快速入门”。

本文假设您基本了解 GitHub Actions。 有关 GitHub Actions 的更多信息,请参阅“GitHub Actions”。

有关可以通过 API 对项目进行的其他更改的更多信息,请参阅“使用 API 管理项目”。

Note: GITHUB_TOKEN is scoped to the repository level and cannot access projects (beta). To access projects (beta) you can either create a GitHub 应用程序 (recommended for organization projects) or a personal access token (recommended for user projects). Workflow examples for both approaches are shown below.

Example workflow authenticating with a GitHub 应用程序

  1. Create a GitHub 应用程序 or choose an existing GitHub 应用程序 owned by your organization. For more information, see "Creating a GitHub 应用程序."

  2. Give your GitHub 应用程序 read and write permissions to organization projects. For more information, see "Editing a GitHub 应用程序's permissions."

    Note: You can control your app's permission to organization projects and to repository projects. You must give permission to read and write organization projects; permission to read and write repository projects will not be sufficient.

  3. Install the GitHub 应用程序 in your organization. Install it for all repositories that your project needs to access. For more information, see "Installing GitHub 应用程序."

  4. Store your GitHub 应用程序's ID as a secret in your repository or organization. In the following workflow, replace APP_ID with the name of the secret. You can find your app ID on the settings page for your app or through the App API. For more information, see "Apps."

  5. Generate a private key for your app. Store the contents of the resulting file as a secret in your repository or organization. (Store the entire contents of the file, including -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY-----.) In the following workflow, replace APP_PEM with the name of the secret. For more information, see "Authenticating with GitHub 应用程序."

  6. In the following workflow, replace YOUR_ORGANIZATION with the name of your organization. 例如 octo-org。 Replace YOUR_PROJECT_NUMBER with your project number. 要查找项目编号,请查看项目 URL。 例如,https://github.com/orgs/octo-org/projects/5 有一个编号为 5 的项目。

YAML
# 此工作流使用未经 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

Example workflow authenticating with a personal access token

  1. Create a personal access token with org:write scope. 更多信息请参阅“创建个人访问令牌”。
  2. Save the personal access token as a secret in your repository or organization.
  3. 在以下工作流程中,将 YOUR_TOKEN 替换为密码名称。 Replace YOUR_ORGANIZATION with the name of your organization. 例如 octo-org。 Replace YOUR_PROJECT_NUMBER with your project number. 要查找项目编号,请查看项目 URL。 例如,https://github.com/orgs/octo-org/projects/5 有一个编号为 5 的项目。
YAML
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

Workflow explanation

The following table explains sections of the example workflows and shows you how to adapt the workflows for your own use.

on:
  pull_request:
    types:
      - ready_for_review
当仓库中的拉取请求标记为“准备审核”时,此工作流程将运行。

GitHub 应用程序 only:

- name: Generate token
  id: generate_token
  uses: tibdex/github-app-token@36464acb844fc53b9b8b2401da68844f6b05ebb0
  with:
    app_id: ${{ secrets.APP_ID }}
    private_key: ${{ secrets.APP_PEM }}
Uses the tibdex/github-app-token action to generate an installation access token for your app from the app ID and private key. The installation access token is accessed later in the workflow as ${{ steps.generate_token.outputs.token }}.

Replace APP_ID with the name of the secret that contains your app ID.

Replace APP_PEM with the name of the secret that contains your app private key.

GitHub 应用程序:

env:
  GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
  ORGANIZATION: YOUR_ORGANIZATION
  PROJECT_NUMBER: YOUR_PROJECT_NUMBER

Personal access token:

env:
  GITHUB_TOKEN: ${{ secrets.YOUR_TOKEN }}
  ORGANIZATION: YOUR_ORGANIZATION
  PROJECT_NUMBER: YOUR_PROJECT_NUMBER
为此步骤设置环境变量。

If you are using a personal access token, replace YOUR_TOKEN with the name of the secret that contains your personal access token.

YOUR_ORGANIZATION 替换为组织名称。 例如 octo-org

YOUR_PROJECT_NUMBER 替换为项目编号。 要查找项目编号,请查看项目 URL。 例如,https://github.com/orgs/octo-org/projects/5 有一个编号为 5 的项目。
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
使用 GitHub CLI 查询项目 ID 的 API 以及项目前 20 个字段的 ID、名称和设置。 响应存储在一个名为 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
解析 API 查询的响应,并将相关 ID 存储为环境变量。 修改此选项以获取不同字段或选项的 ID。 例如:
  • 要获取名为 Team 的字段的 ID,请添加 echo 'TEAM_FIELD_ID='$(jq 'data. rbodiation.projectNext.fields.nodes[] | select(.name== "Team") | .id' project_data.json) >> $GITHUB_ENV
  • 要为 Team 字段获取名为 Octoteam 的选项的 ID,请添加 echo 'OCTOTEAM_OPTION_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Team") |.settings | fromjson.options[] | select(.name=="Octoteam") |.id' project_data.json) >> $GITHUB_ENV
注意:此工作流假定您有一个名为“状态”的单选字段,其中包括一个名为“待办”的选项和一个名为“发布日期”的日期字段。 您必须修改此部分以匹配表中存在的字段。

GitHub 应用程序:

env:
  GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
  PR_ID: ${{ github.event.pull_request.node_id }}

Personal access token:

env:
  GITHUB_TOKEN: ${{ secrets.YOUR_TOKEN }}
  PR_ID: ${{ github.event.pull_request.node_id }}
为此步骤设置环境变量。 GITHUB_TOKEN 如上所述。 PR_ID 是触发此工作流程的拉取请求的 ID。
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')"
使用 GitHub CLI 和 API 将触发此工作流程的拉取请求添加到项目。 jq 标志解析了获取已创建项的 ID 的响应。
echo 'ITEM_ID='$item_id >> $GITHUB_ENV
将已创建项的 ID 存储为环境变量。
echo "DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV
yyy-mm-dd 格式保存当前日期为环境变量。

GitHub 应用程序:

env:
  GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}

Personal access token:

env:
  GITHUB_TOKEN: ${{ secrets.YOUR_TOKEN }}
为此步骤设置环境变量。 GITHUB_TOKEN 如上所述。
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
Status 字段的值设置为 Todo。 设置 Date posted 字段的值。

此文档对您有帮助吗?

隐私政策

帮助我们创建出色的文档!

所有 GitHub 文档都是开源的。看到错误或不清楚的内容了吗?提交拉取请求。

做出贡献

或者, 了解如何参与。