GitHub Actions で Erlang/OTP なクローズドソースのミドルウェアのテストをする
Tags: erlang, github
Published: 2020-10-31 10:34:04

CircleCI から GitHub に移行するにあたって試行錯誤したのでメモとして残しておきます。

## 結論

テスト用の Docker コンテナを利用せず Github Actions の action/cache を活用するのがメンテナンス的にも楽。

## 利用した actions

### https://github.com/actions/checkout

v2 がでているので v2 を使うようにしましょう。

`$GITHUB_WORKSPACE` が使えるようになっています、便利。

### https://github.com/actions/cache

今回のメインはこの cache です。

GitHub Actions で Erlang を自分設定したビルドで利用する場合は Docker を使うよりこの cache 機能を使うことをおすすめします。

このキャッシュ機能は本当に優秀です。

まず OS は ubuntu-latest で env で OpenSSL と Erlang/OTP のバージョンを指定するようにしました。

```yaml
runs-on: ubuntu-latest
env:
  OPENSSL_VERSION: 1.1.1h
  ERLANG_VERSION: 23.1.1
```

あとはキャッシュを活用します。Linux 以外では想定していないため key からプラットフォーム指定は外しています。キャッシュがなかったらビルドする、キャッシュがあったらそれを使うといったシンプルなものです。

シンプルに書いたので、メンテコストもとても軽めです。

```yaml
- uses: actions/cache@v2
  id: openssl-cache
  with:
    path: /opt/openssl/${{ env.OPENSSL_VERSION }}
    key: openssl-${{ env.OPENSSL_VERSION }}
    restore-keys: |
      openssl-

- if: steps.openssl-cache.outputs.cache-hit != 'true'
  run: |
    curl -LO https://www.openssl.org/source/openssl-${{ env.OPENSSL_VERSION }}.tar.gz
    tar xvfz openssl-${{ env.OPENSSL_VERSION }}.tar.gz
    cd openssl-${{ env.OPENSSL_VERSION }}
    ./config --prefix=/opt/openssl/${{ env.OPENSSL_VERSION }}
    make -j
    sudo make install

- uses: actions/cache@v2
  id: erlang-cache
  with:
    path: /opt/erlang/${{ env.ERLANG_VERSION }}
    key: erlang-${{ env.ERLANG_VERSION }}
    restore-keys: |
      erlang-

- if: steps.erlang-cache.outputs.cache-hit != 'true'
  run: |
    git clone https://github.com/erlang/otp
    cd otp
    git checkout OTP-${{ env.ERLANG_VERSION }}
    ./otp_build autoconf
    ./configure --prefix=/opt/erlang/${{ env.ERLANG_VERSION }} \
                --enable-kernel-poll \
                --enable-dirty-schedulers \
                --disable-sctp \
                --disable-dynamic-ssl-lib \
                --disable-sharing-preserving \
                --disable-hipe \
                --disable-native-libs \
                --with-ssl=/opt/openssl/${{ env.OPENSSL_VERSION }} \
                --without-javac \
                --without-odbc
    make -j
    make install
```

キャッシュ容量は 5G まで使えるので本当に助かります。

#### rebar3 キャッシュ

rebar3 で依存ライブラリを引っ張ってくるコストもばかにならないのでキャッシュしてしまっています。

```yaml
- uses: actions/cache@v2
  id: rebar3-deps-cache
  with:
    path: $GITHUB_WORKSPACE/_build
    key: rebar3-deps-${{ hashFiles('~/$GITHUB_WORKSPACE/rebar.lock') }}
    restore-keys: |
      rebar3-deps-
```

キャッシュがなかったら引っ張ってくるようになっています。

### https://github.com/actions/setup-node

E2E テストとして [cypress](https://www.cypress.io/) を利用しています。 cypress を EUnit から呼び出しています。

### https://github.com/webfactory/ssh-agent

Erlang を利用している場合に課題になるのは rebar3 経由でプライベートリポジトリを持ってくる部分です。色々苦労したくないので素直に ssh-agent を利用することにしました。

SSH_PRIVATE_KEY を設定することで rebar3 の設定は一切変更する必要はありません。

```yaml
- uses: webfactory/ssh-agent@v0.4.1
  with:
    ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
```

### https://github.com/rtCamp/action-slack-notify

Slack 通知はこれが一番無難です。ただ Fixed (失敗の後の成功通知）ができないのが残念なところです。
成功時は通知せず、失敗時だけ通知するという方針なので SLACK_COLOR は danger にしています。

失敗したらこれが呼ばれます。通知をもっと詳細にしてもいいかもしれません。

```yaml
- name: Slack Notification
  if: failure()
  uses: rtCamp/action-slack-notify@v2.1.0
  env:
    SLACK_CHANNEL: sora
    SLACK_COLOR: danger
    SLACK_TITLE: Failure test
    SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
```

## Erlang ライブラリ

パブリック、プライベートに関わらずコンテナを利用してビルド、テストしています。

## 費用

https://github.com/features/actions

GitHub Actions (プライベートリポジトリ利用) は Team を契約しているためデフォルトで 3000 分ついています。

それを超えたら 1 分あたり $0.008 です。うちのプッシュ単位で 4 分、デイリーで 14 分くらいです。ざっくり 1 分 1 円くらいのようです。

## CircleCI からの移行理由

- UI/UX があまりにも使いにくい
- OSS 関連を全て GitHub Actions に移行した
- actions が便利になってきた
- CircleCI にあまり未来を感じない