⚠️

GitHub ActionsとDanger JSを組み合わせて自動PRチェックを使ってみた話

2023/09/04に公開

こんにちは。
株式会社ココナラ フロントエンド開発グループの三浦です。

皆さんはこんな経験はないでしょうか?

「マージ先がdevelopになっててうっかりマージしてしまった!」
「毎回同じチェックをしてるはずなのになぜかチェックがすりぬけてしまった!」

どうです?ありますよね?
私はあります。

そんな皆さんに向けて、この記事はPull Requestを自動チェックしてくれるDangerの紹介とそれを導入してみた件についてお話したいと思います。

Dangerとは

DangerのGitHubでは以下のように語られています。

What is Danger?
Danger runs after your CI, automating your team's conventions surrounding code review.

This provides another logical step in your process, through this Danger can help lint your rote tasks in daily code review.

You can use Danger to codify your team's norms, leaving humans to think about harder problems.

(引用:Danger

つまりDangerとは、チーム内で慣習的に行われているコードレビューを自動化してくれるツールです。

DangerはDangerfileと呼ばれるスクリプトを利用して、GitHubのプルリクエスト上で実行するタスクを定義します。
ココナラのフロントエンドは主にNuxt + Vue.jsで作られているため、今回はJavaScript版のDangerJSを使用します。

Dangerの機能

Dangerには、以下のような機能があります。

  • プルリクエストのタイトルやブランチ名のチェック
  • 変更のあるファイルのチェック
  • 指定条件に一致するコメントの自動投稿
  • プルリクエストのApprove/Request Changesの自動化
  • Slackやメールでの通知機能

今回はプルリクエストのタイトルやブランチ名のチェックを例として紹介します。

GitHub Actionsとは

GitHub Actionsは、GitHubリポジトリに直接統合されたCI/CDパイプラインの機能です。
このGitHub Actionsを使用することでリポジトリ内でのビルド、テスト、デプロイなどのタスクを自動化することができます。

(引用:GitHub Actions)

GitHub ActionsでDangerを実行させるには

DangerをGitHub Actionsで実行するには、.github/workflowsディレクトリ内にYAMLファイルを作成する必要があります。

YAMLファイルには、ジョブ、ワークフロー、トリガーなどの設定が含まれます。

下記の例は機能の説明のための設定例です。

name: Danger JS
on: [pull_request]

jobs:
  build:
    name: Danger JS
    runs-on: ubuntu-latest
    permissions: write-all
    steps:
      - uses: actions/checkout@v3
      - name: Danger
        uses: danger/danger-js@11.0.2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          DANGER_DISABLE_TRANSPILATION: true

これによりGitHub Actionsはプルリクエストが作成されたタイミングで自動でDangerを実行してくれるようになります。

続いてリポジトリ直下にdangerfile.tsを作成します。

下記はプルリクエストのタイトルやブランチ名のチェックを行う実装例です。
マージ先がdevelopになっている場合に確認を促すコメントを自動で投稿してくれるようになります。

import { danger, warn, markdown } from "danger";

const IGNORE_BRANCH = ["release", "revert"];
// マージされるブランチ名
const baseBranch = danger.github.pr.base.ref;
// マージするブランチ名
const headBranch = danger.github.pr.head.ref;

function checkBranchName(headBranch, baseBranch) {
  // ブランチ名にrelease,revertが含む場合チェックしないフラグ
  const isCheckBranch = !IGNORE_BRANCH.find((value) =>
    headBranch.includes(value)
  );
  if (!isCheckBranch) return;

  // PRがdevelopに向いている場合注意文言を表示
  if (baseBranch.includes("develop")) {
    warn("Pull requestsの向き先確認");
    markdown(`
### ⚠️ ブランチの向き先確認!
Pull requestsの向き先が\`develop\`になっています
向き先が正しいか確認してください!
    `);
  }
}

checkBranchName(headBranch, baseBranch);

このようにDangerはimportした関数からさまざまな情報を取得できます。

DangerのREFERENCEページで取得できる情報について確認できます。

// マージされるブランチ名
const baseBranch = danger.github.pr.base.ref;
// マージするブランチ名
const headBranch = danger.github.pr.head.ref;

ここではマージするブランチとマージされるブランチの情報を取得しています。

その後checkBranchNameでマージするブランチとマージされるブランチ名を確認し、マージするブランチ名に"release", "revert"が含まれていない場合、マージされるブランチがdevelopでないことを確認する処理を定義しました。

実際に実行してみた

以上のコードを反映した状態でマージ先をdevelopでプルリクエストを作成してみます。

すると、GitHub Actionsから以下の画像のようにコメントが投稿されます。

Dangerのコメント

これによって冒頭でお話したうっかりミスの軽減が見込めるような環境が整いました。

今後の課題

上記のチェック以外にも、恒常的に行う様々なチェックが存在するため、それらを自動化していく必要があります。

また、自動化したことでBOTによる投稿コメントが形骸化していかないかというところはこれからも目を光らせていかなくてはなりません。

そのためにも導入したチェック設定は定期的にチームメンバーで検討を行いメンテナンスしていく予定です。

今後はGitHub suggested changesなどと組み合わせることで、レビューや修正コストを更に減らしていけるように取り組んでいきたいと思います。

最後に

ココナラではエンジニアを募集しています。
よろしければぜひ以下のページもご覧ください。
https://coconala.co.jp/recruit/engineer/

フロントエンドの求人はこちらです。
https://open.talentio.com/r/1/c/coconala/pages/49717

Discussion