github-script-ruby@v2でRubyのバージョンを指定できるようにした

github-script-rubyが何かについてはペパボのテックブログに書きましたので是非ご覧ください。

tech.pepabo.com

github-script-rubyは、簡単にいうと actions/github-scriptRuby版です。

今回は、github-script-ruby独自の機能としてRubyのバージョンを指定できるようにしました。

具体的には ruby-version:Rubyのバージョンを書くとそのバージョンで動きます。 簡単なサンプルとしては以下のような感じです。

- name: 'Hello Ruby version'
  uses: k1LoW/github-script-ruby@v2
  with:
    script: |
      repo = "#{context.repo.owner}/#{context.repo.repo}"
      number = context.issue.number
      comment = "Hello using Ruby v#{RUBY_VERSION}"
      github.add_comment(repo, number, comment)
    ruby-version: 2.7.5

あまり古いバージョンのRubyで動かすことにモチベーションはないですが、現状2.4.10までは動いています(コードを対応させればもう少し古いバージョンでも動くと思います)。

さて、どのように実現したのかというと ruby/setup-ruby の仕組みを利用させてもらうことで実現しています。

ruby/setup-ruby はどのように ruby-version: の機能を実現しているか

ruby/setup-rubyのREADME.mdに以下のように書かれています。

This action downloads a prebuilt ruby and adds it to the PATH.

The prebuilt releases are generated by ruby-builder and on Windows by RubyInstaller2. mingw and mswin builds are generated by ruby-loco. ruby-head is generated by ruby-dev-builder, jruby-head is generated by jruby-dev-builder, truffleruby-head is generated by truffleruby-dev-builder and truffleruby+graalvm is generated by graalvm-ce-dev-builds. The full list of available Ruby versions can be seen in ruby-builder-versions.js for Ubuntu and macOS and in windows-versions.js for Windows.

つまり、あらかじめruby/ruby-builder をはじめとする各リポジトリでプレビルドしたRubyをReleasesのAssetとして置いておき、ruby/setup-ruby側では ruby-version: で指定されたバージョンのRubyをダウンロード・展開し設置するという形で「任意のバージョンのRubyのセットアップ」を実現しています*1

github-script-ruby@v2 でも ruby-version: の機能を実現する

github-script-ruby@v2 でもruby/setup-rubyで使用しているAssetを使用させてもらっています。

まず、さまざまな処理系やバージョンにする必要はないと考えて「MRIのみ」かつ「パッチバージョンまで指定する」という制約をつけています。 そうすると対象となるのは ruby/ruby-builder で管理されているプレビルドRubyだけになります。

github-script-ruby@v2をstepで実行するタイミングで ruby-version: が指定されていれば ruby/ruby-builder からプレビルドRubyをダウンロードして設置して使用します。 また、bundlerが標準添付されていないバージョンの場合はbundlerもインストールします。

https://github.com/k1LoW/github-script-ruby/blob/6852aaffa26d2b760ff60c79b7086ef9a248a918/scripts/entrypoint.sh#L9-L23

これだけで簡単な ruby-version: の機能が実現できました。

その他にも

v2で、gemfile-path: (Gemfileのパスを指定する)や command:github-script-rubyの環境で任意のコマンドを実行する)なども追加しました。

これで、stepだけで独立した任意のバージョンのRuby環境を手に入れることができます。

(必要かどうかはおいておいて)例えば、

- name: 'Capistrano deploy'
  uses: k1LoW/github-script-ruby@v2
  with:
    gemfile-path: path/to/Gemfile
    command: bundle exec cap deploy --gemfile=path/to/Gemfile
    ruby-version: 2.7.5

みたいなこともできたりします。

というわけで、v1からあった gemfile:(Gemfileを書ける) や pre-command:github-script-rubyの環境で任意のコマンドを実行する)に続いて、さらに元ネタであったactions/github-scriptからさらに逸脱してきた感じです。

何か面白いユースケースを思いついたら是非教えてください。

*1:実際にはダウンロード以外にもキャッシュを使ったりruby-buildでビルドしたりなどをしています