AmazonS3上のMavenリポジトリを使った、Gradleでの依存関係管理

## 概要

タイトルの通り、AmazonS3にMavenリポジトリを作成し、Gradleで使う方法を記載しています。

社内のモジュールに依存するモジュールを開発する際に、サーバー上で依存関係を解決しビルドするために使ったりします。  

## 本記事のゴール

本記事のゴールは、下記の1,2です。

1. S3上にMavenリポジトリにライブラリをアップロードする
2. 上記ライブラリを別のGradleプロジェクトからダウンロードする

2については、具体的には以下のようなbuild.gradleの設定で「gradle build」コマンドを実行した際にライブラリをダウンロードできるようにします。

```groovy:build.gradle
dependencies {
    compile 'jp.co.goalist:library:1.0.0'
}
```

以下の内容については本記事では扱いません。いつかまた。

* Jenkinsなどビルドサーバー側での設定
* S3上のリポジトリへのアクセス管理

## 前提

* Gradleをインストールしている(3.3で検証済み)
* S3のバケットにファイルをアップロードできるAWS IAMユーザーを作成している
* 上記IAMユーザーのアクセスキーIDとシークレットアクセスキーを持っている

## Mavenリポジトリへのアップロード

### Gradleプロジェクト作成

以下のコマンドを実行します。

```
mkdir gradle-upload-s3repo
cd gradle-upload-s3repo/
gradle init --type=java-library
```

生成されたファイルはこんな感じです。

```
.
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
    ├── main
    │   └── java
    │       └── Library.java
    └── test
        └── java
            └── LibraryTest.java
```

この時点で build.gradle の内容は以下の通りです。（不要なコメントと依存ライブラリの設定は削除しています）

```groovy:build.gradle
apply plugin: 'java'

//依存ライブラリが未定義のため、
//現時点ではrepositoriesとdependenciesは不要ですが、
//後ほど使うので残しておきます。
repositories {
    jcenter()
}

dependencies {
}
```

確認のため、プロジェクトルートで「gradle build」と打ってあげると、build/libsに「gradle-upload-s3repo.jar 」が生成されます。ここまではjavaプラグインのデフォルト機能です。  
確認後、「gradle clean」してビルド結果を削除してあげましょう。

### groupId、artifactId、version を定義する

Mavenでは、groupIdとartifactIdとversionの組み合わせでライブラリを一意に定義します。

今回作成するライブラリは慣習にならい、

| キー       | 値            |
|------------|---------------|
| groupId    | jp.co.goalist |
| artifactId | library       |
| version    | 1.0.0         |

にしましょう。

build.gradleに以下の設定を追加します。

```groovy:build.gradle
group = "jp.co.goalist"
version = "1.0.0" 
```

settings.gradleを以下のように変更します。


```groovy:settings.gradle
rootProject.name = 'library'
```

### S3上にリポジトリ用のバケットを作成する

手順は省略しますが、リポジトリとして使用するバケットを作成します。

今回は「s3://repository.hoge/maven/」を作成します。

### 開発環境からS3へのアクセス情報を設定する

~/.gradle/gradle.propertiesにリポジトリのURLとIAMユーザーのアクセスキーIDとシークレットアクセスキーを設定します。  
これをプロジェクト側が参照することで、プロジェクトに含めないですむのでセキュリティ的に安全になります。（普通のこと言ってます）
あと個々のプロジェクトでアクセスキーID等で設定しないですみます。

```gradle.properties
goalistRepoUrl=s3://repository.hoge/maven/
awsAccessKeyId = AKIAJWORQEXXXXXXXXXX
awsSecretAccessKey = waTa0aakgK2e5hXXXXXXXXXXXXXXXXXXXXXXXXXX
```

### mavenプラグインのuploadArchivesタスクを設定する

MavenリポジトリへのアップロードにはmavenプラグインのuploadArchivesを使います。  
先程設定したリポジトリのURL、IAMユーザーのアクセスキーID、シークレットアクセスキーを参照するように設定を追加します。 

```groovy:build.gradle
apply plugin: 'maven'
```

```groovy:build.gradle
uploadArchives {
    repositories {
        mavenDeployer {
            configuration = configurations.deployerJars
            repository(url: goalistRepoUrl) {
              authentication(userName: awsAccessKeyId, password: awsSecretAccessKey)
            }
        }
    }
}
```

S3へのアクセスには org.springframework.build:aws-maven を使いますので、dependenciesに設定を追加します。  
今回は最新版の5.0.0.RELEASEを使います。

http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.springframework.build%22%20AND%20a%3A%22aws-maven%22

```groovy:build.gradle
configurations {
    deployerJars
}

dependencies {
    deployerJars 'org.springframework.build:aws-maven:5.0.0.RELEASE'//追加
}
```

これで設定は完了。最終的には以下のようになります。

```groovy:build.gradle
apply plugin: 'java'
apply plugin: 'maven'

group = "jp.co.goalist"
version = "1.0.0" 

repositories {
    jcenter()
}

configurations {
    deployerJars
}

uploadArchives {
    repositories {
        mavenDeployer {
            configuration = configurations.deployerJars
            repository(url: goalistRepoUrl) {
              authentication(userName: awsAccessKeyId, password: awsSecretAccessKey)
            }
        }
    }
}

dependencies {
    deployerJars 'org.springframework.build:aws-maven:5.0.0.RELEASE'
}
```

```groovy:settings.gradle
rootProject.name = 'library'
```

### uploadArchivesタスクを実行

以下のコマンドを実行し、BUILD SUCCESSFULL と表示されたら成功です。

```
gradle uploadArchives
```

S3を確認すると

s3://repository.hoge/maven/以下にライブラリがアップロードされていると思います。

## Mavenリポジトリからダウンロード 

今回アップロードしたライブラリに依存するGradleプロジェクトを作成します。

```
mkdir gradle-upload-s3repo-child
cd gradle-upload-s3repo-child/
gradle init --type=java-library
```

build.gradleを変更し、S3のリポジトリを参照するための設定と、依存関係の設定をします。

```groovy:build.gradle
apply plugin: 'java'

repositories {
    jcenter()
    maven {
        url goalistRepoUrl
        credentials(AwsCredentials) {
            accessKey awsAccessKeyId
            secretKey awsSecretAccessKey
        }
    }
}

dependencies {
    compile 'jp.co.goalist:library:1.0.0'
}

```

以下のコマンドを実行し、BUILD SUCCESSFULなことを確認できたら完了です。

```
gradle build
```

## さいごに

実運用ではビルドサーバーからしかアップロードできないようにして、開発者は参照のみ出来るようにすればいい感じに運用できると思います。
モジュールを再利用していきましょう。