ローファイ日記

出てくるコード片、ぼくが書いたものは断りがない場合 MIT License としています http://udzura.mit-license.org/

mrubyのバイナリコマンドをGitHub Actionでリリースする

あけおめ!

去年やってブログに書き忘れたことをほそぼそ書くシリーズ。


help.github.com

  • mrubyのプロジェクトでCIでビルド・テストを回したい
  • バイナリを作成するツールなので、バイナリのリリースも自動でやりたい

こういう時の設定例です。

ビルドとテストを回す

GitHub Action は基本的にデフォルトイメージをベースに既存のアクションを組み合わせるのが良くて、デフォルトイメージに入っているソフトウェアは以下のページで確認できる。

help.github.com

しかし残念なことにこの中に、mrubyのビルドに必要な bison がない。必要なパッケージがない場合は自分でイメージを作りdockerhubなどに上げておくといいらしい。

github.com

これでビルドしたイメージを udzura/mruby-build-base にプッシュした。一緒に ruby と rake なども入れてしまったので、Rubyプロジェクトでいうgem installみたいなセットアップも不要で。そのまま actions/checkout@v1 を使った後で rake/rake test を走らせれば完了。 on: [push] でどのpushでもCIが回るようになる。

name: GitHub Action CI
on: [push]

jobs:
  build:
    name: Build and test
    runs-on: ubuntu-18.04
    container: udzura/mruby-build-base:0.1.2
    steps:
      - uses: actions/checkout@v1
      - name: Build binary
        env:
          MRUBY_VERSION: master
        run: |
          rake
      - name: Run tests
        env:
          MRUBY_VERSION: master
        run: |
          rake test
      - uses: actions/upload-artifact@master
        with:
          name: bt2prom
          path: mruby/bin/bt2prom

一応できたバイナリは毎回 artifact として保存するようにしているが、それも actions/upload-artifact ですぐできて便利。

タグがついたときはリリースを作ってバイナリをアップロードしたい

以下のように on.push.tags: ['*'] と指定すると、何かしらタグをプッシュした時だけ走るアクションを作ることができる。

on:
  push:
    tags:
    - 'v*'

さて、プッシュされたタグの名前は ${{ github.ref }} でジョブの中で展開できる... が、 refs/tags/vX.Y.Z という形式で取得できるので使いづらい。 awkワンライナーを中で走らせている。この ${{ github.ref }} はたとえば actions/create-release の中では純粋にタグの名前だけになったりするんだけど、普通のジョブではフルパスみたいな形になる模様。

なおかつ、後続のジョブでも使いたいんで ::set-output ... というパラメータをアサインする特殊な出力を経由して、タグをジョブ全体にアサインしている。

help.github.com

で、 rake の最後で自分でzipに固めている。当該ジョブの全体はこう。

      - name: Build project
        id: create_build
        run: |
          rake
          echo "::set-output name=current_tag::$(echo ${{ github.ref }} | awk -F'/' '{print $3}')"
          zip --junk-paths bt2prom.$(echo ${{ github.ref }} | awk -F'/' '{print $3}').zip mruby/bin/bt2prom

あとは actions/create-release でリリースを作成して、 actions/upload-release-asset で先ほど固めたzipをreleaseにアップすれば終わり。

YAMLの全体です。

name: Upload Release Asset

on:
  push:
    tags:
    - 'v*'

jobs:
  release:
    name: Upload Release Asset
    runs-on: ubuntu-latest
    container: udzura/mruby-build-base:0.1.2
    steps:
      - name: Checkout code
        uses: actions/checkout@v1
      - name: Build project
        id: create_build
        run: |
          rake
          echo "::set-output name=current_tag::$(echo ${{ github.ref }} | awk -F'/' '{print $3}')"
          zip --junk-paths bt2prom.$(echo ${{ github.ref }} | awk -F'/' '{print $3}').zip mruby/bin/bt2prom
      - name: Create Release
        id: create_release
        uses: actions/create-release@v1.0.0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: Release ${{ github.ref }}
          draft: false
          prerelease: false
      - name: Upload Release Asset
        id: upload_release_asset 
        uses: actions/upload-release-asset@v1.0.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./bt2prom.${{ steps.create_build.outputs.current_tag }}.zip
          asset_name: bt2prom.${{ steps.create_build.outputs.current_tag }}.zip
          asset_content_type: application/zip

プロジェクトはここです。

github.com

備忘録的にやや端折り気味に書いた。何かあれば聞いてください。