GitHub Projects を Actions で自動化する
takeharak
チケット駆動開発で GitHub Projects を導入することになったので、Issue と Projects の紐付等の反復作業を GitHub CLI + GraphQL API を駆使して Actions ワークフローで自動化したい
今回の環境
TL;DR
1. GitHub App の作成
2. ワークフロー定義 YAML ファイルの作成
# .github/workflows/auto-track-issue.yml
+ #
+ name: Add Issue to project
+ # This workflow runs whenever a issue is opened.
+ on:
+ issues:
+ types:
+ - opened
+
+ jobs:
+ track_issue:
+ runs-on: ubuntu-latest
+ steps:
+ # Uses the [actions/create-github-app-token](https://github.com/marketplace/actions/create-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 configuration variable that contains your app ID.
+ #
+ # Replace `APP_PEM` with the name of the secret that contains your app private key.
+ - name: Generate token
+ id: generate-token
+ uses: actions/create-github-app-token@v1
+ with:
+ app-id: ${{ vars.APP_ID }}
+ private-key: ${{ secrets.APP_PEM }}
+ # Sets environment variables for this step.
+ #
+ # 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.
+ - name: Get project data
+ env:
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ ORGANIZATION: ${{ github.repository_owner }}
+ PROJECT_NUMBER: YOUR_PROJECT_NUMBER
+ # Uses [GitHub CLI](https://cli.github.com/manual/) to query the API for the ID of the project and return the name and ID of the first 20 fields in the project. `fields` returns a union and the query uses inline fragments (`... on`) to return information about any `ProjectV2Field` and `ProjectV2SingleSelectField` fields. The response is stored in a file called `project_data.json`.
+ run: |
+ gh api graphql -f query='
+ query($org: String!, $number: Int!) {
+ organization(login: $org){
+ projectV2(number: $number) {
+ id
+ fields(first:20) {
+ nodes {
+ ... on ProjectV2FieldCommon {
+ id
+ dataType
+ }
+ }
+ }
+ }
+ }
+ }' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json
+
+ # 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:
+ #
+ # - To get the ID of a field called `Team`, add `echo 'TEAM_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Team") | .id' project_data.json) >> $GITHUB_ENV`.
+ # - To get the ID of an option called `Octoteam` for the `Team` single select field, add `echo 'OCTOTEAM_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Team") |.options[] | select(.name=="Octoteam") |.id' project_data.json) >> $GITHUB_ENV`.
+ #
+ # **Note:** This workflow assumes that you have a project with a single select field called "Status" that includes an option called "Todo" and a date field called "Date posted". You must modify this section to match the fields that are present in your table.
+
+ echo 'PROJECT_ID='$(jq '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV
+ echo 'MILESTONE_FIELD_ID='$(jq '.data.user.projectV2.fields.nodes[] | select(.dataType=="MILESTONE") | .id' project_data.json)
+
+ # Sets environment variables for this step. `GH_TOKEN` is the token generated in the first step. `PR_ID` is the ID of the pull request that triggered this workflow.
+ - name: Add issue to project
+ env:
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ ISSUE_ID: ${{ github.event.pull_request.node_id }}
+ # Uses [GitHub CLI](https://cli.github.com/manual/) 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.
+ run: |
+ item_id="$( gh api graphql -f query='
+ mutation($project: ID!, $issue: ID!) {
+ addProjectV2ItemById(input: {projectId: $project, contentId: $issue}) {
+ item {
+ id
+ }
+ }
+ }' -f project=$PROJECT_ID -f issue=$ISSUE_ID --jq '.data.addProjectV2ItemById.item.id')"
+
+ # Stores the ID of the created item as an environment variable.
+ echo 'ITEM_ID='$item_id >> $GITHUB_ENV
+