【初級】GitHub Actionsを使ってnuxtアプリのlint、テストを自動化する


GitHub Actionsとは

端的にいうと、GitHubが提供してくれるサーバーレスの実行環境です。

GitHub上でのpush、issueの作成などをトリガーとしてユーザーが独自で定義したアクションを実行してくれます。

アクションは複数を順序づけて実行することが可能で、そのまとまりをワークフローと呼ばれます。

アクションは実態はdockerコンテナであり、再利用などが前提とされ、公式やAWSなどの他クラウドサービスからも様々なアクションが提供されています。

例として、pushをしたらlintとtestを実行するワークフローを考えると、下記の図のようになります。

大きく3つのアクションに分けられ、実行環境上でそれらが実行されるようにユーザーがワークフローを定義します。

  1. pushしたcommit番号を取得し、checkoutする
  2. (npm install)を行って、lintを回す
  3. testを回す

今回は試しにnuxt.jsのプロジェクトを使って、実際にワークフローを作成します。

環境

筆者の環境です

  • node v12.14.1
  • npm v6.13.4
  • yarn v1.21.1
  • nuxt.js v2.11.0
    • create-nuxt-appでESLint、Jestをインストールしてプロジェクトを用意しました。

記事の最後にgithubのリポジトリも載せておきます。

作成するワークフローの確認

今回はESLintとJestを自動で実行するようなワークフローを作成します。

実際に作ってみてのすごく個人的なワークフロー作成時のコツですが、when(いつ), what(何をする)で大まかな流れを考え、whatを細分化して考えるのがまとまりやすくて良いです。

今回は、マージリクエストの作成、commit時にlintとtestを実行するワークフローと定義します。

lintとtestの実行とは、
1. マージリクエストの最新のcommitの取得
2. node packageのinstall
3. package.jsonに定義された、lintの実行
4. package.jsonに定義された、jestの実行

ワークフローの作成

下記ymlが実際に作成したワークフローです。
作成するのはこの1ファイルで完結します。

.github/workflows/lint-test.yml

name: Check code using lint and test, when push a commit
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  run_lint_and_test:
    runs-on: ubuntu-18.04
    strategy:
      matrix:
        node: [ '12.14.1' ]
    timeout-minutes: 300
    steps:
      - name: checkout pushed commit
        uses: actions/checkout@v2
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - name: run lint and test
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node }}
      - run: yarn install
      - run: yarn lint
      - run: yarn test

他のciツールのymlなどと比べてどうかはわかりませんが、個人的にはGitHub Actionsのymlの中身は割と綺麗だと思っています。

少し要点を絞って見てみます。

ワークフローの作成するディレクトリ

.github/workflows/下に作成してあげましょう。

該当ディレクトリ内のymlをGitHub Actionsの方で認識をして、ワークフローとして登録してくれます。

実際に作成をする方法

大きく2つあります。

  1. 好きなエディターを使って自分の好きに作る。
  2. 公式GUIでサンプルを基に作成する。

1に関しては自身でディレクトリを作成し、好きに作ってcommit、pushをしてあげればOKです。

2に関しては、自身のGitHubのリポジトリページからweb上でワークフローの作成が行うことができます。

  • リポジトリのメニューからActionsを選択

  • 基となるサンプルを選ぶ

  • web上のエディターでサンプルを書き換える

こんな感じでワークフローの作成も行えます。

サンプルがなかなか豊富で様々な種類あるので、一度見て書き方を理解する、その後自分で作成する、といったプロセスが良いかもしれません。

yml内の記述

全部は説明しきれませんが、要点絞って説明します。

詳しくは公式のドキュメントがあるので、そちらを読んでみてください。

onでトリガーを記述する

該当箇所


name: Check code using lint and test, when push a commit
on:
  # プルリクエストが作成、もしくはcommitが更新されたら実行するワークフロー
  pull_request:
    types: [opened, synchronize]

コメントで書いてある通り、プルリクエストが生成、プルリクエストに対してのcommitをトリガーにワークフローを実施したい場合はこのように記述します。

マージリクエストの他にももちろんGitHub上での動作を大体はトリガーにできるのではないかと思います。

  • タグを作成、pushされる
  • Projectが作成、削除される
  • 任意の時間帯をcronのように指定

またタグやブランチ名の指定、条件に一致したタグ名の場合のみなどの条件指定も可能です。

jobsに実行したいワークフローを書いていく

該当箇所


jobs:
  run_lint_and_test:
    runs-on: ubuntu-18.04
    strategy:
      matrix:
        node: [ '12.14.1' ]
    timeout-minutes: 300
    steps:
      - name: checkout pushed commit
        uses: actions/checkout@v2
        with:
          # 該当するプルリクの最新のcommitを取得
          ref: ${{ github.event.pull_request.head.sha }}
      - name: run lint and test
        # nodeの実行環境を用意する
        uses: actions/setup-node@v1
        with:
          # nodeのバージョンはwith内で指定できる
          node-version: ${{ matrix.node }}
      - run: yarn install
      - run: yarn lint
      - run: yarn test

runs-onはワークフローの実行環境を指定します。
ubuntuとwindows、macOSから指定することが現時点で可能です。

stepsが実行されるワークフローです。
usesが実行されるアクションひとつひとつになり、上から順番に実行されます。

記事書きながら、lintとtestでアクション分ける必要なくrunしてあげてもよかったのではと思います。

usesの指定の仕方は、大きく3パターンに分けられています。

  1. すでに用意されているGitHubのパブリックリポジトリからの指定

GitHubの方で汎用的なアクションが用意されています。
- 指定したタグでチェックアウトする
- AWS利用のための認証

GitHub Actions公式AWS関連など、本当に色々用意されています。

# checkoutする
# https://github.com/actions/checkout
uses: actions/checkout@v2
# nodeの実行環境を用意する
# https://github.com/actions/setup-node
uses: actions/setup-node@v1
  1. DockerHubで公開されているimageを指定
uses: docker://alpine:3.8
  1. 自分でアクションを作成してパスを指定

自身でdockerfileを作成してアクションを自作することが可能です。
別の機会でこちらも紹介します。

uses: ./.github/actions/my-action

runで実行するコマンドを指定する

該当箇所

      - run: yarn install
      - run: yarn lint
      - run: yarn test

動作確認

実際にnuxt.js + GitHub Actionsのサンプルを作成しました。下記リポジトリになります。

実際にわざとlintの通らないcommitをしてマジリクを作ってみます。

マージリクエストの画面の、マージボタンのあたりで作成したワークフローが頑張ってくれてるのがわかります。

そして無事落ちましたね!無事動いて事前に問題を検知できるので良きですね!

実際になんで落ちたのか、アクションの詳細はActionsタブから確認することができます。
failedの要因がわかるので、debugできます。

またSettiings > Branchesから、指定したcheckが通らないとマージできないようにするなどの設定が可能です。

これで誤ってのマージを防ぐこともできます。安心安心。

終わり

いかがだったでしょうか?

  • GitHubのみでこうしたCI/CDのような動きができること
  • Runner用のインスタンスを用意する必要のないこと
  • 無料枠も存在する(publicなら完全無料、privateなら2,000分/月)

やれることの幅も広いので、GitHubを利用している方に是非オススメしたいです。
普段アプリケーション側を書いている筆者もドキュメント見ながら書けて、何より自動化していくことの楽しさ、良さを改めて実感することができました。
今後も個人でちょくちょく触っていきたいです。(マージリクエストごとのプレビュー環境作ったり、Railsのrspec実行を自動化するためのAction自作などやってみます。)