これはHubble Advent Calendar 2023の14日目1の記事です。
はじめに
再びこんにちは!株式会社Hubbleでバックエンドのエンジニアをしている@oaktomeです。
Hubble Advent Calendar 2023では4日目の記事ぶりの2回目の投稿となります。
私たちが作っているHubbleというサービスは、契約書をGitのように自動でバージョン管理したい!という着想から始まりました。
そんな開発には欠かせないGitと代表的なホスティングサービスであるGitHub。
GitHubを有効的に使う手段として、GitHub Actionsによるワークフローの自動化は欠かせないです。
今回はHubbleで実際に使っているGitHub ActionsのWorkflowスクリプトの中から3つほど紹介したいと思います!
Workflow 3選
Hotfix PRのオートマージ
name: Hotfix PR auto merge to staging and develop
on:
pull_request:
branches:
- main
types: [closed]
jobs:
create_pr:
runs-on: ubuntu-latest
if: github.event.pull_request.merged == true && startsWith(github.head_ref, 'hotfix/')
steps:
- name: Checkout Main Branch
uses: actions/checkout@v3
with:
ref: main
fetch-depth: 0
- name: Generate token
id: generate-token
uses: tibdex/github-app-token@v1
with:
app_id: ${{ secrets.PR_APPROVER_APP_ID }}
private_key: ${{ secrets.PR_APPROVER_PRIVATE_KEY }}
- name: Create Master to Staging Pull Request
id: create-master-to-staging-pull-request
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: PULL_REQUEST_URI=$(gh pr create -B staging -t "Master -> Staging" -b "PR created by GithubActions")
- name: Approve Master to Staging Pull Request
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: gh pr review ${{steps.create-master-to-staging-pull-request.outputs.PULL_REQUEST_URI}} --approve
- name: Merge Master to Staging Pull Request
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh pr merge ${{steps.create-master-to-staging-pull-request.outputs.PULL_REQUEST_URI}} --merge --auto
# これ以降は同じ手順をStaging to Developで繰り返すので割愛
解説
HubbleのBackendリポジトリではブランチ戦略として主にGit-flowでマルチステージ(Main, Staging, Develop)を採用しています。
(ちなみにFrontendチームではBranch戦略をGit-flowからトランクベースに変更しており、その話を今回のAdvent Calendarで @KOHETs さんが紹介しているので、気になる方はチェックしてみてください!)
緊急の修正対応でhotfixブランチをmainブランチにマージした際に、内容をStaging, Developに降ろしていく必要があります。
hotfix/
から始まる名前のブランチがmainブランチにマージされた時に実行されるようにしています。
if: github.event.pull_request.merged == true && startsWith(github.head_ref, 'hotfix/')
コード以外のポイントとして、GitHub Appsで事前にPRをApproveするためのGitHub Appを用意しておくことと、リポジトリの設定でauto-mergeを有効化しておくことでApproveが必須の場合でも強制マージではなく、自然な流れでPRをマージすることが可能です。
またリポジトリのBranch rulesからRequire status checks to pass before merging
を設定しておくと、予め必須のステータスチェックを指定することができます。
改善点としては、コンフリクトが起きた場合や既にブランチ間のPRが存在する場合はエラーになるので、failure()
したときにrtCamp/action-slack-notifyなどを利用してSlackに通知を流したりすると落ちたときに気づくことができるので使いやすいと思います。
PRの自動アサイン
name: PR Auto Assignment
on:
pull_request:
types: [opened]
jobs:
Assignees:
if: ${{ github.actor != 'dependabot[bot]' }}
runs-on: ubuntu-latest
timeout-minutes: 1
steps:
- uses: actions/checkout@v3
- uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.issues.addAssignees({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
assignees: `${{ github.actor }}`
});
解説
PRを作成した際にAssigneesにPR作成者を自動で入れるスクリプトです。
このworkflowを入れるまでチームではAssigneesについてのルールはなかったので開発者によって入れる、入れないがバラバラの状態でしたが、Assigneesを入れておくとPRの一覧で絞り込みが容易で、統計にも使えるので全員に設定してほしいという思いがありました。
ただAssigneesを設定するだけスクリプトですが、そこをスムーズにクリアできたのがポイントです。
rubocopのオートフォーマット
formatter:
name: formatter
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2.2'
- name: Install dependencies
run: bundle install
- name: rubocop
run: rubocop -a
- name: Commit
uses: stefanzweifel/git-auto-commit-action@v3.0.0
with:
commit_message: Apply Code Formatter Change
ref: ${{ github.head_ref }}
解説
これはtestのjob内に含まれているものですが、rubocopのSafe auto-collect(rubcoop -a
)を実行してコミットするようにしています。
もちろん別でrubocopの実行テスト自体は組み込んでいますが、事前のタイミングで実行することで手元での実行を忘れていたときのカバーになります。
最後に
今回紹介したスクリプトに共通するのは、毎回発生していた作業を自動化するというまさにワークフローの効率化に対してのアプローチとして有効だったものです。
小さい作業であっても毎回発生するものや、チーム内で共通させたいものは、規約的にルールを設定するよりも自動化によって浸透させたほうが効率的なので、まずは自分のチームで何を改善したいのか、どこが開発のスピードを下げる要因になっているのかを探ることが重要だと思います。
GitHub Actionsを使った自動化はその一部ですが、Hubbleでは開発体験を向上させる取り組みや仕組みづくりを目指しています!
明日は @ktkr-wks さんによる投稿です!
-
平日のみの投稿なので、投稿日は20日ですが14日目の記事としています。 ↩