com4dc’s blog

Javaプログラマーのはずだけど運用してます

GithubのRepositoryをmavenリポジトリとして使う

なんで今さら

  • 数年前に開発が停止してしまっているコードをフォークして利用したい
  • 元のソースのApache License 2.0。フォークしたコードはOSSとして公開しないといけない?(うろ覚え・・・)
    • ソースコードをそのまま組み込むのはNGそうな気がする?
    • 修正と再頒布そのものは禁止されていない(はず
  • maven のローカルリポジトリとして修正したコードを公開する
  • 実際のコードにはこれを取り込んで使う

手順

maven の deploy タスクの実行によって生成物を Github Respositry へアップロードする。生成物はブランチで管理、構成。 Version はタグによって管理する。

環境

maven の Version は以下の通り。

$ mvn --version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /usr/local/Cellar/maven/3.6.3_1/libexec
Java version: 11.0.6, vendor: Amazon.com Inc., runtime: /Users/com4dc/.sdkman/candidates/java/11.0.6-amzn
Default locale: ja_JP, platform encoding: UTF-8
OS name: "mac os x", version: "10.14.6", arch: "x86_64", family: "mac"

Github AccessToken の生成

password の代わりに Github の Personal AccessToken を生成する。 参照した URL では repo:* 権限のみで良いとあったが、実際には user:email の read 権限も必要だった。

f:id:com4dc:20200330224807j:plain

以下のIssueコメントで見つけた。

github.com

~/.m2/settings.xml

settings.xml には Github Repository の認証情報を記述する。

<settings>
  <servers>
    <server>
      <id>github</id>
      <username>USERNAME</username>
      <password>PERSONAL-ACCESSTOKEN</password>
    </server>
  </servers>
</settings>

これらの情報は当然 push しない(してしまったら、速攻でAccessTokenをRevokeする)

pom.xml

pom.xml に以下の情報を記述する。まずは project.properties

project.properties

Dependency で必要なライブラリの Version 情報、文字コード情報や Java のバージョン指定等のメタデータを入れる。

<project>
    <properties>
        <!-- 文字コード -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- コードと生成クラスのバージョン情報 -->
        <java.version>1.8</java.version>
        <!-- 認証情報を読み込む(settings.xml) -->
        <github.global.server>github</github.global.server>
    </properties>

<github.global.server>github</github.global.server>  には前出の settings.xml で作成した Id を指定することで、Github の認証情報を取り込んでいるっぽい。

project.distributionManagement

project.distributionManagement は Upload 元となる生成物を指定する。

<project>
    <!-- Local の target/mvn-repo フォルダをリポジトリとして宣言 -->
    <distributionManagement>
        <repository>
            <id>internal.repos</id>
            <name>Sample Maven Repository</name>
            <url>file://${project.build.directory}/mvn-repo</url>
        </repository>
    </distributionManagement>
</project>

project.build

 続いて project.build 以下を見ていく。基本的に利用する plugin の指定が記述されている。

maven-compiler-plugin

何も指定しないで実行したところ、5, 6 あたりがターゲットになってしまった。さすがに古すぎる。

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>

site-maven-plugin

Github Officialmaven-plugin

github.com

userName, password 等も設定できるので、CI等の動作を考えると環境変数に値を埋め込む方が都合が良いかもしれない。今回はすでに認証情報が読み込まれている状況なので特に何も設定しなくてもOK。

            <plugin>
                <groupId>com.github.github</groupId>
                <artifactId>site-maven-plugin</artifactId>
                <version>0.12</version>
                <configuration>
                    <!-- Git commit message -->
                    <message>Maven artifacts for ${project.version}</message>
                    <noJekyll>true</noJekyll>

                    <!-- distributionManagement の url と一致させる -->
                    <outputDirectory>${project.build.directory}/mvn-repo</outputDirectory>
                    <branch>refs/heads/mvn-repo</branch>
                    <includes><include>**/*</include></includes>

                    <!-- Github リポジトリ名 -->
                    <repositoryName>sample-project</repositoryName>
                    <repositoryOwner>com4dc</repositoryOwner>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>site</goal>
                        </goals>
                        <phase>deploy</phase>
                    </execution>
                </executions>
            </plugin>

基本的に素直に設定しているだけなのだが noJekyll だけよくわからなかった。OfficialページのREADMEを確認すると以下とある。

Whether to always create a .nojekyll file at the root of the site if one doesn't already exist. This setting should be enabled if your site contains any folders that begin with an underscore.

アンダースコアを含むディレクトリがあるかどうかで変わるらしい。 どうやらこれはGithub Pagesの機能Jekyllという処理エンジンを利用しているのだが、それを利用しない場合に配置するファイルらしい。ふーむ。なるほど

最終形

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>com.github.github</groupId>
                <artifactId>site-maven-plugin</artifactId>
                <version>0.12</version>
                <configuration>
                    <!-- Git commit message -->
                    <message>Maven artifacts for ${project.version}</message>
                    <noJekyll>true</noJekyll>

                    <!-- distributionManagement の url と一致させる -->
                    <outputDirectory>${project.build.directory}/mvn-repo</outputDirectory>
                    <branch>refs/heads/mvn-repo</branch>
                    <includes><include>**/*</include></includes>

                    <!-- Github リポジトリ名 -->
                    <repositoryName>sample-project</repositoryName>
                    <repositoryOwner>com4dc</repositoryOwner>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>site</goal>
                        </goals>
                        <phase>deploy</phase>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

deploy

Deployするとみゃ~っとコンパイルからUploadまで実行される。

$ mvn clean deploy

....
[INFO] --- site-maven-plugin:0.12:site (default) @ sample-project ---
[INFO] Creating 9 blobs
[INFO] Creating tree with 10 blob entries
[INFO] Creating commit with SHA-1: aaaaaaaa
[INFO] Updating reference refs/heads/mvn-repo from xxxxxxx to bc9947dbd112e7298bf82eb4214860b99999ede9
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  42.236 s
[INFO] Finished at: 2020-03-30T22:42:39+09:00
[INFO] ------------------------------------------------------------------------

Deploy後に出力されたハッシュ bc9947dbd112e7298bf82eb4214860b99999ede9 をタグに記録。

事前にPullしないと fatal: cannot update ref 'refs/tags/0.0.2': trying to write ref 'refs/tags/0.0.2' with nonexistent object 6d4XXXXX と出る可能性がある

$ git tag 0.0.1 bc9947dbd112e7298bf82eb4214860b99999ede9
$ git push origin 0.0.1

使い方

gradle プロジェクトでは build.gradle に以下を記述。

repositories {
    mavenCentral()

    // for sample-project
    maven { url "https://raw.github.com/com4dc/sample-project/mvn-repo"}
}

dependencies {
    compileOnly "com.github.com4dc:sample-project:0.0.1"
}

repositories には次のフォーマットで url を記述する。 https://raw.github.com/OWNER_NAME/REPOSITORY_NAME/BRANCH_NAME 今回は BRANCH_NAMEmvn_repo としているので、変更がある場合は別途変更すれば良さそう。

version 情報は前の手順で打った Tag と同じ。

参照