notebook

都内でWEB系エンジニアやってます。

新しくなったGitHubActionsを試す

yamlの記述になってから試してみたかったものの題材がなかったのと割と忙しくて試せていなかったためいまさらながら試してみた、記事的には目新しいことはなさそうなので完全なチラシの裏

とりあえず下記のリポジトリでいくつか実践してみた

swfz/ngx-libraries: ngx-libraries

github.com

設定ファイル

.github/workflows以下のファイルを読み込んでくれるが今回は用途に分けて3つ設置した

  • CI
    • push時に実行するbuild, test, lint
  • npm publish
    • masterへのpush時に実行するGitHubPagesへのデプロイ
  • deploy
    • release作成時に実行するnpmへのpublish

複数ファイルで同じイベントを指定してもそれぞれ読み込んで実行してくれるようなので用途ごとに分けた

今までCircleCIに慣れていたためCircleCIでいうworkflowsの項目でよしなに切り替えたい(1ファイルに集約したい)なぁと思っていた

そうなった場合「1つにまとめて分岐で頑張る」などもできそうだったが記述が増えてきたら役割ごとに分けられていたほうが良さそうだったので今回は分けた

あとテンプレート的なworkflowがいくつか用意されていてNew workflowから選択していくとそれっぽい設定をサクッと入れることができる

f:id:swfz:20191104231119g:plain

これだけでも始めるハードル下げられるだろうなーと思った

CI

テストとビルド、lint系のjobを定義した

name: build

on: [push]

jobs:
  build-app:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [12.x]

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

      - name: cache
        uses: actions/cache@preview
        with:
          path: node_modules
          key: ${{ runner.os }}-node-${{ hashFiles(format('{0}{1}', github.workspace, '/package.json')) }}

      - name: npm install, build, and test
        run: |
          npm install
          npm run build:app
          npm run test:app
        env:
          CI: true

  build-lib:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [12.x]

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

      - name: cache
        uses: actions/cache@preview
        with:
          path: node_modules
          key: ${{ runner.os }}-node-${{ hashFiles(format('{0}{1}', github.workspace, '/package.json')) }}

      - name: npm install, build, and test
        run: |
          npm install
          npm run build:lib
          npm run test:lib
        env:
          CI: true

  prettier:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [12.x]

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

      - name: cache
        uses: actions/cache@preview
        with:
          path: node_modules
          key: ${{ runner.os }}-node-${{ hashFiles(format('{0}{1}', github.workspace, '/package.json')) }}

      - name: npm install, prettier
        run: |
          npm install
          npm run prettier:check
        env:
          CI: true

  lint:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [12.x]

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

      - name: cache
        uses: actions/cache@preview
        with:
          path: node_modules
          key: ${{ runner.os }}-node-${{ hashFiles(format('{0}{1}', github.workspace, '/package.json')) }}

      - name: npm install, lint
        run: |
          npm install
          npm run lint
        env:
          CI: true

ほとんどテンプレートから引っ張ってきたものを少し改変、追記しただけで実行できた

プラスアルファはcacheの箇所くらい

npm publish

npmのpublishを定義した

Node.js Packageというテンプレートがあるのでそこから拝借と少し修正

プラスアルファはcacheの箇所くらい

GitHubRegistryは今回いったん除外した

SecretsにnpmのTokenを入力して読み出している

name: npm package

on:
  release:
    types: [created]

jobs:
  publish-npm:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - uses: actions/setup-node@v1
        with:
          node-version: 12
          registry-url: https://registry.npmjs.org/

      - name: cache
        uses: actions/cache@preview
        with:
          path: node_modules
          key: ${{ runner.os }}-node-${{ hashFiles(format('{0}{1}', github.workspace, '/package.json')) }}

      - name: npm install, build, publish
        run: |
          npm install
          npm run build:lib
          cd projects/filter-keyup-events
          npm publish
        env:
          NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

deploy

GitHubPagesへのデプロイを定義した

angular-cliからng deployでデプロイするためワン・コマンドですんでしまう

name: Deploy GitHub Pages

on:
  push:
    branches:
      - master

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [12.x]

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

      - name: cache
        uses: actions/cache@preview
        with:
          path: node_modules
          key: ${{ runner.os }}-node-${{ hashFiles(format('{0}{1}', github.workspace, '/package.json')) }}

      - name: build and deploy
        run: |
          npm install
          npm run deploy -- --repo=https://github.com/swfz/ngx-libraries.git --name="$GITHUB_USERNAME" --email="$GITHUB_EMAIL"
        env:
          CI: true
          GH_TOKEN: ${{secrets.GITHUB_PERSONAL_TOKEN}}
          GITHUB_USERNAME: ${{ secrets.GITHUB_USERNAME }}
          GITHUB_EMAIL: ${{ secrets.GITHUB_EMAIL }}

GitHubのSecretsに登録

  • GITHUB_USERNAME
  • GITHUB_EMAIL
  • GITHUB_PERSONAL_TOKEN

GitHubPagesのデプロイにpersonal tokenを使いたかったため最初から読み込めるTOKENではなくSecretsに登録した

いまさらだけどusername, emailは別にSecretsでやらなくても良かったかも

matrixビルド

今回特に必要ないがとりあえず試してみた(nodeのバージョンを3つにして実行してみた)

結構な数並列で動かしたためかそれなりのjobが下記エラーでfailした

Use Node.js 10.x
##[error]Node run failed with exit code 1
Run actions/setup-node@v1
/bin/tar xzC /home/runner/work/_temp/79d84685-64da-470c-9057-f2b1e20ec304 -f /home/runner/work/_temp/35432b1c-dc51-4ec2-b435-7118a29463ba

gzip: stdin: unexpected end of file
/bin/tar: Unexpected EOF in archive
/bin/tar: Unexpected EOF in archive
/bin/tar: Error is not recoverable: exiting now
##[error]The process '/bin/tar' failed with exit code 2
##[error]Node run failed with exit code 1

今のところあんまり組み合わせ数を増やさないほうが良さそう…

結局nodeのバージョンも1つに戻した

よくあるのはos, versionを指定する方法だがmonorepoでの開発ではディレクトリもここに突っ込めば効率よく記述できそう

別途活用方法を模索したいところ

キャッシュ

「キャッシュがないから残念」という話は散々いわれていたがついに!

actions/cache: Cache dependencies and build outputs in GitHub Actions

github.com

とりあえず入れてみたが結構よしなにやってくれるよう

jobの最初と最後にrestore, saveをやってくれるので明示的にstepに書かなくて良い(今のところ気が利くなーと思っている)

少しではあるがインストール時間は短縮された

  • 導入前

f:id:swfz:20191104231219p:plain

  • 導入後

f:id:swfz:20191104231225p:plain

感想とまとめ

ざっと触ってみただけだが所感を

  • All workflowsでworkflowの一覧を見れるがpushにおいてはCommitメッセージまでファーストビューでみたいなと思ってしまった
    • 必ずしもCommitを必要とするイベントだけではないのでこうなるのは分かるには分かる…けど!といった感じ

f:id:swfz:20191104231229p:plain

  • 正直個人開発であればこれで困ることないんじゃないかなーと思う
    • テンプレートから選べばそれで終わりなパターンも結構ありそう
  • GitHubActionsのバリデーション自体はCommit前にやりたい
    • 構文エラーに気付きたい(探しきれなかっただけかも?)
    • CircleCIのcircleci config validate相当のものが欲しい
  • デバッグまだつらいイメージ
    • CircleCIでいう一時的なsshアクセス許可みたいな機能とか欲しい
  • matrixビルド便利そう
    • すでに色々事例が出ているが最初に環境を作れればその後結構な範囲をカバーできるのでコスパ良さそう
    • 試し始めて無意味にnodeのバージョン(8,10,12)で一斉にビルドを走らせたりしてみたがそうするとctions/setup-nodeの箇所で結構落ちたので並列実行数増やしまくってもまだ対応できるほど安定しているわけではなさそう?
  • キャッシュ使ってみた
    • CircleCIでは明示的にsave_cacheなどをする必要があったがGitHubActionsではuseすればよしなにやってくれるので良い

ということで、今後積極的に使っていきたいところ