こんにちは。トグルホールディングス SRE/プラットフォームエンジニアリングチームの小澤 (@kota65535)です。
この記事は トグルホールディングス アドベントカレンダー 2024 の 10 日目の記事です。
概要
弊社では開発ツールのインストールに Mise を使っています。Miseは Asdf の後継で、 言語ランタイム(例: Node.js, Python)やCLI(例: AWS CLI, Terraform)などのツールの指定したバージョンをコマンド一発で入れてくれます。 またBackendという概念があり、既存のAsdfプラグインがそのまま流用できる他、npmやpipx経由で入るツールも管理できます。
しかしながら、弊社で利用しているMySQLのマネージドサービスである PlanetScale を操作する PlanetScale CLI には未対応であったため、 これをインストールするAsdfプラグインを作ってみました。今回はその手順を残したので共有したいと思います。
成果物
手順
公式のプラグイン作成の手順に沿って進めます。 asdf-vm.com
レポジトリの作成
公式のテンプレートレポジトリ が用意されているので、これを元に作成します。
- Use this template → Create a new repository から新規レポジトリを作成
- Repository name
asdf-{プラグイン名}の形式にする。今回はasdf-planetscale-cliとした
- Repository name
- レポジトリが作成できたら手元に
git cloneする
初期化
READMEのUsageの手順に従い setup.bash を実行します。対話式で様々な質問をされるので回答していきます。
% bash setup.bash
- プラグイン名。先に決めた
planetscale-cliと入れる
Name for your plugin, starting with `asdf-`, eg. `asdf-foo` > planetscale-cli
- インストールが成功したことをテストするためのコマンド。これが0を返せば正常にインストールされたと見なす。単に
pscaleでも良いが 今回はバージョンを返すpscale --versionとした
Shell command for testing correct tool installation. eg. `foo --version` or `foo --help` [planetscale-cli --help] > pscale --version
- GitHubのユーザー名と氏名
Your GitHub username > kota65535 Your name [Tomohiko Ozawa] >
- ライセンス。特にこだわり無ければMITで良い
Please choose a LICENSE keyword. See available license keywords at https://help.github.com/en/github/creating-cloning-and-archiving-repositories/licensing-a-repository#searching-github-by-license-type License keyword: MIT/APACHE-2.0/MPL-2.0/AGPL-3.0 > MIT
- 入力内容の確認。yesをタイプするとテンプレートのソースコードを回答に沿って改変して Commit & Force Push する
Setting up plugin: asdf-planetscale-cli author: Tomohiko Ozawa plugin repo: https://github.com/kota65535/asdf-planetscale-cli license: https://choosealicense.com/licenses/mit/ planetscale-cli github: https://github.com/planetscale/cli planetscale-cli docs: https://planetscale.com/docs/reference/planetscale-cli planetscale-cli test: `pscale --version` After confirmation, the `main` will be replaced with the generated template using the above information. Please ensure all seems correct. Type `yes` if you want to continue. > yes
スクリプトの実装
AsdfプラグインはMise (Asdf) のコマンドから呼び出されるいくつかのシェルスクリプトを実装する必要があります。スクリプトは bin 以下に配置されています。
テンプレートの時点でデフォルトの実装が入っているので、ツールのリリース方法が素直であればそんなにやることは無いです。
list-all
mise ls-remote {プラグイン名} コマンドから呼び出され、インストール可能なバージョンを列挙します。
出力形式は空白で区切られたバージョンのリスト(例: 1.0.1 1.0.2 1.1.0)です。
テンプレートのデフォルト実装ではGitHub Releaseのバージョンをリストアップしてくれる挙動になっています。 PlanetScale CLIのバイナリは GitHub Release でリリースされているので、変更なしでOKでした。
download
mise install {プラグイン名@バージョン} から呼び出され、実際にそのツールの指定されたバージョンをダウンロードします。
上記の通りGitHub Release からリリースされているので、ファイル名さえ分かれば問題無くダウンロードできます。
PlanetScale CLIはGoで書かれており、GoReleaserでリリースされているのでファイル名のパターンは
pscale_{バージョン}_{OS}_{アーキテクチャ}.{圧縮フォーマット}
となっています。そのため、ダウンロードの際にOSとアーキテクチャ、圧縮フォーマットを判別してやる必要があります。
- OS
get_platform() { plat=$(uname | tr '[:upper:]' '[:lower:]') case ${plat} in darwin) plat='macOS' ;; linux) plat='linux' ;; windows) plat='windows' ;; esac echo "${plat}" }
get_arch() { arch=$(uname -m | tr '[:upper:]' '[:lower:]') case ${arch} in aarch64 | aarch64* | armv8*) arch='arm64' ;; arm | armv6* | armv7*) arch='arm' ;; x86_64) arch='amd64' ;; i386 | i686) arch='386' ;; esac echo "${arch}" }
- 圧縮フォーマットは、AsdfはWindowsに正式対応していないので
tar.gzで固定です。
これらの関数を使ってダウンロード用のURLを構築すれば後はほぼデフォルト実装で良いのですが、一点だけちょっとハマりポイントがありました。
圧縮ファイルを展開する際の tar コマンドに --strip-components=1 という見慣れないオプションが付いているのですが、
これは展開時にディレクトリの第1階層を切り捨てる挙動になります。PlanetScale CLIのバイナリは第1階層にいるのでこのオプションは外しましょう。
- tar -xzf "$release_file" -C "$ASDF_DOWNLOAD_PATH" --strip-components=1 || fail "Could not extract $release_file" + tar -xzf "$release_file" -C "$ASDF_DOWNLOAD_PATH" || fail "Could not extract $release_file"
install
downloadスクリプトでダウンロードしたバイナリを Mise (Asdf) の管理する所定のパスにコピーします。これもデフォルト実装のままでOKです。
動作確認のコツ
シェルスクリプトなので当然ローカルでそのまま実行できます。しかし、例えばdownloadスクリプトだと単に実行するだけだとこんな感じで落ちます。
% ./bin/download ./bin/download: line 11: ASDF_DOWNLOAD_PATH: unbound variable
これは Mise (Asdf) がプラグインのスクリプトを実行する際に特定の環境変数をセットしているためです。何がセットされるかは Environment Variables available to script セクションに書かれています。 downloadスクリプトの場合、以下のようにすればローカルで実行できます。
export ASDF_INSTALL_TYPE=version # ダウンロードしたいバージョンを指定 export ASDF_INSTALL_VERSION=0.216.0 export ASDF_INSTALL_PATH=./ # 現在のワーキングディレクトリにダウンロード export ASDF_DOWNLOAD_PATH=./
CI/CD
ありがたいことに、テンプレートの時点でGitHub Workflowが整備されています。
- Buildワークフロー
- PR作成・更新で発火
- プラグイン経由でのインストール・ツールのコマンド実行までをテスト
- Releaseワークフロー
- mainブランチへのPushで発火
- GitHub Release を自動的に作成
Releaseワークフローが走ったらもうそのまま使えます。
使い方
mise.toml を以下のように作成します。
Mise Registry に登録していないので [plugins] セクションでプラグインを追加します。
[tools] planetscale-cli = "0.216.0" [plugins] planetscale-cli = "https://github.com/kota65535/asdf-planetscale-cli"
インストール実行。問題なく入りました!
% mise install mise plugin:planetscale-cli ✓ https://github.com/kota65535/asdf-planetscale-cli#c1d025e mise planetscale-cli@0.216.0 ✓ installed % pscale --version pscale version 0.216.0 (build date: 2024-12-02T23:02:15Z commit: b50c743)
結論
公式テンプレートレポジトリのお陰で、思ったよりわずかな実装だけで新たなAsdfプラグインを作ることができました。 プラグインの本体はシェルスクリプトなので、やろうと思えばどんなリリース形態でも柔軟に対応することが可能です(それゆえセキュリティ的に問題があるとも言われるのですが)。 みなさんもお気に入りのツールがあれば是非作ってみてください。