octocovで任意のメトリクスを記録できるようにした(カスタムメトリクス)

octocov

octocovはコードカバレッジのためのツールキットです。

github.com

コードカバレッジなどのコードメトリクスを手元のターミナルで確認したり、GitHub ActionsのActionとしてPull Requestにレポートしたりできます。

計測したコードメトリクスを、さまざまなデータストアに蓄積することもできます。

octocovはコードカバレッジ、Code to Test ratio、テスト実行時間の3つのコードメトリクスを計測しますが、今回、任意のメトリクスに対応しました。

カスタムメトリクス

カスタムメトリクスの使用方法は簡単です。

  1. 計測したメトリクスを指定のフォーマットで保存する(カスタムメトリクスJSON
  2. octocovに環境変数経由でカスタムメトリクスJSONの保存パスを渡す

これだけです。

1. 計測したメトリクスを指定のフォーマットで保存する(カスタムメトリクスJSON

カスタムメトリクスが対応できるのはKey-Value形式で、かつValueが数値であるメトリックです。

それを次のようなJSONフォーマットで保存します。

{
  "key": "benchmark_0",
  "name": "Benchmark-0",
  "metrics": [
    {
      "key": "N",
      "name": "Number of iterations",
      "value": 1000
    },
    {
      "key": "NsPerOp",
      "name": "Nanoseconds per iteration",
      "value": 676.5,
      "unit": " ns/op"
    }
  ]
}

JSONスキーマはこちらに定義しています

2. octocovに環境変数経由でカスタムメトリクスJSONの保存パスを渡す

カスタムメトリクスJSONが保存しているパスを OCTOCOV_CUSTOM_METRICS_プレフィックスにつけた任意の環境変数でoctocovに渡します。 カスタムメトリクスJSONは、OCTOCOV_CUSTOM_METRICS_1 OCTOCOV_CUSTOM_METRICS_2 のようにいくつ渡しても構いません。

例えばGitHub Actionsでoctocov-actionを使っている場合は次のように指定します。

steps:

[...]

      - name: Run octocov
        uses: k1LoW/octocov-action@v0
        env:
          OCTOCOV_CUSTOM_METRICS_BENCHMARK: custom_metrics_benchmark.json

これで設定は終わりです。

あとはoctocovがもともと対応している3つのコードメトリクスと同じようにPull Requestにレポートしたり比較したりしてくれます。

octocov-go-test-bench

1つの例として go test -bench の結果をoctocovのカスタムメトリクス形式に変換するコマンドを作成しました。

github.com

次のように go test -bench の標準出力をoctocov-go-test-benchに渡すだけでoctocovのカスタムメトリクス形式に変換して出力してくれます。

そのままJSONファイルに保存すればよいです。

同時にベンチマークの出力結果も確認したい場合は --tee オプションを付与してください。

$ go test -bench . -benchmem | octocov-go-test-bench --tree > custom_metrics_benchmark.json
goos: linux
goarch: amd64
pkg: github.com/k1LoW/rp
cpu: Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz
BenchmarkNGINX-2       10000        635221 ns/op       17720 B/op        139 allocs/op
BenchmarkRP-2          10000        376138 ns/op       64199 B/op        191 allocs/op
PASS
ok      github.com/k1LoW/rp 25.807s

GitHub Actions上での具体的な設定例としては、私が別で開発しているOSSの設定を見ると良いでしょう。

コードメトリクスツールから、汎用メトリクスツールへ

今回、octocovの想定利用ケースを広げることができました。

当初の構想としては未実装はあと1つで、v1になる日も近そうです。

是非使ってみてください。

テストでしか使わないパッケージをgo.modに含めない方法

元エントリは↓で、これが全てです。

dev.to

Goでツールではなくライブラリ(パッケージ)を作っているとき、テストにしか使わないパッケージがgo.modに入って依存関係ができてしまうのが、いつも気になっていました。

ただ、「まあ別にいいかな」と思っていたのですが、ちょうど標準パッケージだけで機能が実現できるパッケージができたので、どうしてもgo.modを綺麗にしたくなりました。

そして、えいっと調べてみたらすぐに解決方法が見つかったのでした。

テストでしか使わないパッケージをgo.modに含めない方法

方法は次の通りです*1

  • テスト用に go_test.mod ファイルを用意して -modfile オプションを使って go_test.mod ファイルを指定して go test を実行する
  • (例えば)go.modの更新に go mod tidy を使わない

テスト用に go_test.mod ファイルを用意して -modfile オプションを使って go_test.mod ファイルを指定して go test を実行する

-modfile でgo.modを指定できるので(知らなかった!)、テスト用にgo_test.modファイルを指定するようにすることでパッケージとしての依存関係とテスト実行時の依存関係を別に管理します。

(例えば)go.modの更新に go mod tidy を使わない

公式の go mod tidy の説明によると

go mod tidy works by loading all of the packages in the main module and all of the packages they import, recursively.

とのことで、これにはテストコードも含まれます。

なので、 go mod tidy をそのまま使用することをやめるか、

Note that go mod tidy will not consider packages in the main module in directories named testdata or with names that start with . or _ unless those packages are explicitly imported by other packages.

とのことなので、テストコードを testdata ディレクトリ以下に押し込んでしまえば、テストでしか使わないパッケージが go.mod に入ることを回避できそうです。

ただ、 go mod tidy が使えないのは面倒...

具体的にどうしているか

https://github.com/k1LoW/rp/blob/aa26b46a7d17cdeb16370c1b704ee741c5e7b5b4/Makefile#L8-L10

$ cp go.mod testdata/go_test.mod
$ go mod tidy -modfile=testdata/go_test.mod
$ go test ./... -modfile=testdata/go_test.mod -coverprofile=coverage.out -covermode=count

のような感じで go_test.mod を生成してテストを実行しています。

もっといい方法がありそう

「私はこうやって解決しているよ」というのがあれば是非教えてください!

*1:エントリ公開当初「テストコードを別パッケージにする」と書いていましたが特に必要ありませんでした

PHPカンファレンス福岡2023に参加した

PHPカンファレンス福岡2023に参加してきました。

phpcon.fukuoka.jp

ホームでのカンファレンス開催と参加

私は福岡に住んでいます。その福岡のカンファレンスが、復活しました。実に4年ぶりとのことです。

4年で様々なことが変わりました。その変化の中、あの頃と変わらずにカンファレンスという場を提供してれたことに本当に感謝します。

これは推測でしかありませんが、4年の間、誰かの、誰か「達」の思いの火がずっと消えなかったからこその開催なのではないかなと思います。 一度(毎年開催という意味で)途絶えたカンファレンスを再度立ち上げるのは本当に「気持ち」が必要だっただろうなと思います。

私はというと、4年前といえば、私の子供はまだ生まれていませんでした。 そう考えると私のライフステージっぽいものも変わっていまして、今回は全然野菜や前夜祭などの参加は見送り、本編とAfter Hackの2つに絞って楽しみました。

fusic.connpass.com

あっという間の2日間でしたが、本当に楽しむことができました。

5年分の集大成としての発表

かなりの競争率の中無事採択され、発表をさせてもらうことができました。

今回、私が開発している tbls というツールについて話をさせてもらいました。

github.com

tblsと、tblsを開発したことがきっかけで考えるようになった "Documentation as Code" について、5年分のまとめ、そしてその先についての発表になります。

発表冒頭でも話しましたが、Documentation as Codeについて、もう話せることはありません。小さなアイデアすらないです。全部出し切りました。今後はインプットのフェーズだと思います。

5年分をまとめたお得スライドになっていると思いますので、よろしければ結論だけでも見てください。

かつて、私は福岡Ruby会議02でawspecというツールについて集大成的な発表をしました。

k1low.hatenablog.com

今回も福岡で、tblsについて同じように集大成的な発表ができて感無量です。

#runn開発者会議

PHPerKaigi2023に続いてrunn開発者会議を開催することができました。奇跡!

github.com

前回の去り際に「PHPカンファレンス福岡2023にプロポーザル出して福岡に行きますねー」といっていた @katzchum さん、有言実行してすごい。

今回もいくつかの機能について議論ができました。

  • 各ランブックから読みこむファイルのパス解決の機能拡張
    • まずパス解決の機構を統一する
    • 便利なパス名解釈( ../ など)やワイルドカード***/*)はセキュリティの観点からオプトインの仕組みを作る
  • Cookieを取り扱う機能の導入
  • ランブック単位、ステップ単位で一意性を持つIDの導入
    • 目的はエラー時の発生箇所特定や再実行に使う
    • コミットハッシュのように一意であれば短く指定することできるように
  • 大量のランブックを読み込む時の速度向上(もしくはUIで解決)

方針だけは決めたので、あとはGitHub上でコミュニケーション取りながらぼちぼち解決していこうと思います。

PHPカンファレンス福岡だった

PHPカンファレンス福岡の会場に入って受付をしたとき、「あーPHPカンファレンス福岡だ」と思いました。

スタッフに見知った熟練者がいるのを見かけるのも「あーPHPカンファレンス福岡だ」と思いました。

@nojimage さんがニコニコしているのも「あーPHPカンファレンス福岡だ」と思いました。

いろいろアップデートされていてさらに過ごしやすく楽しくなっているのはその通りなのですが、なんか「あーPHPカンファレンス福岡だ」と思ったのです。

いやー良いPHPカンファレンス福岡でしたね。

みなさんお疲れ様でした。

gh auth loginで作成されたクレデンシャルだけで生活するためにgh-doを作った

GitHub CLIgh auth login で作成されたクレデンシャルはOSのセキュアストレージに保存されるようになりました。

次のエントリが詳しいです。

blog.kyanny.me

「じゃあ、もう全部セキュアストレージに保存されたクレデンシャルを使えばOK」となるのですが、なかなかそうはいきません。

なぜかというとGitHubのクレデンシャルを使うツールによって環境変数の扱いが異なるからです。

GitHubのクレデンシャル設定の歴史(私の記憶版)

注意: 以下は、あくまで私の記憶であって実際と異なるかもしれません。

前史

GitHub CLIgh )やGitHub Actionsの登場以前は、クレデンシャルを保存する環境変数名として使われていたのは GITHUB_TOKEN でした。また、github.comとEnterpriseを切り替えるための環境変数名は定まっていなかった気がします。

GitHub Actions の登場

GitHub Actionsが登場したことで、GitHub Actionsがデフォルトで設定している環境変数が認知されるようになってきました。

docs.github.com

これにより、 GITHUB_API_URL といった「github.comとEnterpriseを切り替える」環境変数に対応したツールが登場してきました。

GitHub CLIgh )の浸透

そしてGitHub CLIが広く使われるようになってきて、GitHub CLIがサポートする環境変数GH_HOST GH_TOKEN など)が認知されるようになってきました。

cli.github.com

異なる環境変数の取り扱いにまとめて対応する

上記のような経緯が(たぶん)あったので、GitHubのクレデンシャルを扱うツールはその登場時期によって認識する環境変数が異なります。

独自に環境変数名を定めているものはしかたないとしても、当時のデファクトスタンダード環境変数に対応していたツールにはなんとか対応したいと考えました。

また、GitHub CLIには gh auth token というトークンそのものを取得するコマンドがありますが、「github.comとEnterpriseを切り替える」環境変数まで設定してくれる訳ではありません。

というわけで、gh-do というコマンドを作りました。

gh-do

github.com

gh-doは何かというと gh auth login で保存されたクレデンシャルとホスト名を使って環境変数を設定してくれるツールです。

インストール

gh-doはGitHub CLI 拡張機能としてインストールして gh do として実行できます。

$ gh extension install k1LoW/gh-do
$ gh do --help
gh-do is a tool to do anything using GitHub credentials.

Usage:
  gh-do [flags]

Flags:
      --help
  -h, --hostname string   The hostname of the GitHub instance to do
      --insecure          Use insecure credentials
  -v, --version           version for gh-do

また、単体のコマンド gh-do としてインストールすることも可能です。macOSであれば Homebrewでインストールできます。

$ brew install k1LoW/tap/gh-do

使い方

引数にコマンドがあれば、環境変数を設定したうえでコマンドを実行してくれますし、

gh do -- any-command arg arg arg

引数が何もなければ環境変数をexportコマンドの形で出力します。

$ gh do
export GH_HOST=github.com
export GH_TOKEN=gho_xxxxxXXXXXXXXxxxxxxxXXXXXXXXXxxXXxxx
export GH_ENTERPRISE_TOKEN=
export GITHUB_ENTERPRISE_TOKEN=
export GITHUB_TOKEN=gho_xxxxxXXXXXXXXxxxxxxxXXXXXXXXXxxXXxxx
export GITHUB_API_URL=https://api.github.com
export GITHUB_GRAPHQL_URL=https://api.github.com/graphql

github.comとEnterpriseの切り替え」も環境変数 GH_HOST を読んで自動で切り替えてくれます。 また --hostname ( -h ) オプションで切り替えることも可能です。

$ gh-do --hostname enterprise.internal
export GH_HOST=enterprise.internal
export GH_TOKEN=gho_yyyyyYYYYYYYYyyyyyyyYYYYYYYYYyyYYyyy
export GH_ENTERPRISE_TOKEN=gho_yyyyyYYYYYYYYyyyyyyyYYYYYYYYYyyYYyyy
export GITHUB_ENTERPRISE_TOKEN=gho_yyyyyYYYYYYYYyyyyyyyYYYYYYYYYyyYYyyy
export GITHUB_TOKEN=gho_yyyyyYYYYYYYYyyyyyyyYYYYYYYYYyyYYyyy
export GITHUB_API_URL=https://enterprise.internal/api/v3
export GITHUB_GRAPHQL_URL=https://enterprise.internal/api/graphql

デフォルトではOSのセキュアストレージに保存されたクレデンシャルしか使わないようになっていますが、--insecure オプションを付与することでGitHub CLIと同様にクレデンシャル用環境変数にも反応してくれます。

$ gh do --insecure

ところで

envchainにまとめるというのも汎用性高くてとてもオススメです。

github.com

というわけで

gh auth login で作成されたクレデンシャルだけの生活がはじまる...

github.comのSettingsにあるクレデンシャルはゼロ)

と思ったのですが、現在はまだ完全には至っていません。

Jasperめちゃ便利なのでオススメです*1

jasperapp.io

*1:GHESのPR/Issueビューワーとしてフル活用しています

Calendar Versioningを扱うパッケージ/ツールとしてcalverを作った

提供する機能とは関係なくリリースを定期的に実施するようなプロダクトや、バージョンにSemantic Versioning(以下SemVer)のような意味付けがしにくいプロダクトの場合、バージョン管理手法にCalendar Versioning(以下、CalVer)というものが採用されることがあります。

calver.org

例えば、CalVerのサイトに掲載されているケーススタディで私が知っていたものとしてはUbuntuのバージョニング( YY.0M.MICRO )があります。 22.04 とか 22.10 とかのアレです。

そしてちょうど私がバージョニングしたいプロダクトも

  • 1ヶ月に1度定期的にリリースしたい
  • しかし、なにかしらの要因で1ヶ月に1度以上リリースすることがある

というものでSemVerではない気がするし、とは言え単純に 年月 でバージョニングすると同月リリースがあるとバージョンがかぶることがあるということでCalVerを採用することにしました。

そして、CalVerを操作するパッケージやツールを探したのですが微妙に用途にあわなかったため、車輪の再発明ですが作りました。

calver

github.com

calver はGoのパッケージでありツールであるのですが、多くはツールとしての利用することが多いと思うのでツールとしての calver の紹介をします。

CalVerのバージョンの管理方式は1つではありません。なので calver ではまずバージョンレイアウトを指定します。

$ date
Mon May 15 13:01:27 UTC 2023
$ calver --layout YYYY.0M.MICRO
2023.05.0
$ calver --layout YY.MM
23.5

指定できるパーツはCalVerのSchemaの項に掲載されているものが使用できます。

次のバージョン

そしてCalVerの特徴的なものが「次のバージョン」です。

レイアウトが YYYY.MM.MICRO、 カレントバージョンが 2023.4.0、現在の日付が2023年4月だった場合、次のバージョンは 2023.4.1 になります。 ところが、レイアウトが YYYY.MM.MICRO、 カレントバージョンが 2023.4.0、現在の日付が2023年5月だった場合、次のバージョンは 2023.5.0 になります。

日付表記のバージョンが被った場合のみ、数値バージョンの部分がインクリメントされるのです。

calver では対象となるバージョンと --next オプションを付与することで次バージョンを計算できます。

$ date
Tue May  9 13:04:09 UTC 2023
$ calver --layout YY.0M.MICRO
23.5.0
# 対象となるバージョンを標準入力もしくは引数で与えることができる
$ calver --layout YY.0M.MICRO | calver --layout YY.0M.MICRO --next 
23.5.1

最新のバージョン

「次のバージョン」の元となるバージョンは「最新のバージョン」です。

calver は標準入力もしくは引数で複数のバージョンを与えると、最新のバージョンを取得し表示します。また、その中に指定のレイアウトに合致しないバージョン文字列があっても無視します。

具体的には次のようにバージョニングされたリリース群に対して使うことを想定しています。

$ date
Tue May  9 13:04:09 UTC 2023
$ gh release list | cut -f 1
v1.1.2
v1.1.1
2023.05.1
2023.05.0
v1.1.0
v1.0.1
2023.03.1
2023.03.0
v1.0.0
2023.02.0
v0.1.0
$ gh release list | cut -f 1 | calver --layout YY.0M.MICRO
2023.05.1
$ gh release list | cut -f 1 | calver --layout YY.0M.MICRO --next
2023.05.2

--trim-suffix

UbuntuのCalVerのレイアウトは YY.0M.MICRO らしいです。ただし、 MICROバージョンが 0 の場合は末尾の .0 が省略されます。

それを実現するオプションとして --trim-suffix を用意しています。

$ date
Tue May  9 13:04:09 UTC 2023
$ calver --layout YY.0M.MICRO --trim-suffix
2023.05
$ calver --layout YY.0M.MICRO --trim-suffix | calver --layout YY.0M.MICRO --trim-suffix --next
2023.05.1

MODIFIERバージョンを特別に扱ったりなど、かなり用途に沿った実装をしたつもりです。

というわけで

もしCalVerを使う機会がありましたらcalverを検討してみてください。

OSSとPHPerKaigi 2023

3月23日から25日までPHPerKaigi 2023に参加してきました。

phperkaigi.jp

参加してみての感想は、一言で表すと

かつて思い描いていたカンファレンスと、想像以上を提供してくれるカンファレンスの融合を体験できて楽しかったし嬉しかった

です。

想像以上の体験を提供してくれるカンファレンス

これはPHPerKaigiのことです。

カンファレンス運営に対して狂気ともいえる情熱を注ぎ続ける主催者と、それを強固にバックアップするスタッフの方々が存在することにより実現される体験。まだ今年で4回しか参加していませんが、常にアップデートされています。アップデートの方向も想像がつかないです。毎回毎回楽しい(毎回同じでも楽しいのに!)。

あらゆる場所にエンターテイメントがあり、おもてなしがあり、当日以前にもカンファレンス開催前のビッグなノベルティボックスや、事前登壇の自動録画機能など驚きがあります。

2020年のグッズで今だに遊べるのがすごいですよね。まだ遊べる。ずっと遊べる。

かつて思い描いていたカンファレンス体験

日本のカンファレンスで有名なものの1つにRubyKaigiがあります。

私は一参加者としてRubyKaigi 2017に参加させてもらったことがあります。

RubyKaigi のオススメコンテンツは廊下」という言葉があるらしいのですが、RubyKaigi 2017でそれを見る機会がありました。

2階に上がる階段の下にたまたまあったようなホワイトボードを使ってRubyのコミッタの方々が(おそらくRubyの実装について)議論していました。何回か通りがかったのですが、ずっと議論していました。

そういえば、かつて学生時代に参加した学会でもそういった様子を見ることがありました*1

ただ、私は「見ていた」だけでした。当事者ではなかったのです。

とても羨ましく感じたのを覚えています。「希少なオフラインで会う機会を使って自分たちのOSSや研究を進める」というのがカッコよく感じました。

カンファレンスにずっとそういった思いを持ち続けて、今年、PHPerKaigiでその体験を得ることができました。

runnを一緒に開発しているkatzumiさんがPHPerKaigi 2023に参加されるということだったので、「これだ!」とばかりにrunnの次の機能について議論させてもうことができました。

詳しくはkatzumiさんが書いてくださったエントリが全てです。

zenn.dev

延々と「オタクの早口」で話していた気がします。ずっと嬉しくてテンションが高かったのを覚えています。

PHPerKaigiは場を提供してくれている

ところで、PHPerKaigi会場に「もくもく会スペース」があったのはご存じですか? runn開発者会議ではこの場を有効活用させてもらったりしました(ホワイトボードも少しお借りしました)。

もくもく会スペース」があるということは「もくもく」が推奨されているということです。Track Cとして「突然の発表(アンカンファレンス)の場」も提供されていましたね(Dでも発表がはじまったとか)。

「PHPerKaigiはコミュニティ」といわれているとおり、PHPerKaigiの会場が「発表と聴講の場」以上の設計がされているのがわかります。PHPerKaigiはあらゆるコミュニケーションに開かれていると感じます。

そして、PHPerKaigiはOSS開発にも開かれていました。

runn開発者会議ができて、自分の思い描いていたカンファレンス体験ができたのはPHPerKaigiの場のおかげです。

カンファレンス中の成果

カンファレンス中の成果です。

tblsのER図の出力調整

tblsのER図(SVG)の出力が微妙(私も薄々感じていました)というフィードバックをもらって、それをごりっごりのワークアラウンドで対応しました

runnクックブックにレシピ追加

CDPランナーの使用において必要になる設定についての紹介レシピを追加しました。

runnのSSHランナーでsudoができるのかを確認

SSHランナーは keepSession: true でセッションをステップ間で維持できるのですが、PHPerKaigi内での質問に「sudoも大丈夫なはず」と回答したのですが不安だったのでテストを追加して試してみました。

github.com

runnでシナリオのステップごとの成功/失敗を記録

これがrunn開発者会議のメイン議題だったのですが、「ステップが失敗してもそのまま継続して最後まで実行したい」というユースケースに対応するべく、まずはrunnのシナリオのステップごとに成功/失敗を記録するように内部実装をいじっていました。

Release for v0.65.0 by github-actions[bot] · Pull Request #468 · k1LoW/runn · GitHub

で、「ステップが失敗してもそのまま継続して最後まで実行」したとして「そのシナリオは果たして成功なのか失敗なのか」についてkatzumiさんと議論して、「そのシナリオは失敗だろう」ということに落ち着きました*2

GitHub Actionsの continue-on-error: を例に出して議論していたのですが「実現したいユースケースは多分 continue-on-error: とは違う」ということになり、設定名も違うものになりそうです。

近いうちに実装を終わらせます。

OSSとPHPerKaigi 2023

思えば、パンフレットに趣味OSSについて寄稿させてもらったり、

fortee.jp

発表の一部でOSSについて紹介させてもらったり、

runn開発者会議をしたり、

懇親会でEmacsユーザミートアップをしたり、

私のPHPerKaigi 2023はOSS色の強いものになりました。

実際はそれだけではなくて、 ペンライトが意外に楽しくてブンブン振ったり、コーヒーとビールが無限だったり、uzullaさんの最高のエンターテイメントでかつ強く考えさせられる発表で「D!T!O!!!D!T!O!!!」と手拍子したり*3、N次会で綺麗なそーだいさんをみたり*4、非公開なこともあったり*5、濃い三日間でした。

運営の皆様、スポンサーの皆様、発表者の皆様、ありがとうございました!

「また来年!*6

*1:研究会ごとに分野が絞られているのでそういったことが発生しやすいし、むしろそれが重要コンテンツなんだと思います

*2:2人でいろいろ考えて議論しました

*3:是非録画で見てほしい

*4:残念ながら録画でもみれない

*5:何も書けない。匂わせもできない

*6:ってクロージングで小桜エツコさんの声で言ってた

tblsをセットアップするGitHub Actionとしてsetup-tbls(を作るツールとしてgh-setup)を作った

タイトルが何を言っているのかよくわからないと思いますので順を追って紹介したいと思います。

tblsをセットアップするGitHub Actionとしてsetup-tbls を作った

setup-tblsはtblsをインストールしてくれるGitHub Actionです。

github.com

各所で「ないの?」とは言われており(最近Issueもたった)、いつか作らないとなと思っていたのですが、いろいろ重なって作りました。

github.com

私はGoで作ったツールのActionはDocker container actionを使うのですが、tblsでそうするとDockerコンテナ上で動くtblsからデータベースサーバの名前解決ができなかったりして、それも手を鈍らせている原因でした。

今回作成した setup-tbls はComposite actionで作っているので上記のような心配もありません。

なお余談ですが、ActionというかRunner上のJobの実行環境については次の資料にまとめてあります。

speakerdeck.com

使い方は簡単で紹介するまでもないですが、 uses: k1low/setup-tbls@v1 で呼び出せば終わりです。

# .github/workflows/doc.yml
name: Document

on:
  push:
    branches:
      - main

jobs:
  doc:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout .tbls.yml
        uses: actions/checkout@v3
      -
        uses: k1low/setup-tbls@v1
      -
        name: Run tbls for generate database document
        run: tbls doc

setup-*GitHub Actionを作るためのツールとして gh-setup を作った

setup-*install-* というActionは、大抵は実行ファイルをPATHに設置してくれるものです。

Goであれば本当にバイナリポン置きでいいのですし、そのバイナリは大抵GitHub Releasesにあるのであとは設置するだけなのですが、意外にこれが面倒なのです。

  1. まず実行環境を特定する(OSやArch)
  2. GitHub Releasesから特定バージョンもしくはlatestなリリースを特定
  3. 1の実行環境に適したリリースアセットを特定
  4. 3のリリースアセットが圧縮ファイルだったら展開
  5. 4の展開したファイルから必要なもの(今回は実行ファイル)だけ取得
  6. 実行環境のPATHを特定し5のファイルを設置

また、GitHub Releasesへのアセットの置き方も開発者によって、リポジトリによって千差万別です。私個人でもバラバラです(その時々でマイブームがある)。

それをいい感じにしてくれるツールとして gh-setup を作りました。

github.com

使い方はいくつかあるのですが、今回はGitHub Actionとしての使い方を紹介します*1

例えば、tblsをインストールする場合は以下のように書けます。

# .github/workflows/doc.yml
[...]
    steps:
      -
        name: Setup k1LoW/tbls
        run: k1LoW/gh-setup@v1
        with:
          repo: k1LoW/tbls

これだけで、煩わしい「GitHub Releaseからアセットを取得して実行ファイルをPATHに設置」をやってくれます。 中身は結構泥臭い実装が入っています。気になる方は是非 gh-setup のソースコードをご覧ください。

また、泥臭い実装を信用できない人にもいろいろオプションを用意していますので、詳しくは action.ymlのinputs:セクション をご覧ください。

さて、ここまで来たら勘のいい方はわかるかと思いますが、setup-tblsはgh-setupを組み込んで作っています。

setup-tblsのaction.ymlは次のとおりです。

name: 'Setup tbls'
description: 'GitHub Action for tbls, a CI-Friendly tool for document a database, written in Go.'
branding:
  icon: 'box'
  color: 'blue'
inputs:
  github-token:
    description: The GitHub token
    default: ${{ github.token }}
    required: false
  version:
    description: Version of tbls
    default: latest
    required: false
  force:
    description: Enable force setup
    default: ''
    required: false
runs:
  using: 'composite'
  steps:
    -
      uses: k1LoW/gh-setup@v1
      with:
        repo: github.com/k1LoW/tbls
        github-token: ${{ inputs.github-token }}
        version: ${{ inputs.version }}
        bin-match: tbls
        strict: true
        force: ${{ inputs.force }}

これだけです。ほとんどの処理はgh-setupの中にあります。

setup-* というGitHub Actionを作りたい方へ

是非 gh-setup をご検討ください。うまく動かない、気に食わない挙動についてはフィードバックいただけると嬉しいです。

これで setup-* は作りたい放題!

*1:実はGitHub CLI extensionとしてもスタンドアローンCLIツールとしても使えます