LoginSignup
0
0

More than 5 years have passed since last update.

CircleCIで別プロジェクトをMavenライブラリとして追加し、ビルドに使わせる方法

Posted at

背景

一つの親Mavenプロジェクトの元にプロジェクトAとプロジェクトBという二つの子Mavenプロジェクトがあります。プロジェクトAとプロジェクトBは個別にGitHubに通じてCircleCIへ追加されていますので、無関係なプロジェクトとして見なされています(即ち、リポジトリは別々)。しかし、プロジェクトAはプロジェクトBの機能を使っている為、プロジェクトBへの依存性が存在します。

課題

ローカル環境では、プロジェクトAとBの兄弟関係が親Mavenプロジェクト経由で確認できる為、プロジェクトAのpom.xmlにプロジェクトBをdependencyとして追加するだけで、ビルドが可能になります。しかし、CircleCI上では無関係なプロジェクトとして見なされていますので、Could not resolve dependencies for projectが発生し得ます。プロジェクトAのpom.xmlを汚さずにディペンデンシーの依存解消を果たしたいです。

解決法

様々なやり方で試行錯誤を重ねた末に、下記の方法が一番単純で行いやすいんじゃないかと思います。

  1. プロジェクトBのビルド成果物をartifactとして出力
  2. プロジェクトA側ではCircleCIのAPIに通してBのパッケージをダウンロード
  3. CircleCIがディペンデンシー解消を行う前にMavenインストールに通してBを外部ライブラリとして導入

詳細手順

イ プロジェクトBにMaven Assembly Pluginを導入

以下のコードをプロジェクトBのpom.xmlに入れます。これを使用しなければ、プロジェクトBが使用しているライブラリがjarに含まれない可能性が存在します1

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <!-- ... -->
  <build>
    <plugins>
      <!-- ... -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.5.5</version>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
        <executions>
          <execution>
            <id>assemble-all</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <!-- ... -->
    </plugins>
  </build>
  <!-- ... -->
</project>

ロ プロジェクトBに成果物をartifactとして指定

CircleCIに出力したいファイルをartifactに指定する必要があります。やり方は以下のコードをcircle.ymlに追加することです。

#...#
general:
    #...#
    artifacts:
        #このファイル名はmaven-assembly-pluginのデフォルトのようです
        - "target/<ファイル名>-<バージョン>-jar-with-dependencies.jar"
    #...#
#...#

ハ プロジェクトBをコミットし、ビルド成功を確認

特に変なことが発生しなければ、成功するはずです。
ちなみに、成果物をartifactに指定すれば、CircleCIのビルドページからもダウンロード可能になります。(artifacts項目内)

ニ アクセストークンを発行

プライベートプロジェクトであれば、artifactをダウンロードするのにアクセス用のトークンが必要になります。
アクセストークンはCircleCIの「ACCOUNT SETTINGS」→「Personal API Tokens」→「Create New Token」にて発行できます。

circleci-access-token.PNG

ホ アクセストークンをプロジェクトAの環境変数に追加

プロジェクトAのビルドでAPIを使ったり、ダウンロードを行ったりする為、トークンが発行できたら、プロジェクトAの環境変数にそれを入れます。
場所は「PROJECT SETTINGS(歯車記号)」→「Environment Variables」→「Add Variable」です。

circleci-add-environment-variables.PNG

ヘ ディペンデンシー追加用スクリプトを作成

add_dependencies.shというファイルを作成し、以下の内容を入れます(プロジェクト名をproject_bとしています、<>で囲まれている部分は適切な値に置き換えてください)。
一行目で追加したjqというライブラリはCircleCIから返されてきたJsonレスポンスを解読する為に使用されます2

#!/bin/sh
sudo apt-get install jq
currentDirectory=$(pwd)
echo $currentDirectory
downloadUrl=$(curl -sS "https://circleci.com/api/v1.1/project/github/<ユーザ/組織名>/project_b/latest/artifacts?circle-token=$MY_ACCESS_TOKEN&branch=<ブランチ名>" | jq '.[] | .url' | grep project_b.*with-dependencies\.jar | sed -e "s/\"//g")
echo $downloadUrl
sudo wget $downloadUrl?circle-token=$MY_ACCESS_TOKEN -O project_b.jar --quiet
mvn install:install-file -Dfile=$currentDirectory/project_b.jar -DgroupId=<グループID> -DartifactId=project_b -Dversion=<バージョン> -Dpackaging=jar -DgeneratePom=true

*注意:wgetに--quite-qを付けなければ、トークンがコンソールに出力される恐れがありますので、必ずつけて下さい3
*使用しているCircleCIのAPIはこちら

ト CircleCIの実行手順にスクリプトを追加

スクリプトが完成できたら、プロジェクトAのcircle.ymlにそれを実行させるコマンドを追加します。実行のタイミングはCircleCIがディペンデンシーを解消する前です。

# ... #
dependencies:
    pre:
        - sudo chmod a+x add_dependencies.sh
        - ./add_dependencies.sh
# ... #

チ プロジェクトAをコミットし、ビルド成功を確認

待望の画面を迎えましょう!
circleci-success.PNG

ご参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0