Google Cloud Storage上にMavenインハウスリポジトリを構築する

## はじめに
[Google Cloud Storage](https://cloud.google.com/storage?hl=ja) （以下GCS）上にMavenインハウスリポジトリを構築して利用する方法のまとめです。
ドキュメントに書いてあることの二番煎じ的な感じもしますが、インハウスリポジトリの作り方や、作った後のjarファイルの転送方法から使用方法まで総合的にまとめてある記事が見当たらなかったので、備忘録として残しておきます。

ちなみに自分はGradleユーザなので、Gradleを使った場合の方法についてまとめています。

## 構築方法および使い方

### Gradleのドキュメント
公式のドキュメントは [こちら](https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:supported_transport_protocols) から。
ちなみに [リリースノート](https://docs.gradle.org/4.2/release-notes.html#support-for-google-cloud-storage-backed-repositories) によるとバージョン4.2で追加された機能のようです。
結構前からあったんですね、知らなかったです・・・。 :sweat_drops:

### インハウスリポジトリの構築
コマンド打ってバケットを作成するだけです。

```
$ BUCKET_NAME='your-inhouse-repository'
$ gsutil mb -c standard -l asia-northeast1 gs://${BUCKET_NAME}
```

自分一人で作業する分にはこれだけでOKです。
複数人で開発を行っている場合は、開発者へバケットへのアクセス権を付与してあげてください。

以下、バケット名は `your-inhouse-repository` で、その下にMaven用のパス `maven` を切って、Gradleからは `gcs://your-inhouse-repository/maven` を参照する前提で話を進めます。

### 認証方法
インハウスリポジトリなので外部には公開しません。
バケットに対する権限があるアカウントのみアクセスできるように認証を行いますが、ドキュメントにはこんな記載があります。

> When using a Google Cloud Storage backed repository default application credentials will be used with no further configuration required

「アプリケーションのデフォルトの認証情報」ってなんだ？って感じですが、どうやらそういう概念があるらしいです。
GCPでは [ADC](https://cloud.google.com/docs/authentication/production?hl=ja) と呼ばれています。

ローカルで作業する際は `gcloud init` して `gcloud auth application-default login` を行えばOKです。
それでADCとやらが適切な場所に配置され、あとはGradleが勝手にそれを使用して認証してくれます。

```
$ gcloud init
$ gcloud auth application-default login
```

### jarファイルのアップロード
ライブラリ側のサンプルコードです。
[Maven Publishプラグイン](https://docs.gradle.org/current/userguide/publishing_maven.html) を使用してjarファイルをアップロードできます。

```gradle:build.gradle
plugins {
    id 'java-library'
    id 'maven-publish'
}

group = 'your.libs'
version = '1.0.0'

publishing {
    publications {
        maven(MavenPublication) {
            from components.java
        }
    }
    repositories {
        // アップロード先としてインハウスリポジトリを指定する。
        maven {
            url 'gcs://your-inhouse-repository/maven'
        }
    }
}
```

```gradle:settings.gradle
rootProject.name = 'example-library'
```

```
$ gradle publish
```

### jarファイルの使用
ライブラリを使う側のサンプルコードです。
`repositories` に参照先のインハウスリポジトリを追加し、 `dependencies` に依存関係を定義するだけです。

```gradle:build.gradle
repositories {
    // 参照先としてインハウスリポジトリを追加する。
    maven {
        url 'gcs://your-inhouse-repository/maven'
    }
}

dependencies {
    // ライブラリを依存関係として追加する。
    implementation 'your.libs:example-library:1.0.0'
}
```

### 認証情報が切り替わらない際のTips
自分はGCPのアカウントを個人用と業務用で複数所持しているのですが、 `gcloud init` 、 `gcloud auth application-default login` をして認証情報を切り替えても、Gradleが切り替える前の情報を参照するという問題に遭遇・・・。
原因が分からず1日くらい無駄にしました。 :sweat_drops:

**分かってしまえば単純ですが、原因はGradleのデーモンが起動していてそれが古い認証情報を握ったままでした。**

なのでデーモンを一度停止すれば、その後は切り替えた後の認証情報を使ってくれます。

```
$ gradle --stop
```

もしくはデーモンを使用しないように明示的に指示すれば、現在の認証情報を参照してくれます。

```
$ gradle <some_task> --no-daemon
```

## 余談
2020年7月25日現在、ビルドアーティファクトの管理に特化した [Artifact Registry](https://cloud.google.com/artifact-registry?hl=ja) というサービスがβ版で公開されています。
[Mavenリポジトリ](https://cloud.google.com/artifact-registry/docs/java/quickstart?hl=ja) としても使えるようですが、こちらはまだα版のようなのでこれからが楽しみといったところですね。