Gleamエコシステムでより多くのライブラリを構築するにつれ、Gleamのファイルシステム依存関係のサポートを活用してきました。 パスの依存関係により、複数のGleamパッケージをリンクして一緒に構築するローカルワークスペースを作成できます。これは素晴らしいことです!

最初にセットアップしたワークスペースは、CRDT実装のコレクションであるlatticeプロジェクトでした。 各データ構造は個別にパッケージ化されているため、カウンターやOR-setだけに依存することができ、他のすべてを引き込むことなく、各パッケージは独自のスケジュールでバージョン管理とリリースが可能です。これは明らかにlatticeに適した形です。

また、2つの問題も浮上しました。

正しい順序で実行すること。 単一のパッケージ内では、Gleamはパス依存関係をうまく扱います — 依存関係のソースを編集すると、コンシューマーの次のビルドでそれが反映されます。しかし、ワークスペースの認識はそこで終わります:gleam buildgleam testgleam publishはそれぞれ1つのパッケージディレクトリごとに動作します。ワークスペース全体で、または実際に変更が影響したパッケージ全体でテストを実行するには、justfileでトポロジカル順序でパッケージリストを手動で管理し、それをbashでシリアルにループする必要がありました。新しいパッケージが追加されるたびに手動でリストに追加する必要があり、依存関係グラフが進化するにつれて順序を検証するものは何もありませんでした。これは2つのパッケージでは問題ありませんが、それ以降はますます問題になります。

リリース。 複数パッケージのワークスペースをHexに公開するには、bashのグルーコードが必要でした:手動で公開順序を計算し、そして最悪の部分 — 各パッケージのパス依存関係を公開時に有効なHexバージョン要件に書き換え、その後で元に戻す必要がありました。このステップは自動化するのに最も面倒でエラーが発生しやすいものでした。リリースが半分失敗すると、リポジトリが書き換えられた状態のままになるからです。

また、当初はパッケージ間のバージョン管理の扱いに苦労しました。これは特定の方法で動作すべきだと考えています:すべてのユーザー向け変更は、着地時に小さなフラグメントファイルとして記録され、リリースは蓄積されたフラグメントをバージョンアップと変更ログエントリにバッチ処理します。幸いなことに、このワークフローを正確に自動化するChangieという優れたツールがあり、強くお勧めします。私はRustプロジェクト — 偶然にもこのプロジェクトを含む — で使用しています。

同じGleamワークスペースインフラストラクチャを必要とする3番目のプロジェクトに遭遇した後、問題を適切に解決する時が来たと判断しました。

Trellisの登場

この分野でかなりのプロフェッショナルな経験があるので、シナリオを書き留めてCLIをスケッチし、Fable 5に組み立ててもらいました。生成されたものにかなり感心しており、すでに自分のプロジェクトで使用しています。

結果はtrellisです — もちろん、格子が成長するフレームであるトレリスです。

設計原則:導出可能なものは設定せず、重複が必要なものは検証する。 別個のワークスペース設定ファイルはありません。ルートのgleam.toml[tools.trellis]テーブルがワークスペースをマークし、メンバーのglobをリストします。他のすべて — 依存関係グラフ、ビルド順序、公開順序、変更の影響、パス依存関係の書き換えマップ — はメンバーの独自のgleam.tomlファイルから計算され、宣言されることはありません。

# リポジトリルートのgleam.toml

[tools.trellis]

members = ["packages/*", "examples/*"]

exclude = { "@release" = ["examples/*"] }

これで日常のコマンドに十分です:

trellis run test # グラフ並列:パッケージはワークスペースの依存関係が

# 完了するとすぐに実行されます

trellis run test --since origin/main --with-dependents

# PRが触れたものと依存関係のみ

trellis graph --format mermaid # トポロジーを確認

trellis doctor # すべてのワークスペースの不変条件を一度にチェック

そして、私が実際に構築した理由であるリリースのため:

trellis changelog new --kind Added --body "..." # フラグメントを記録

trellis release pr # フラグメント -> リリースPR

trellis tag create --push --github-release # マージされたバージョンをタグ付け

trellis publish --all-untagged # 順序に従ってHexに公開

publishは以前最も嫌いだったbashスクリプトだったパス依存関係の書き換えを処理します:各ワークスペースのパス依存関係は、その依存関係の現在のバージョンから導出されたHex要件になり、gleam publishが実行され、元のgleam.tomlが復元されます — 失敗した場合でも。すでに公開されたバージョンはスキップされるため、部分的に失敗したリリースを再実行しても安全です。

意見を持っているがモジュール化されている

Trellisは意見を持っていますが、部品はモジュール化されているので、必要なものだけを採用できます。rungraphだけが必要な場合は、それらを使用し、既存のリリースプロセスを維持できます。また、変更ログエンジンをネイティブのChangie互換機能として組み込みました — .changes/unreleased/のフラグメント、設定可能な種類とバンプルール — なぜなら、CIとローカルの両方で、ワークスペースのシナリオ全体をエンドツーエンドで処理する単一のバイナリを持つことは素晴らしいことだからです。しかし、その動作が気に入らない場合は、置き換えることができます。

また、trellisリポジトリでバグレポート、機能リクエスト、プルリクエストなどを歓迎します。MITライセンスのオープンソースです。

単一の事前ビルドされたバイナリ(シェルインストーラー、Homebrew、mise、またはcargo install)として出荷されるため、CIでのインストールは約1秒で完了します。包括的なドキュメントはtrellis.tylerbutler.comにあります。リポジトリで複数のGleamパッケージを構築している場合は、試してみてください。