📝
GitHub ActionsのCI/CDを華やかにするactions/github-scriptを使いこなす
イントロダクション
皆の者〜、おはこんハロチャオ〜!
medibaではバックエンド・インフラ・フロントエンド・SRE兼任で、OSSのコントリビュートもたまにしている雑用エンジニアの菅原です。
この記事は、mediba Advent Calendar 2022の3日目にエントリしています。前回のアドベントカレンダーもGitHub Actions
ネタでしたが、今回も同じ系統のネタです。
さて皆さん、GitHub Actions
でCI/CDを作っていると、やりたいことがたくさん出てきませんか?
その度に目的に見合ったactions
を探すのは非効率ですし、メンテナンスがされない可能性のあるactions
を使うのもセキュリティ等の観点から懸念がありますよね。
そこで、皆さんに紹介したいのがactions/github-script
actionです。
これさえあれば、GitHub
に対してほぼすべての操作を行えます。
とはいえ、有能なaction
にも関わらず、ググっても実用例がなかなか出てきません。
なので、この記事では、actions/github-script
actionの実用例をご紹介します。
actions/github-script
とは何者なんじゃ?
actions/github-script
とは、簡単に説明すると、Actions
のワークフロー内でJavaScript
で記述できてGitHub API
をコールできるすごい奴です。
actions/github-script
の実用例
プルリクエストがopenされたときにメンション付きでコメントする
name: Comment opening announce
on:
pull_request:
branches:
- 'staging'
types:
- opened
jobs:
comment_opening_announce:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: Set up opening announce
id: opening_announce
run: |
lf='\n'
message="@${{ github.event.pull_request.user.login }} さん、デプロイプルリクエストの作成ありがとうございます! :tada:"
message+="${lf}${lf}ステージング環境へのデプロイは下記の手順で行ってください。"
message+="${lf}1. リリース予定の\`feature\`ブランチを\`release\`ブランチにマージします。"
message+="${lf}1. \`ready-for-build\`ラベルを付けます。"
message+="${lf}1. \`github-actions\`ボットのプルリクエストに対するアクションを待ちます。"
message+="${lf} - \`approve\`された場合、\`staging\`ブランチにマージします。"
message+="${lf} - \`ready-for-build\`ラベルが剥がされた場合、原因を特定して手順2からやり直してください。"
message+="${lf}${lf}プルリクエストをマージすると、ステージング環境にデプロイが行われます。 :rocket:"
message+="${lf}\`github-actions\`ボットから\`approve\`された後にプルリクエストを更新した場合は、"
message+="${lf}\`ready-for-build\`ラベルを付ける手順からやり直してください。"
echo "message=${message}" >> $GITHUB_OUTPUT
- name: Comment opening announce
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const params = {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: '${{ steps.opening_announce.outputs.message }}'
}
await github.rest.issues.createComment(params)
ワークフロー実行後イメージ
プルリクエストにコメントしてcloseする
name: Close pull request
on:
pull_request:
branches:
- 'production'
types:
- opened
- synchronize
- reopened
jobs:
close_pull_request:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: Set up closed announce
id: closed_announce
run: |
lf='\n'
message="おや?ステージング環境にデプロイしていないようです :worried:"
message+="${lf}商用環境へのデプロイプルリクエストは、ステージング環境で検証してから作成しましょう! :smiley:"
echo "message=${message}" >> $GITHUB_OUTPUT
- name: Comment closed announce
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const params = {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: '${{ steps.closed_announce.outputs.message }}'
}
await github.rest.issues.createComment(params)
- name: Closed pull request
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const params = {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
state: 'closed',
}
await github.rest.pulls.update(params)
ワークフロー実行後イメージ
プルリクエスト更新時に特定のラベルを剥がす
name: Remove special label from pull request
on:
pull_request:
branches:
- 'staging'
types:
- synchronize
jobs:
remove_special_label:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: Remove special label
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
for (const label of context.payload.pull_request.labels) {
if (!label.name.startsWith("ready-for-build")) {
continue
}
const params = {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
name: label.name
}
await github.rest.issues.removeLabel(params)
}
ワークフロー実行後イメージ
プルリクエストをApproveする
name: Approved pull request
on:
pull_request:
branches:
- 'staging'
types:
- synchronize
jobs:
approved_pull_request:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: Set up pull request approved comment
id: pr_approved_comment
run: |
base_ref="${{ github.event.pull_request.base.ref }}"
head_sha="${{ github.event.pull_request.head.sha }}"
lf='\n'
message="## :pushpin: 実行結果"
message+="${lf}:white_check_mark: ビルドに成功しました。"
message+="${lf}## :information_source: 詳細情報"
message+="${lf}### :pencil: ビルドに使用したコミットハッシュ"
message+="${lf}[${head_sha}](${base_ref}...${head_sha})"
echo "message=${message}" >> $GITHUB_OUTPUT
- name: Approved pull request
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const params = {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
event: 'APPROVE',
body: '${{ steps.pr_approved_comment.outputs.message }}'
}
await github.rest.pulls.createReview(params)
ワークフロー実行イメージ
プルリクエストにRequest Changesする
name: Request changes pull request
on:
pull_request:
branches:
- 'staging'
types:
- synchronize
jobs:
approved_pull_request:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: Set up request changes comment
id: request_changes_comment
run: |
lf='\n'
message="プルリクエストの内容が更新されたので、特殊なラベルをすべて外しました! :smile:"
message+="${lf}\`ready-for-build\`ラベルを付け直してください。 :pray:"
echo "message=${message}" >> $GITHUB_OUTPUT
- name: Change requested special label
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const params = {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
event: 'REQUEST_CHANGES',
body: '${{ steps.request_changes_comment.outputs.message }}'
}
await github.rest.pulls.createReview(params)
ワークフロー実行イメージ
参考になるサイト
actions/github-script
action 関連
- マーケットプレイスのページ
- ソースコードがあるページ
-
actions/github-script
actionが使っているGitHub APIライブラリのリファレンス
GitHub Actions 関連
-
Actions
で使うgithub.event.*
やactions/github-script
で使うcontext.payload.*
の内容を調べたいときのリファレンス
- bashがきちんと動くか確認するとき(ただし、一部のコマンドを除く)のテストサイト
最後に
mediba ではエンジニア職を含めて幅広い業種を絶賛募集中です。
OSS コントリビューターと一緒に働きたい方からの沢山の応募お待ちしております。
明日の担当
4日目は、私と同じバックエンドエンジニアの井上さんです。
今年のやらかしの供養という面白そうな記事なので、みなさんも見てみてくださいね。
Discussion