GitHub Actionsに移行して2週間が経ちましたので、その間の変化を振り返ってみます。

Table of Contents

移行直後に執筆した以下記事からの変更点や続きです。

対応リポジトリと概要

PythonとTypeScriptで書かれたリポジトリ計4つに導入しました。
環境は全てubuntu/latestです。

リポジトリ名 言語 テスト内容
tadashi-aikawa/owlmixin Python pytest with doctest
tadashi-aikawa/owcli Python Bats
tadashi-aikawa/jumeaux Python pytest and Bats
tadashi-aikawa/togowl TypeScript Jest

stepsのnameは可能なら省略したほうがよい

省略してもブラウザのページにはusesのaction名が表示されます。
ソースコードの冗長なコメントと同じく、見れば分かるものにはnameを付けない方がよいと思います。

例えば以下の設定があるとします。

steps:
  - name: Checkout repository
    uses: actions/checkout@v1
  - name: Setup nodejs
    uses: actions/setup-node@v1
    with:
      node-version: ${{ matrix.node }}

  - name: Install dependencies
    run: npm install
  - name: Build
    run: npm run build
  - name: Unit test
    run: npm test

GitHub Actionsやnpmを使っている人であれば、nameの説明は自明であるためノイズにしかなりません。
nameを取っ払うと以下のようになります。

steps:
  - uses: actions/checkout@v1
  - uses: actions/setup-node@v1
    with:
      node-version: ${{ matrix.node }}

  - run: npm install
  - run: npm run build
  - run: npm test

シンプルでLGTM😄
逆にnameを付けるのは以下のようなケースだと考えています。

runが複数行に渡っている

nameが無いとパッと見ただけでは何をしているのか分からないと思います。

- name: Install dependencies
  run: |
      python -m pip install --upgrade pip pipenv
      sed -ri 's/python_version = ".+"/python_version = "${{ matrix.python }}"/g' Pipfile
      pipenv install --dev --skip-lock      

GitHub Actions以外でも使うのなら、Makefileに定義すればnameは不要になりますね👍

runは単一行だが、やっていることが分かりにくい

以下はPipfileのPythonバージョンをmatrixで指定したバージョンに置換しています。

- run: sed -ri 's/python_version = ".+"/python_version = "${{ matrix.python }}"/g' Pipfile

一瞬だと分からないのではないでしょうか。

blockの設定行が5行以上

内容は分かりやすくても、5行以上に渡る項目はnameを付けた方が分かりやすいです。

- name: "Slack Notification (success)"
  uses: homoluctus/slatify@master
  if: always()
  with:
    type: ${{ job.status }}
    username: GitHub Actions (Success)
    job_name: ":python: All tests"
    icon_emoji: ":renne:"
    url: ${{ secrets.SLACK_WEBHOOK }}

これは テスト全体の成功をSlackへ通知 です。

通知の最適化

Matrix Buildの数だけ通知が来るため、Slackの画面が一瞬で占有されていました..。

失敗がない場合はリポジトリに対して1通だけ通知するようにしました。

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: ['10.x', '12.x']
    name: Node ${{ matrix.node }}

    steps:
      # ... 省略 ...

      - name: 'Slack notification (not success)'
        uses: homoluctus/slatify@master
        if: '! success()'
        with:
          type: ${{ job.status }}
          username: GitHub Actions (Failure)
          job_name: ':togowl: :nodejs:*${{ matrix.node }}* Tests'
          mention: channel
          mention_if: always
          icon_emoji: 'tio2'
          url: ${{ secrets.SLACK_WEBHOOK }}

  notify:
    needs: test
    runs-on: ubuntu-latest

    steps:
      - name: 'Slack Notification (success)'
        uses: homoluctus/slatify@master
        if: always()
        with:
          type: ${{ job.status }}
          username: GitHub Actions (Success)
          job_name: ':togowl: :nodejs: All tests'
          icon_emoji: ':renne:'
          url: ${{ secrets.SLACK_WEBHOOK }}

成功以外という条件の書き方がなかなか見つからず苦戦しました..。
if: '! success()'と書けばOKです。!後のスペースがミソ😢

また、失敗した場合はユーザー画像を変更し、Channelに通知させています。
usernameを変更しないと、同一ユーザと見なされて画像が変わらないので注意です。

作者の方に相談したらすぐ実装してくださり圧倒的感謝🙏

その他の部分は参考にさせていただいた以下ブログをご覧ください。

よく使う処理のスニペット

スニペットはGistの内容に追従します
執筆時点の内容とは限りません。ご了承下さい。

Pipenvで依存関係インストール

Pipenvを使う場合の準備です。

Code Climateでテストレポート登録

テスト結果をCode Climateに送る場合です。

よく使うワークフローファイルのテンプレート

Actionのリポジトリを作成するほどではないため、Gistで管理することにしました。

スニペットはGistの内容に追従します
執筆時点の内容とは限りません。ご了承下さい。

Nodeプロジェクト

npmを使ってCIするケースです。

展開する

Pipenvプロジェクト with Bats

Pipenvで環境構築し、pytestBatsを使ってCIするケースです。

展開する

BatsによるCLIテストが不要ならそこだけ削除してください。

総括

GitHub Actionsに移行してから2週間経って所感とノウハウをまとめました。

今も動作は高速なおかげで、心地よい開発ができています🙂
変数機能に対応すると記述がシンプルになったり幅が広がりそうなので、密かに期待しています。