Cover Image for gradleからproxy越しにArtifactoryに成果物をアップロードする

gradleからproxy越しにArtifactoryに成果物をアップロードする

この記事は最終更新日から7年以上が経過しています。

proxyに縛られているエンジニアのために、gradleとArtifactoryの間にproxyが存在する場合に、ビルド成果物をアップロードする方法をまとめました。

要約

設定方法

環境

  • gredle:version 2.1
  • Artifactory:version 3.5.1

build.gradleの設定方法

artifactory_user=user
artifactory_password=password
artifactory_contextUrl=http://xxx.xxx.xxx.xxx/artifactory
artifactory_proxyHost=yyy.yyy.yyy.yyy
artifactory_proxyPort=8080
buildscript {
    repositories {
        mavenCentral()
        maven {
            url 'http://xxx.xxx.xxx.xxx/artifactory/plugins-release'
            credentials {
                username = "${artifactory_user}"
                password = "${artifactory_password}"
            }
        }
    }
    dependencies {
        //Check for the latest version here: http://plugins.gradle.org/plugin/com.jfrog.artifactory
        classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.0.1"
    }
}

allprojects {
    apply plugin: "com.jfrog.artifactory"
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'maven'
apply plugin: 'maven-publish'

/* エンコード指定 */
def defaultEncoding = 'UTF-8'
[compileJava, compileTestJava]*.options*.encoding = defaultEncoding

/* 成果物の情報 */
String module_group = 'my.module'
String module_archivesBaseName = 'test-module'
String module_version = '1.0.0'

/* 依存関係を記載 */
repositories {
    mavenCentral()
}
// artifactoryの設定
artifactory {
    contextUrl = "${artifactory_contextUrl}"   //The base Artifactory URL if not overridden by the publisher/resolver
    resolve {
        repository {
            repoKey = 'libs-release'
            username = "${artifactory_user}"
            password = "${artifactory_password}"
            maven = true
        }
    }
}

// 成果物をアップロード
configurations {
    deployerJars
}
dependencies {
    deployerJars "org.apache.maven.wagon:wagon-http:2.2"
}
uploadArchives {
    repositories {
        mavenDeployer {
            configuration = configurations.deployerJars
            repository(url: "${artifactory_contextUrl}/libs-release-local/") {
                authentication(userName: "${artifactory_user}", password: "${artifactory_password}")
                if(project.hasProperty("artifactory_proxyHost")){
                    proxy(host: "${artifactory_proxyHost}", port: "${artifactory_proxyPort}".toInteger(), type: "http")
                }
            }
            snapshotRepository(url: "${artifactory_contextUrl}/libs-snapshot-local/") {
                authentication(userName: "${artifactory_user}", password: "${artifactory_password}")
                if(project.hasProperty("artifactory_proxyHost")){
                    proxy(host: "${artifactory_proxyHost}", port: "${artifactory_proxyPort}".toInteger(), type: "http")
                }
            }
            pom.groupId = module_group
            pom.artifactId = module_archivesBaseName
            pom.version = module_version
        }
    }
}

上記のように設定するとgradle.propertiesartifactory_proxyHostartifactory_proxyPortの設定があるときのみ、gradle uploadArchives でプロキシ設定を利用してアップロードできる。 ※本当はsystemProp.https.proxyHostの設定を見るようにしたかった…

経緯

上記の設定方法になった経緯を書いています。気になる人は読んで頂ければと思います。 社内ネットワークの構成上、ビルドサーバー ↔ proxy ↔ Artifactory と通信しなければならずいろいろやっていたことが始まりでした。

Gradle Artifactory Pluginmaven-publish Pluginの組み合わせで検証

  • proxy設定のいらない環境 → :o: ダウンロード/アップロードともに問題ない
  • proxy設定が必要な環境
    1. gradle.propertiesにsystemProp.https.proxyHostsystemProp.https.proxyPortを設定してみる → :x: ダウンロードはできるが、アップロードができない…
    2. 環境変数にJAVA_OPTS="-DproxyHost=yyy.yyy.yyy.yyy -DproxyPort=8080"を設定してみる → :x: ダウンロードはできるが、アップロードができない…
    3. gradleの起動引数に-DproxyHost=yyy.yyy.yyy.yyy -DproxyPort=8080を渡してみる → :x: ダウンロードはできるが、アップロードができない…

試してみたところ、どうやらGradle Artifactory Pluginとmaven-publish Pluginの組み合わせだと普通に考えつくgradleのプロキシ設定は効かなそう… ならbuild.gradleの中でプロキシ設定すればいいんだ!

Gradle Artifactory Plugin を調査

Gradle Artifactory Pluginのページを詳しく読んでみた。 いろいろ設定できるけどproxy設定は無いみたい… → Artifactoryの設定に特化してるみたいだから、maven-publish Pluginのリポジトリ設定にproxy情報を追加できるかもしれない。

maven-publish Plugin を調査

maven-publish Pluginを詳しく調べてみた。 maven-publish Pluginクラスで使用されているRepositoryはMavenArtifactRepositoryクラス → これにもproxy設定は無い…

MavenArtifactRepositoryの拡張であるMavenDeployerにはプロキシ設定がありそうだ。これは何に使われてる? → Maven PluginuploadArchivesに使われてるのか。 → ん?ならいっその事uploadArchivesを使うようにすれば問題解決するんじゃね?

上記の結果から以下を試してみる。

  • 推奨の組み合わせは諦めてuploadArchivesでアップロードする → :o:proxyが間にあっても問題なくアップロードできる!

検証結果

  • Gradle Artifactory Pluginmaven-publish Pluginの組み合わせだとプロキシ設定する方法はなさそう
    • プロキシが存在することを考慮されてない?
    • どうしても使いたいならプラグインが拡張されるのを待つか、自分で改良するか
    • そもそもプロキシが必要ないサーバーをクラウド上に建てるべきなのか
  • 推奨の組み合わせは諦めてuploadArchivesでアップロードする
  • ビルド情報はArtifactoryに連携されなくなるけど、本筋の目的では無いのでOK
  • プロキシ情報はgradle.propertiesに書いて環境ごとに変更できるようにする。
  • ~~プロキシなんかクソくらえ~~