Co-authored-by: Lukasz Warchol <lukewar@github.com> Co-authored-by: Sarah Edwards <skedwards88@github.com>
21 KiB
title, intro, allowTitleToDifferFromFilename, miniTocMaxHeadingLevel, versions, type, topics
| title | intro | allowTitleToDifferFromFilename | miniTocMaxHeadingLevel | versions | type | topics | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Automating projects (beta) | You can use built-in workflows or the API and {% data variables.product.prodname_actions %} to manage your projects. | true | 3 |
|
tutorial |
|
{% data reusables.projects.projects-beta %}
{% data reusables.projects.graphql-deprecation %}
Introduction
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 {% data variables.product.prodname_actions %}.
Built-in workflows
{% data reusables.projects.about-workflows %}
You can enable or disable the built-in workflows for your project.
{% data reusables.projects.enable-basic-workflow %}
{% data variables.product.prodname_actions %} workflows
This section demonstrates how to use the GraphQL API and {% data variables.product.prodname_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.
A project can span multiple repositories, but a workflow is specific to a repository. Add the workflow to each repository that you want your project to track. For more information about creating workflow files, see "Quickstart for {% data variables.product.prodname_actions %}."
This article assumes that you have a basic understanding of {% data variables.product.prodname_actions %}. For more information about {% data variables.product.prodname_actions %}, see "{% data variables.product.prodname_actions %}."
For more information about other changes you can make to your project through the API, see "Using the API to manage projects."
{% note %}
Note: GITHUB_TOKEN is scoped to the repository level and cannot access projects (beta). To access projects (beta) you can either create a {% data variables.product.prodname_github_app %} (recommended for organization projects) or a personal access token (recommended for user projects). Workflow examples for both approaches are shown below.
{% endnote %}
Example workflow authenticating with a {% data variables.product.prodname_github_app %}
-
Create a {% data variables.product.prodname_github_app %} or choose an existing {% data variables.product.prodname_github_app %} owned by your organization. For more information, see "Creating a {% data variables.product.prodname_github_app %}."
-
Give your {% data variables.product.prodname_github_app %} read and write permissions to organization projects. For more information, see "Editing a {% data variables.product.prodname_github_app %}'s permissions."
{% note %}
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.
{% endnote %}
-
Install the {% data variables.product.prodname_github_app %} in your organization. Install it for all repositories that your project needs to access. For more information, see "Installing {% data variables.product.prodname_github_apps %}."
-
Store your {% data variables.product.prodname_github_app %}'s ID as a secret in your repository or organization. In the following workflow, replace
APP_IDwith 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." -
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, replaceAPP_PEMwith the name of the secret. For more information, see "Authenticating with {% data variables.product.prodname_github_apps %}." -
In the following workflow, replace
YOUR_ORGANIZATIONwith the name of your organization. For example,octo-org. ReplaceYOUR_PROJECT_NUMBERwith your project number. To find the project number, look at the project URL. For example,https://github.com/orgs/octo-org/projects/5has a project number of 5.
{% data reusables.actions.actions-not-certified-by-github-comment %}
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: {% raw %}${{ secrets.APP_ID }}{% endraw %}
private_key: {% raw %}${{ secrets.APP_PEM }}{% endraw %}
- name: Get project data
env:
GITHUB_TOKEN: {% raw %}${{ steps.generate_token.outputs.token }}{% endraw %}
ORGANIZATION: YOUR_ORGANIZATION
PROJECT_NUMBER: YOUR_PROJECT_NUMBER
run: |
gh api graphql -f query='
query($org: String!, $number: Int!) {
organization(login: $org){
projectV2(number: $number) {
id
fields(first:20) {
nodes {
... on ProjectV2Field {
id
name
}
... on ProjectV2SingleSelectField {
id
name
options {
id
name
}
}
}
}
}
}
}' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json
echo 'PROJECT_ID='$(jq '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV
echo 'DATE_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Date posted") | .id' project_data.json) >> $GITHUB_ENV
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
echo 'TODO_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .options[] | select(.name=="Todo") |.id' project_data.json) >> $GITHUB_ENV
- name: Add PR to project
env:
GITHUB_TOKEN: {% raw %}${{ steps.generate_token.outputs.token }}{% endraw %}
PR_ID: {% raw %}${{ github.event.pull_request.node_id }}{% endraw %}
run: |
item_id="$( gh api graphql -f query='
mutation($project:ID!, $pr:ID!) {
addProjectV2ItemById(input: {projectId: $project, contentId: $pr}) {
item {
id
}
}
}' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectV2ItemById.item.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: {% raw %}${{ steps.generate_token.outputs.token }}{% endraw %}
run: |
gh api graphql -f query='
mutation (
$project: ID!
$item: ID!
$status_field: ID!
$status_value: String!
$date_field: ID!
$date_value: Date!
) {
set_status: updateProjectV2ItemFieldValue(input: {
projectId: $project
itemId: $item
fieldId: $status_field
value: {
singleSelectOptionId: $status_value
}
}) {
projectV2Item {
id
}
}
set_date_posted: updateProjectV2ItemFieldValue(input: {
projectId: $project
itemId: $item
fieldId: $date_field
value: {
date: $date_value
}
}) {
projectV2Item {
id
}
}
}' -f project=$PROJECT_ID -f item=$ITEM_ID -f status_field=$STATUS_FIELD_ID -f status_value={% raw %}${{ env.TODO_OPTION_ID }}{% endraw %} -f date_field=$DATE_FIELD_ID -f date_value=$DATE --silent
Example workflow authenticating with a personal access token
- Create a personal access token with the
projectandreposcopes. For more information, see "Creating a personal access token." - Save the personal access token as a secret in your repository or organization.
- In the following workflow, replace
YOUR_TOKENwith the name of the secret. ReplaceYOUR_ORGANIZATIONwith the name of your organization. For example,octo-org. ReplaceYOUR_PROJECT_NUMBERwith your project number. To find the project number, look at the project URL. For example,https://github.com/orgs/octo-org/projects/5has a project number of 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: {% raw %}${{ secrets.YOUR_TOKEN }}{% endraw %}
ORGANIZATION: YOUR_ORGANIZATION
PROJECT_NUMBER: YOUR_PROJECT_NUMBER
run: |
gh api graphql -f query='
query($org: String!, $number: Int!) {
organization(login: $org){
projectV2(number: $number) {
id
fields(first:20) {
nodes {
... on ProjectV2Field {
id
name
}
... on ProjectV2SingleSelectField {
id
name
options {
id
name
}
}
}
}
}
}
}' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json
echo 'PROJECT_ID='$(jq '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV
echo 'DATE_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Date posted") | .id' project_data.json) >> $GITHUB_ENV
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
echo 'TODO_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .options[] | select(.name=="Todo") |.id' project_data.json) >> $GITHUB_ENV
- name: Add PR to project
env:
GITHUB_TOKEN: {% raw %}${{ secrets.YOUR_TOKEN }}{% endraw %}
PR_ID: {% raw %}${{ github.event.pull_request.node_id }}{% endraw %}
run: |
item_id="$( gh api graphql -f query='
mutation($project:ID!, $pr:ID!) {
addProjectV2ItemById(input: {projectId: $project, contentId: $pr}) {
item {
id
}
}
}' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectV2ItemById.item.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: {% raw %}${{ secrets.YOUR_TOKEN }}{% endraw %}
run: |
gh api graphql -f query='
mutation (
$project: ID!
$item: ID!
$status_field: ID!
$status_value: String!
$date_field: ID!
$date_value: Date!
) {
set_status: updateProjectV2ItemFieldValue(input: {
projectId: $project
itemId: $item
fieldId: $status_field
value: {
singleSelectOptionId: $status_value
}
}) {
projectV2Item {
id
}
}
set_date_posted: updateProjectV2ItemFieldValue(input: {
projectId: $project
itemId: $item
fieldId: $date_field
value: {
date: $date_value
}
}) {
projectV2Item {
id
}
}
}' -f project=$PROJECT_ID -f item=$ITEM_ID -f status_field=$STATUS_FIELD_ID -f status_value={% raw %}${{ env.TODO_OPTION_ID }}{% endraw %} -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.
|
This workflow runs whenever a pull request in the repository is marked as "ready for review". |
|
{% data variables.product.prodname_github_app %} only: |
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 {% raw %}${{ steps.generate_token.outputs.token }}{% endraw %}.
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.
|
|
{% data variables.product.prodname_github_app %}: Personal access token: |
Sets environment variables for this step.
If you are using a personal access token, replace YOUR_TOKEN with the name of the secret that contains your personal access token.
Replace YOUR_ORGANIZATION with the name of your organization. For example, octo-org.
Replace YOUR_PROJECT_NUMBER with your project number. To find the project number, look at the project URL. For example, https://github.com/orgs/octo-org/projects/5 has a project number of 5.
|
|
Uses {% data variables.product.prodname_cli %} to query the API for the ID of the project and return the name and ID of the first 20 fields in the project. The response is stored in a file called |
|
Parses the response from the API query and stores the relevant IDs as environment variables. Modify this to get the ID for different fields or options. For example:
|
|
{% data variables.product.prodname_github_app %}: Personal access token: |
Sets environment variables for this step. GITHUB_TOKEN is described above. PR_ID is the ID of the pull request that triggered this workflow.
|
|
Uses {% data variables.product.prodname_cli %} and the API to add the pull request that triggered this workflow to the project. The jq flag parses the response to get the ID of the created item.
|
|
Stores the ID of the created item as an environment variable. |
|
Saves the current date as an environment variable in yyyy-mm-dd format.
|
|
{% data variables.product.prodname_github_app %}: Personal access token: |
Sets environment variables for this step. GITHUB_TOKEN is described above.
|
|
Sets the value of the Status field to Todo. Sets the value of the Date posted field.
|