Docker でテストする
src/ci/docker ディレクトリには、GitHub Actions で実行される Linux ベースのジョブ用の Docker イメージ定義が含まれています(Linux 以外のジョブは Docker の外部で実行されます)。
これらのジョブはローカルの開発マシンで実行でき、
ローカルシステムとは異なる環境をテストするのに役立ちます。
Linux、Windows、または macOS システムに Docker をインストールする必要があります(通常、Linux のほうが Windows や macOS よりもはるかに高速です。後者は Linux 環境をエミュレートするために仮想マシンを使用するためです)。
CI で実行されるジョブは一連の bash スクリプトを通じて設定されており、その挙動をローカルで再現するのは必ずしも簡単ではありません。
CI ジョブをできるだけ簡単な方法でローカル実行したい場合は、CI で起きることを可能な限り忠実に再現しようとする、提供されているヘルパー citool を使用できます。
cargo run --manifest-path src/ci/citool/Cargo.toml run-local <job-name>
# 例:
cargo run --manifest-path src/ci/citool/Cargo.toml run-local dist-x86_64-linux-alt
上記のスクリプトがうまく動作しない場合、Docker イメージの実行をより細かく制御したい場合、または Docker ジョブの実行中に正確に何が起きるのかを理解したい場合は、以下を読み進めてください。
run.sh スクリプト
src/ci/docker/run.sh スクリプトは、特定の Docker イメージをビルドして実行し、
そのイメージ内で Rust をビルドし、テストを実行するか、配布用に設計された一連のアーカイブを準備するために使用されます。
このスクリプトは、ローカルの Rust ソースツリーを読み取り専用モードで、obj ディレクトリを読み書き可能モードでマウントします。
コンパイラーの成果物はすべて obj ディレクトリに保存されます。
シェルは obj ディレクトリで開始されます。
そこから、Docker イメージで定義されたビルドを開始する ../src/ci/run.sh を実行します。
src/ci/docker/run.sh <image-name> を直接実行できます。
run.sh スクリプトに関する重要な注意点がいくつかあります。
- CI 上で実行される場合、このスクリプトはすべてのサブモジュールがチェックアウトされていることを期待します。
ジョブからアクセスされるサブモジュールの一部が利用できない場合、ビルドはエラーになります。
したがって、必要なサブモジュールがすべてローカルでチェックアウトされていることを確認する必要があります。
これは git で手動で行うことも、
bootstrap.tomlでbuild.submodules = trueを設定してx buildのようなコマンドを実行し、bootstrap に最も重要なサブモジュールをダウンロードさせることもできます ただし、実行しようとしている特定の CI ジョブに対しては、これだけでは十分でない場合があることに注意してください。 <image-name>は、src/ci/docker/host-*ディレクトリのいずれかにある単一のディレクトリに対応します。 一部のジョブは同じイメージを実行しますが、異なる環境変数や Docker ビルド引数を使用するため、イメージ名が必ずしもジョブ名に対応するとは限らないことに注意してください これは、CI ジョブをローカルで実行することを難しくしている複雑さの一部です。- “dist” ジョブ(
dist-で始まるジョブ)を実行する場合は、DEPLOY=1環境変数を設定する必要があります。 - “alternative dist” ジョブ(
dist-で始まり-altで終わるジョブ)を実行する場合は、DEPLOY_ALT=1環境変数を設定する必要があります。 - 一部の std テストには IPv6 サポートが必要です。
Linux 上の Docker では、デフォルトで無効になっているようです。
コンテナーを作成する前に、IPv6 を有効にするために
enable-docker-ipv6.shのコマンドを実行してください。 これは一度だけ行えば十分です。
対話モード
特定の Docker イメージをビルドしてから、その中でカスタムコマンドを実行し、対象システムの挙動を試せるようにすると便利な場合があります。
これは対話モードを使用して行うことができ、
src/ci/docker/run.sh --dev <image-name> を使用してコンテナー内で bash シェルを開始します。
Docker コンテナー内では、特定のタスクを実行するために個別のコマンドを実行できます。
たとえば、UI テストだけを実行するために ../x test tests/ui を実行できます。
対話モードの使用に関する追加の注意点をいくつか示します。
- シェルを終了するとコンテナーは自動的に削除されますが、
ビルド成果物は
objディレクトリに残ります。 異なる Docker イメージ間で切り替えている場合、objディレクトリに保存された以前の環境の成果物が ビルドシステムを混乱させる可能性があります。 コンテナー内でビルドする前に、objディレクトリの一部または全部を削除する必要がある場合があります。 - コンテナーは最小限で、最小限のパッケージセットしか含まれていません。
apt install less vimのように、いくつかのものをインストールしたくなるかもしれません。 - コンテナー内で複数のシェルを開くことができます。
まずコンテナー
名(短いハッシュ)が必要です。これはシェルプロンプトに表示されます。または、コンテナーの外部で
docker container lsを実行して、利用可能なコンテナーを一覧表示できます。 コンテナー名がわかったら、docker exec -it <CONTAINER> /bin/bashを実行します。ここで<CONTAINER>は4ba195e95cefのようなコンテナー名です。