Open5
[デバッグ中] Github Actions でワークフローを自動化 ~ PR作成⇒関連issueのステータスを変更
背景
現在の案件では、以下の流れで開発しています。
- issueを起票。issue statusはなし。
issueには案件のProjectsを設定します。
- メンバーでissueについて話し合い、issue statusをTODOにセットする。
- issueに着手。issue statusはIn Progressにセットする。
- 実装が必要であればPRを作成。PRとissueを関連付ける。issue statusをReviewingにセットする。
- LGTMをもらったらPRをmergeする。issue statusをresolvedにセットする。issueをcloseする。
操作漏れが発生するので、GithubのWorkflow機能でなるべく自動化しています。5については自動化できています。
PRでは、bodyにclose #344
のように記載することでPRとissueを関連づけることができ、PRがmergeされたときに自動で関連するissueをcloseすることができます。
3まではフロー上、手動で問題ありません。
4についてはYAML構文を使用したワークフローを作成する必要があります。
ワークフロー ファイル作成
.github/workflows/issue-status-update.yml
というワークフロー ファイルを作成。
トリガー設定
ワークフロー開始トリガーはPRの open
, reopen
。
デバッグ用に手動で行いたいのでトリガーにworkflow_dispatch
を追加した。
name: Updating issue status
on:
workflow_dispatch:
pull_request:
types:
- opened
- reopened
jobの作成
実際に書いたコードを先に見せます。
jobs:
issue-status-update:
runs-on:
ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Authenticate GitHub CLI
run: gh auth login --with-token <<< "${{ secrets.GITHUB_TOKEN }}"
- name: Get related issue number
id: get_issue_number
run: |
PR_NUMBER=${{ github.event.number }}
ISSUE_NUMBER=$(gh pr view $PR_NUMBER --json body --jq '.body' | grep -o 'close #[0-9]\+' | grep -o '[0-9]\+')
echo "Retrieved ISSUE_NUMBER: $ISSUE_NUMBER"
echo "ISSUE_NUMBER=$ISSUE_NUMBER" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get Issue Node ID
id: get_issue_node_id
run: |
echo "ISSUE_NUMBER: ${{ env.ISSUE_NUMBER }}"
echo "Owner: ${{ github.repository_owner }}"
echo "Repo: ${{ github.event.repository.name }}"
ISSUE_NODE_ID=$(gh api graphql -f query='
query($issueNumber: Int!, $owner: String!, $repo: String!) {
repository(owner: $owner, name: $repo) {
issue(number: $issueNumber) {
id
}
}
}
' -f issueNumber=${{ env.ISSUE_NUMBER }} -f owner=${{ github.repository_owner }} -f repo=${{ github.event.repository.name }} -q '.data.repository.issue.id')
echo "ISSUE_NODE_ID=$ISSUE_NODE_ID" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get Project Item ID and Field ID
id: get_project_item_id
run: |
PROJECT_ITEM_ID=$(gh api graphql -f query='
query($issueId: ID!) {
node(id: $issueId) {
... on Issue {
projectItems(first: 1) {
nodes {
id
project {
fields(first: 10) {
nodes {
id
name
}
}
}
}
}
}
}
}
' -f issueId=${{ env.ISSUE_NODE_ID }} -q '.data.node.projectItems.nodes[0].id')
FIELD_ID=$(gh api graphql -f query='
query($issueId: ID!) {
node(id: $issueId) {
... on Issue {
projectItems(first: 1) {
nodes {
project {
fields(first: 10) {
nodes {
id
name
}
}
}
}
}
}
}
}
' -f issueId=${{ env.ISSUE_NODE_ID }} -q '.data.node.projectItems.nodes[0].project.fields.nodes | map(select(.name == "Status")) | .[0].id')
echo "PROJECT_ITEM_ID=$PROJECT_ITEM_ID" >> $GITHUB_ENV
echo "FIELD_ID=$FIELD_ID" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Update Project Status to Reviewing
run: |
gh api graphql -f query='
mutation (
$projectItemId: ID!
$fieldId: ID!
$status_value: String!
) {
updateProjectV2ItemFieldValue(input: {
projectId: "<PROJECT_ID>"
itemId: $projectItemId
fieldId: $fieldId
value: {
singleSelectOptionId: $status_value
}
}) {
projectV2Item {
id
}
}
}
' -f projectItemId=${{ env.PROJECT_ITEM_ID }} -f fieldId=${{ env.FIELD_ID }} -f status_value="Reviewing"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
runs-onは、ジョブが実行される環境を指定します。ここでは、GitHubが提供するホストランナーである ubuntu-latest を使用しています。
steps以下のnameは各ステップで何を実行しているかを示しています。
大まかな流れとしては以下です。
- リポジトリ取得
- GitHub CLIを使用してGitHubに認証
- 関連 Issue番号取得
- Issue取得
- IssueのプロジェクトIDとフィールドID取得
- IssueのStatusをRevieingにセット
リポジトリ取得
ワークフローを実行するためにリポジトリの内容をランナーにクローンします。
actions/checkout@v4
はGithubが用意しているアクションなのでそのまま使います。
ちなみに、permissionを明示的に設定すると、ここで失敗するので注意です(自分もハマりました)。
GitHub CLIを使用してGitHubに認証
ワークフローがリポジトリの内容にアクセスし、認証された状態でGitHub APIやその他のリポジトリ操作を実行できるようにします。