Java開発をするにあたり、ローカル環境はオンラインだけど、CI/CD環境はオフラインという特殊な環境で開発をすることはありませんでしょうか?
私はありました…
いろいろ苦労はしましたが、なんとかうまくCI/CDを回すことに成功したので、gradleプロジェクトをオフライン環境でもテスト・ビルドができるようにする方法をご紹介します!
下準備
今回はSpring Initializrで作成したプロジェクトを対象にやってみます。
生成されたbuild.gradleは以下の通りです。必要なライブラリがあれば追加しましょう。
plugins { id 'org.springframework.boot' version '2.5.2' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' } group = 'com.think-memo' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' } test { useJUnitPlatform() }
作業
以下の作業はオンライン環境のローカルPCで作業していきます。
プラグインの設定を追加
利用しているプラグインがある場合は、以下のように設定を追加します。
dependenciesには利用しているプラグインを「gradlePlugin」として、必要な分追記しておきます。
configurations { compileOnly { extendsFrom annotationProcessor } gradlePlugin } ... dependencies { ... gradlePlugin 'org.springframework.boot:spring-boot-gradle-plugin:2.5.2' }
ライブラリコピーgradleタスクの作成
オフラインでもビルドするためには、あらかじめ必要なライブラリ(jarファイル)をダウンロードしておき、プロジェクトに含めておく必要があります。
ただ手作業で依存ライブラリを持ってくると労力がかかりすぎるので、かき集めてくれるgradleタスクを作成します。
task copyLibs { doLast { // dependenciesで利用している設定を定義する def targetDependencies = [ "compileOnly", "developmentOnly", "implementation", "testImplementation", "gradlePlugin" ] targetDependencies.each({ def dir = new File("${projectDir}/lib/" + it) if (dir.exists()) { dir.delete() } def conf = configurations.getByName(it) conf.canBeResolved = true copy { from conf into dir } }) } }
タスクの実行
作成したgradleタスクを実行します。
プロジェクト直下で以下のコマンドを実行すればOKです。
gradle copyLibs
正常終了したら、libフォルダ以下にライブラリがコピーされていると思います。
オフライン用build.gradleの作成
先ほどのタスクで集めてきたライブラリを利用してビルドを行う設定を記述したbuild.gradleを作成します。
既存の内容を書き換えてもいいんですが、新しいライブラリを追加する際に不便なので、既存のbuild.gradleをバックアップしておくことをお勧めします。
ということで、既存のbuild.gradleをbuild_online.gradleという名称でコピーします。
cp build.gralde build_online.gradle
コピーが完了したらbuild.gradleの内容をオフライン向けに変更します。
赤い部分が変更した箇所です。
buildscript {
dependencies {
classpath fileTree(includes: ['*.jar'], dir: 'lib/gradlePlugin')
}
}
plugins {
id 'java'
}
apply plugin: 'org.springframework.boot'
group = 'com.think-memo'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation fileTree(dir: 'lib/implementation')
implementation fileTree(dir: 'lib/extra')
compileOnly fileTree(dir: 'lib/compileOnly')
developmentOnly fileTree(dir: 'lib/compileOnly')
annotationProcessor files('lib/compileOnly/lombok-1.18.20.jar')
testImplementation fileTree(dir: 'lib/testImplementation')
}
test {
useJUnitPlatform()
}
ポイントは以下の3つです
①dependenciesは「fileTree」または「files」にする。
②プラグインの依存ライブラリは「buildscripts」の「dependencies」に記述する
③Gradle標準以外のプラグインは「apply plugin」で記述する
ビルド実行
設定ができたらビルドを実行してみましょう。
今回はSpringBootのプラグインがないと実行できないbootJarタスクを実行してみます。
gradle bootJar
build/libs以下にjarが作成されて入ればOKです!
ライブラリをリポジトリに追加
<project_root>/lib配下のライブラリをすべてリポジトリに追加してしまいましょう。
こうすることで、オフラインのCI/CD環境でもテストおよびビルドの実行が可能になります!
補足
ライブラリが追加になったとき
開発途中でライブラリが追加になったとき以下の手順を実施します。
①dependenciesの追加
まずbuild_online.gradleのdependenciesに追加します。
②copyLibsタスク実行
追加したら、build_online.gradleを指定してcopyLibsを実行します。
※ここはオンライン環境で実施する必要があります。
gradle copyLibs -b build_online.gradle
lib配下に追加したライブラリがコピーされていればOKです。
リポジトリ追加を忘れずに!
まとめ
オフラインのCI/CD環境は特殊な環境だと思いますが、セキュリティ要件の高い環境では意外と目にするかもしれません。
ローカル環境でビルドするという方法に逃げると後で大変ですし、障害の原因にもなりますので、ぜひ今回の記事を参考に、自動でビルド・テストできるCI/CD環境を構築しちゃいましょう!
コメントを残す