NHN Cloud NHN Cloud Meetup!

TOAST UI GridとGitHub Actionsが一緒になったら?

GitHub Actionsとは?

GitHub Actionsは、GitHubで昨年末に全体公開された、開発ワークフローをGitHubで自動化できるようにサポートするツールです。コードのバージョン管理、レビューだけでなく、テスト、構築、配布などをGitHubで管理できるようになり、従来使用していたCIツール(Jenkins、Travis CI、CircleCI)が行っていた役割を、ある程度GitHubで実行できるようになります。言語もNode.js、Python、Java、PHP、Ruby、C/C++、.NET、Android、iOSなどをサポートしており、今後も拡張される予定です。

アクションでワークフローをコードで管理し、修正して簡単に適用することができます。速いスピードと統合された環境で作業できることは大きな魅力となるでしょう。GitHub Actionsにはさまざまに強力な機能が存在しますが、そのうち複数の環境で複数バージョンをテストできるmatrixについて、簡単に見ていきたいと思います。

jobs:
  test:
    name: Test on node ${{ matrix.node_version }} and ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        node_version: [8, 10, 12]
        os: [ubuntu-latest, windows-latest, macos-latest]

    steps:
    - uses: actions/checkout@v1

    - name: Use Node.js ${{ matrix.node_version }}
      uses: actions/setup-node@v1
      with:
        version: ${{ matrix.node_version }}

    - name: npm install, build and test
      run: |
        npm install
        npm run build --if-present
        npm test

複数のノードバージョンとOS環境で並列的にnpmをインストールし、ビルドしてテストします。このように、テスト結果はすぐにアクションタブから確認できます。

サクサク動く姿をリアルタイムで見ることができます。

いつアクションが発生するのか?

主にwebhook(ウェブフック)によって発生します。ウェブフックは、GitHubにpushやPR(プルリクエスト)が届くとイシューが作成され、イシューにコメントが登録されたり、ラベルやマイルストーンが変更されたりした際に通知してくれます。単にそのイベントだけでなく、より具体的に削除や追加されたときなどを指定してアクションを発生させることができます。さらに個人がウェブフックを作ることも可能です。

# pushやprが発生したときにワークフローを実行
on: [push, pull_request]

# イシューが登録、修正されたり、マイルストーンが指定されたときにワークフローを実行
on:
  issues:
    types: [opened, edited, milestoned]

また、スケジューリングもサポートします。POSIXクローン構文で作成しましょう。時間は最小5分間隔まで可能です。

on:
  schedule:
    - cron:  '*/15 * * * *'

そのほかに、外部のdispatchも実行させることができます。

on: repository_dispatch

料金は?

オープンソースは無料で、プライベートの場合は1分当たりの使用時間で計算します。

アラート

また、メールでアラートを受け取るように登録していなくても、イシューが生じると登録されたメールに当該ワークフローの結果が送信されます。

このほか、フックを利用してメッセンジャーで通知させることも可能です。

TOAST UI Grid ワークフローを作成する

TOAST UI GridはNHNで開発しているオープンソースです。ここからはTOAST UI Gridの保守管理者になったつもりで想像してみましょう。まず、開発した誰かがPRを作成しました。外部のコントリビューターであったり、NHNの開発者であったりするでしょう。PRが上がってくると、作業ブランチにマージする前のコードレビューなど、いくつかのテストが存在します。サンプルをあげてみましょう。

1.修正事項が部門別のスタイルルールにマッチしているか
2.作成した(あるいは作成された)テストがうまく通過するか
3ビルド上の問題がないか、など

このとき問題が発生したら、GitHubのブランチポリシーを使ってマージすればよいでしょう。現在は、このような役割をローカル環境に構築されたJenkinsで自動化しています。これらをGitHub Actionsが実行するように簡単にワークフローを作成してみました。

ワークフロー作成

テストはtui.gridをフォークした個人リポジトリで行いました。

設定ファイルを作成するためにアクションタブに入ってみましょう。簡単に使えるように、さまざまな環境のテンプレートが提供されています。

ここで使用したい環境を選択して、拡張したり直接ワークフローを作成することができます。上記で整理したワークフローを、実行する日別にもう少し具体化してみましょう。私たちはESLint静的解析をする必要があり、Cypressをテストする必要があったので、Node.js環境で作業しました。(Cypressの場合、提供されているワークフローが存在しますが(リンク)、モノリシックリポジトリのイシューにより制限があるようで、Node環境から直接作成しました。イシューを作成したので、後で回答がきたらどのように解決するか作成します。(イシューリンク

作る前に、もう少し具体的に自動化について整理してみましょう。

  1. テスト準備
    1. ノードバージョン選択
    2. 全体npmインストール
    3. package/toast-ui.grid npmインストール
  2. ESLint分析
  3. Cypress E2Eテスト

全体の流れをworkflow、上記の各タスクをjob、これらのjobが実行される順序をstepと呼びます。それではワークフローを作成しましょう。作るのはそれほど難しくはありません。.github/workflows/パスにymlファイルを作成します。(設定ファイルはエディタで作成しても構いませんが、フォーマット自動補完を提供するため、個人的にはGitHubウェブ上で作成することをお勧めします。)

では、作成したymlファイルを見てみましょう。

name: PR # workflowの名前。それぞれのjobを明示するときもnameで作成します。
on: pull_request # いつアクションが発生するかを示す。さまざまな状況で発生させたい場合は配列の形で作成します。
jobs: 
  test:
    name: eslint & E2E test
    runs-on: ubuntu-16.04
    steps:
      - uses: actions/checkout@v1 # usesは使用するアクションとバージョンを選択します。詳しくは下記リンク1を参照。
      - name: Use Node.js 10.x
        uses: actions/setup-node@v1
        with:
          node-version: '10.x'
      - name: npm install(root dir) # 全体npmインストール
        run: |
          npm install
      - name: npm install(toast.ui-grid) # パッケージ内npmインストール
        working-directory: ./packages/toast-ui.grid # working-directoryで作業が行われるパスを指定します。
        run: |
          npm install
      - name: eslint # ESLint静的分析
        working-directory: ./packages/toast-ui.grid
        run: |
          npm run lint
      - name: test # Cypressテスト
        working-directory: ./packages/toast-ui.grid
        run: |
          npm run test:ci

Cypress 18.04 ubuntu環境においてxvfb issueがあったため、16.04でテストしました。

テスト

それでは、作成したワークフローが正常に動作するかテストしてみましょう。2つのワークフローの過程で、それぞれイシューが発生するようにサンプルを作ってみます。まず、ESLintルールに違反しているコードを作成してPRを上げてみました。

赤いラインが入ってきました。

PRを上げるとすぐにアクションが実行されたことがわかります。詳細画面に入ってみましょう。

ESLintを返したときと同様に、どの部分でイシューが発生したかアクションで確認することができました。次にESLintイシューが生じた部分を解決し、Cypressテストをわざと修正して、テストが壊れるようにしてみましょう。column.spec.tsの結果値を少し変更してPRを上げてみました。

ESLintは通過しましたが、column.spec.tsが通過できず、当該ワークフローを通過することができませんでした。それぞれ必要な部分に赤信号をつけて簡単な1つのワークフローを作ってみました。Jenkinsを構成せずに、いくつかのコマンドではイシューを迅速に解決できました。しかし、まだ安定的ではない部分も存在しています。

安定的ではない部分とは?

matrixで複数の環境でテストを並列的に行えるようにしてCypressを返してみると、すべての異なる環境でテストが失敗しました。理由もなく突然中断されたものもあり、正常通過しなければならないテストが失敗したケースもありました。(並列実行したときに発生する問題だと思われます。それぞれでテストを実行するとすべて通過しますが、こうするとあまり意味がありません。)

それぞれのノードのバージョンを明示してテストすると合格しますが、一方で断続的にテストが失敗しています。同じコードですが、失敗する部分の原因が把握しずらく、継続的に現象が続いた場合、通過したテストが信頼できる結果なのか、もう一度考える必要があるようです。

結論

NHNでは、まず優先的に TOAST UI GridにGitHub Actionsを導入する予定です。上記のワークフローだけでなく、複数の配布過程で発生する作業をアクションで自動化する予定で、すでに大小のオープンソースに導入して使用しています。フィードバックも速いスピードで反映されており、大規模なCI会社やテストツールもGitHub Actionで動作できるように開発したり、すでに発売しているケースがほとんどです。現在、TOAST UIのコンポーネントは、Seleniumなどさまざまな理由から社内環境にJenkinsを構築し、ポーリングしてワークフローを実行しています。さらに管理の問題も負担になっています。今後、複数プライベート環境で構築されたCI、あるいはGitHubエンタープライズ環境でもGitHub Actionをサポートすることから、見どころは十分にあると思います。


付録

ActionではありませんがDeepScanの紹介

  • https://deepscan.io/dashboard/
  • コード上で使用されていないコードや誤った構文を把握して教えてくれます。
  • まだTypeScriptが完全にサポートされている感じではありません。
  • しかし、人間が見逃しがちな部分を見つけてくれるので有用だと思います。


GitHub Actionsでnpm node_modulesキャッシュを使用する

NHN Cloud Meetup 編集部

NHN Cloudの技術ナレッジやお得なイベント情報を発信していきます
pagetop