🦄
CodeX × Android開発:オフライン環境でもテスト可能なGradle依存の事前取得法
CodeX × Android開発:オフライン環境でもテスト可能なGradle依存の事前取得法
背景・問題意識
私が開発しているプロジェクトは、以下のような構成になっています:
- 複数のアプリを 1 つのリポジトリにまとめた「マルチアプリ構成」
- アプリ間でコードを共有するための「マルチモジュール構成」
CodeX にテストも担保してもらいながら開発を進めるためには注意が必要です。CodeX はセットアップ処理の完了後にオフライン環境に切り替わるため、./gradlew test
を正常に実行させるには、セットアップ時にすべての依存関係を解決・ダウンロードしておく必要があります。
CodeX対応のセットアップスクリプト全体像
本記事では、CodeX で Android プロジェクトのテストを正常に実行できるようにするためのセットアップ手順を紹介します。
やっていること(概要)
-
setup.sh
で Android SDK, Build Tools, ライセンス承諾を自動化 -
resolveAllDependencies
タスクをbuild.gradle.kts
に追加して、全モジュールの依存解決を一括で実行
setup.sh(抜粋)
#!/bin/bash
set -ex
export ANDROID_SDK_ROOT="/root/android-sdk"
apt-get update && apt-get install -y expect
mkdir -p "$ANDROID_SDK_ROOT/licenses"
echo "8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_SDK_ROOT/licenses/android-sdk-license"
mkdir -p "$ANDROID_SDK_ROOT/cmdline-tools"
cd "$ANDROID_SDK_ROOT/cmdline-tools"
curl -sSL -o tools.zip https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
unzip -q tools.zip
rm tools.zip
mkdir -p latest
mv cmdline-tools/* latest/
export PATH="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/platform-tools:$PATH"
yes | "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" --licenses > /dev/null
expect <<EOF
spawn sdkmanager --sdk_root="$ANDROID_SDK_ROOT" --no_https \
"platform-tools" \
"platforms;android-35" \
"build-tools;35.0.0"
expect {
"Accept? (y/N):" { send "y\r"; exp_continue }
eof
}
EOF
gradle help --no-daemon
PROJECT_DIR="/workspace/your_project_name"
echo "sdk.dir=$ANDROID_SDK_ROOT" > /workspace/your_project_name/local.properties
cd "$PROJECT_DIR"
./gradlew resolveAllDependencies
※スクリプト全体は推敲中のため、冗長な処理が残っている可能性があります。
build.gradle.kts(プロジェクトルート)
allprojects {
tasks.register("resolveAllDependencies") {
group = "dependency"
description = "Resolves and downloads all dependencies for all configurations in all projects."
doLast {
configurations
.filter { it.isCanBeResolved }
.forEach { config ->
println("🔍 Resolving ${config.name} in ${project.name}")
try {
config.resolve()
} catch (e: Exception) {
println("❌ Failed to resolve ${config.name} in ${project.name}: ${e.message}")
}
}
}
}
}
なぜこの構成にしたのか:試行錯誤の背景と設計意図
SDK ライセンス受諾の自動化
mkdir -p "$ANDROID_SDK_ROOT/licenses"
echo "8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_SDK_ROOT/licenses/android-sdk-license"
これは、sdkmanager
コマンド実行時に毎回表示されるライセンス確認を事前に済ませるためです。
SDK コンポーネントの自動インストールと応答制御
当初は以下のように yes
コマンドを使って一括応答させる方法を検討しました:
yes | sdkmanager --sdk_root=... "platforms;android-35" ...
しかし、CodeX の本番実行環境ではこの方法ではプロセスが途中で停止してしまうことがあり、安定したセットアップを構築できませんでした。
そのため、expect
コマンドで Accept? (y/N):
に明示的に "y" を送る方法に切り替えました。
Gradle の依存ライブラリ事前解決
./gradlew resolveAllDependencies
このタスクは canBeResolved
な全設定に .resolve()
を実行し、事前に依存ライブラリをすべてキャッシュに保存します。プロジェクトが大きく ./gradlew test
や ./gradlew build
では依存取得が間に合わない場合にも有効です。
local.properties による SDK パス指定
以下のようなエラーを避けるため:
SDK location not found. Define a valid SDK location with an ANDROID_HOME environment variable
or by setting the sdk.dir path in your project's local.properties file
次のように local.properties
を生成しています:
echo "sdk.dir=$ANDROID_SDK_ROOT" > /workspace/soundverse-android/local.properties
Discussion