dip Engineer Blog

Engineer Blog
ディップ株式会社のエンジニアによる技術ブログです。
弊社はバイトル・はたらこねっとなど様々なサービスを運営しています。

GitHub Actionsでリリースノート作成を自動化してみた

はじめに

こんにちは、PHPで求人系サービスの開発や社内向けツールの開発を行なっている @taku-0728 です。
今回はGitHub Actionsについて記事を書きました。
この記事を書くまで全然知らなかったので実際に触ってみて、成果物としてリリースノート作成を自動化するワークフローを作ります。
同じように「GitHub Actions便利そうだし触ってみたいけどよくわからない...」という方が実際に触ってみるきっかけになればいいと思います。
よろしくお願いいたします。

GitHub Actionsとは

GitHub Actionsは、コードを保存するのと同じ場所でソフトウェア開発のワークフローを自動化し、プルリクエストやIssueで協力することを支援します。 個々のタスクを書き、アクションを呼び出し、それらを組み合わせてカスタムのワークフローを作成できます。ワークフローとは、GitHubで任意のコードプロジェクトをビルド、テスト、パッケージ、リリース、またはデプロイするためにリポジトリで設定できる、カスタムの自動プロセスです。

GitHub Actionsについてより

詳しくは上記サイトに載っていますが、要はPull RequestやIssueやPushなどのイベントをトリガーとして、ビルド、テスト、パッケージ、リリースを自動で行ってくれるものです。

背景

どのチームでもそうかもしれませんが、私のチームでは本番リリース作業終了時にGithubにリリースノートを作成しています。この作業ですがリリースの度に発生するにもかかわらず、毎回手動で作成しているので何かルールや仕組みで自動化できないかと思っていました。
リリースノートに書かれた説明とリリース用のプルリクエストの説明の文言が似ていたので、これは1つに統合したいと考えGitHub Actionsを使って自動化に挑戦しました。

今回作るもの

今回はすでに公開されているcreate-releaseを書き変えて、「masterブランチをベースにしたプルリクエストが作成されたとき、そのプルリクエストのタイトルをタグ名とし、そのプルリクエストの本文をリリースの説明としてドラフトリリースを作成する」ワークフローを作ります。

実際に作ってみる

ワークフローを設定する

  1. リポジトリ/.github/配下にworkflowsディレクトリを作ります。
    $ mkdir {リポジトリ名}/.github/workflows

  2. 1で作成したworkflowsディレクトリの配下にtest.ymlファイルを作成し、create-releaseを参考に下記のように記載します。

on:
  push:
    tags:
      - 'v*'

name: Create Release

jobs:
  build:
    name: Create Release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@master
      - name: Create Release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: Release ${{ github.ref }}
          body: |
            Changes in this Release
            - First Change
            - Second Change
          draft: false
          prerelease: false

詳細はGitHub Actionsのワークフロー構文にリファレンスがありますがざっくり説明すると

on:
  push:
    tags:
      - 'v*'

まず1行目のonでどのイベントをトリガーとして動作するかを指定します。2行目にpushを記載されているので、ここではpushイベントがトリガーとして動作します。3行目と4行目にそれぞれtagsv*とあるので今回は「先頭がvのタグがpushされると動作する」という意味になります。

name: Create Release

jobs:
  build:
    name: Create Release
    runs-on: ubuntu-latest

ここの先頭のnameでこのワークフローに名前をつけ、jobsから実際のワークフロー処理に入っていきます。buildはこのジョブのIDですので、任意の文字列で大丈夫です。次のnameはこのジョブの名前です。その次のruns-onではこのジョブを実行するマシンの種類を設定します。macOSやWindowsも指定できますが、ここではUbuntuの最新版を指定します。

steps:
  - name: Checkout code
    uses: actions/checkout@master
  - name: Create Release
    id: create_release
    uses: actions/create-release@v1
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    with:
      tag_name: ${{ github.ref }}
      release_name: Release ${{ github.ref }}
      body: |
        Changes in this Release
        - First Change
        - Second Change
      draft: false
      prerelease: false

実際に処理を行っている部分です。 ここで行っていることは大きく分けて2つあります。

- name: Checkout code
  uses: actions/checkout@v2

上のnameでこの処理に名前をつけ、uses:で既に公開されているアクションを使用できます。今回はブランチをチェックアウトしてくれる既存アクションのactions/checkoutを使用します。

- name: Create Release
  id: create_release
  uses: actions/create-release@master
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  with:
    tag_name: ${{ github.ref }}
    release_name: Release ${{ github.ref }}
    body: |
      Changes in this Release
      - First Change
      - Second Change
    draft: false
    prerelease: false

今回の本題となる実際にリリースを作成している部分です。
envでは環境変数を指定できます。今回はGitHub Actionsを使うときに機密情報を保持するためのsecrets配下のGITHUB_TOKENを指定していますが、Action側で生成されるため自身で用意する必要はありません。
withではこのアクションに対する入力値を指定します。${{ github.ref }}はワークフローの実行をトリガーしたブランチまたはタグ名が入ります。詳しくはこちら
bodyにはこのリリースの説明が入ります。
draftはドラフトリリースにするかどうかを示し、prereleaseはプレリリースにするかどうかを示します。

以上がcreate-releaseのテンプレートです。
今回はトリガーにタグを指定しているため、実際にタグをpushしてみます。

$ git tag -a v1.0 -m 'auto release test'
$ git push origin v1.0

Github上で確認してみます。

期待通りのリリースが登録されているはずです。
自動化はできましたが、このままではリリースの内容が固定値しか入れられないので今回は

・トリガー:masterブランチをベースにしたプルリクエストが作成されたとき
・タグ名:そのプルリクエストのタイトル
・リリース内容:そのプルリクエストの本文

となるようにこのワークフローを書き換えていきます。

ワークフローを編集する

まずトリガーをタグのpushからプルリクエストの作成に書き変えます。 先ほどのコードの

on:
  push:
    tags:
      - 'v*'

ここを

on:
  pull_request:
    types: [opened]
    branches:
      - master

このように書き換えます。これでmasterブランチをベースとしたプルリクエストが作成された時にワークフローが動作するようになります。 そして

with:
  tag_name: ${{ github.ref }}
  release_name: Release ${{ github.ref }}
  body: |
    Changes in this Release
    - First Change
    - Second Change
  draft: false
  prerelease: false

ここの部分を

with:
  tag_name: ${{ github.event.pull_request.title }}
  release_name: ${{ github.event.pull_request.title }}
  body: ${{ github.event.pull_request.body }}
  draft: true
  prerelease: false

このように書き換えます。 これでタグ名とリリースの名前がプルリクエストのタイトルに、 リリース内容がプルリクエストの説明になり、ドラフトリリースが適用されます。
最終的なymlファイルの内容は下記になります。

name: リリースの自動作成
on:
  pull_request:
    types: [opened]
    branches:
      - master
jobs:
  auto_release:
    name: auto_release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@master
      - name: Create Release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.event.pull_request.title }}
          release_name: ${{ github.event.pull_request.title }}
          body: ${{ github.event.pull_request.body }}
          draft: true
          prerelease: false

実際にプルリクエストを作ってみると、タイトルと本文を基にしたドラフトリリースが作成されているはずです。

まとめ

今回はリリース作業の中で自動化できそうな作業をみつけたので、GitHub Actionsを使って自動化に挑戦しました。 GitHub Actionsについてこの記事を書くまで全然知らなかったのですが、いざ触ってみると色々便利なことに気づきました。同じように触ってみたいけどよくわからない方の参考になれば幸いです。
(本当はプルリクエストがマージされたらドラフトリリースをリリースするところまでやりたかったのですが、思ったより詰まったのと長くなりそうなので別の記事でやります。)

参考

筆者

https://dippeople.dip-net.jp/6818/dippeople.dip-net.jp (写真右)