システム部の福原と申します。
前回に引き続き、あーだこーだしている日常を並べていきます。
ご笑覧あれー。
前回までのあらすじ
Spring 2.5 から ChainedTransactionManager が非推奨になりました。 そこで、このクラスを勝手Mavenアーティファクトにしてインハウスリポジトリに登録することになりました。 現在のソースを把握することができたので、Mavenアーティファクトにする作業にとりかかります。
詳細はこちら:
やること整理
まずやること整理しよう。色々ありそうだ。ええと??
- ソースの修正と単体テストを追加する
- リポジトリの場所を決定する
- リポジトリへの登録処理を設定する
- リポジトリの詳細な構成を検討する
- その他細かい事を決めていく
では片端からやって行こう。
ソースの修正と単体テストを追加する
ソースは基本的にそのままでよいのだけれど、せっかくなのでKotlinに変換してしまおう。
それにしてもIntelliJの変換機能は便利すぎるぜ!コピペするだけで変換できてしまう。
https://www.jetbrains.com/help/idea/get-started-with-kotlin.html#2d4faf0b
変換後に警告出てまた直したりするけどそれぐらいはご愛嬌だ。
そういえば単体テストがついているな。ありがたい。流してjacocoでカバレッジ確認しよう。
<<ドタドタ。バタリ。>>
むむ?例外系のテストが一部無くて、カバレッジ100%になっていないな。テストが取っていれば緑色だが通ってないところは赤い。それにSavePoint関係のコードは全くテストされてない。
うーん、面倒だがテスト書くか。カバレッジ通すためのテストはしんどいがやむを得ない。そんなに難しいことではない。ついでにSavePoint関係の機能はぶっちゃけいらないから本体もろとも消してしまおう。
テストコードではモックライブラリとか使っていなくて自前でモックのクラスを作っていたようだ。Mockito とか便利なのにな。なんで使わないのだろう?依存を増やしたくなかったのかな?
<<ドタドタ。バタリ。>>
よしできた。ではアーティファクト化しようか。
リポジトリの場所を決定する
リポジトリの場所をどうしようか。インハウスリポジトリだったら既に社内オンプレミス環境にあることはある。今までのやり方ならこれを使うのだが、今やっている新しい仕組みでは Github Actions でCIをやっている。社内環境のリポジトリだとアクセス制御の設定面倒そうだ。これも Github に寄せてしまおう。では GitHub Packages で決まりだ。
https://docs.github.com/ja/packages/learn-github-packages/introduction-to-github-packages
リポジトリへの登録処理を設定する
gradle からアーティファクトを登録するには build.gradle.kts
に設定をいれて gradlew publish
を実行すればよい。
実運用段階では登録もこのプロジェクトの Github Actions でやることになるだろう。 そして動作確認用途もあるだろうから、手元PCからでもリポジトリに登録できるようにしておこう。
両対応するにはどうしたらよいだろうか? 既にgithub関係で共通的に使う ci-user
というユーザが既にあるから、まずこいつの Personal Access Token を作成しよう。 で、Github Actions で動かすときは環境変数 PAT_FOR_CI
にこの値を設定しよう。 gradle では、PAT_FOR_CI
があったらその値を使う。なかったら手元PC上の設定を使う。
build.gradle.kts
への設定はこうなる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
val githubUser: String by project val githubToken: String by project publishing { repositories { maven { name = "ghp" url = uri("https://maven.pkg.github.com/GMORBLOGDUMMY/SOMEREPOSITORY") credentials { username = if (System.getenv()["PAT_FOR_CI"] == null) githubUser else "ci-user" password = System.getenv()["PAT_FOR_CI"] ?: githubToken } } publications { create<MavenPublication>("TransactionManager") { from(components["java"]) artifact(tasks["sourcesJar"]) // ソースもアーティファクトに入れるための設定。後述。 } } } } |
今後このライブラリを使うプロジェクトがたくさん増えることを考えると、 認証の情報を手元PC上のプロジェクトフォルダそれぞれに置くと面倒そうだ。 $USER_HOME/.gradle
に、gradle.properties
を置いて、認証情報を登録するようにしよう。 各開発者さんたちに、read:packages
できるようなPersonal Acccess Token を作ってもらって、こういうファイルを入れてもらえばよい。
1 2 |
githubUser = <<各開発者のgithubアカウント>> githubToken = <<各開発者のPersonal Acccess Token>> |
あと、ついでにソースもjarにしてアーティファクトに入れておこう。IDEAからソース確認したいときもあるだろう。
1 2 3 4 5 6 |
tasks { val sourcesJar by creating(Jar::class) { archiveClassifier.set("sources") from(sourceSets["main"].allSource) } } |
javadoc相当のものはない。けどそれはそれで無くてもいいかな。
これでよし! gradlew publish
もできた。
リポジトリの詳細な構成を検討する
GitHub Packages ではそれぞれの git リポジトリに maven のリポジトリを持たせることができる。 今 publish
したのはソース管理の git リポジトリと同じ場所だ。 アーティファクトが増えるごとに maven のリポジトリが増えるという今のやりかただと、 今後 build.gradle.kts
が長大化して無闇に大変になるかもしれない。
アーティファクトのソースを管理するリポジトリとは別に、maven のリポジトリ専用の git リポジトリを設定するようにしようか。
よし、いままではなんとなく自分のリポジトリに gradlew publish
していたが、maven 専用の git リポジトリにしよう。新しく git リポジトリを作って、こっちに向き先変えて、試しに登録、と。
1 2 3 4 5 6 7 |
c:\dev\testproject>gradlew publish > Task :publishTransactionManagerPublicationToGhpRepository FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':publishTransactionManagerPublicationToGhpRepository'. > Failed to publish publication 'TransactionManager' to repository 'ghp' > Could not PUT 'https://maven.pkg.github.com/GMORBLOGDUMMY/SOMEREPOSITORY/nantoka/nantoka-transactionmanager/0.0.1/nantoka-transactionmanager-0.0.1.jar'. Received status code 422 from server: Unprocessable Entity |
あれ、エラー?なんでだ?なにか制約あるのかな?
Githubのサポート
同じgroupIdとartifactIdを持つアーティファクトを登録できるリポジトリは、organizationで1個だけですよ。
おおう、そうなのか。じゃあ向き先変える前の元のアーティファクトを消してもう一回登録すればよいな。よしできた。
これってgithubの設計としてはどうなんだろう?あるアーティファクトが複数リポジトリに散在するのはだめだって事か。とっ散らかるよりは良いのかな?
その他細かい事を決めていく
CI/CD。基本的にこれは今まで通りでよい。CIはコミット入ったときに全テスト流して結果をPRにメッセージを上げるように Github Actions を仕込む。CDとしてはリリースタグを作ったときに新しい版のアーティファクトが publish
されるようにする。Github Actions の設定はこんなふうにすれば良い。
1 2 3 4 |
on: push: tags: - '*.*.*' |
わかりやすいようにこのアーティファクトのバージョンは、Spring Boot のバージョンと揃えるようにしよう。
このアーティファクトを使う方は、リポジトリへの認証の情報を設定して、depencencies にこのアーティファクトを入れればよい。
ん?これで完成したかな?
完成!
よっしゃ、できたぞー。
いやー色々大変だった。最初はやり方が分からなくてどうしようかと思った。
でもこれ、もしspringの中の人が やっぱDeprecated やめるー とか言い出したら今までの苦労は全部水の泡だな。けどなんだかんだ半年以上経っているし、このまま行くと思う。頼む、このまま行ってくれ。
それにしても、何故このクラスはDeprecatedになったのだろう?
……
DBアクセス周りのAPIの構造を非互換が起きるほどに変えたかった、とか無いかな……? そのインパクトを減らすために、自分で使っているライブラリを使わせないようにしている……とか?
そう考えるともしかしたらSpring Boot 3系では、このトランザクションマネージャも非互換のあおりを受けるかもしれない。
でもまあその時はその時かな。
気にしても仕方がないことだ。さあ次へ行こう。