使用Gradle釋出工件到Maven倉庫

精裝機械師發表於2018-12-21

Gradle釋出工件(Publishing Artifacts)

此文章基於Gradle 4.6編寫。

1. Maven Plugin(舊版)

使用Maven Plugin釋出Artifcat是舊的外掛,新版Gradle有新的外掛Maven Publish Plugin釋出Artifact

官方文件

Maven Plugin是新增支援釋出artifact到Maven倉庫的外掛。

1.1 使用

需要使用Maven plugin外掛,首先需要在專案的構建指令碼build.gradle上新增外掛引用宣告:

apply plugin: 'maven'

1.2 任務

Maven Plugin定義了以下任務

任務名稱 依賴於 型別 描述
install 構建關聯歸檔的所有任務。 Upload 將關聯的工件安裝到本地Maven快取,包括Maven後設資料生成。預設情況下,安裝任務與archives配置相關聯。預設情況下,此配置僅將預設jar作為元素。要了解有關安裝到本地儲存庫的更多資訊,請參閱:“安裝到本地儲存庫”一節

1.3 依賴管理

Maven Plugin沒有定義任何依賴配置。

1.4 與Maven倉庫互動

1.4.1 介紹

使用Gradle,您可以部署到遠端Maven儲存庫或安裝到本地Maven儲存庫。這包括所有Maven後設資料操作,也適用於Maven快照。事實上,Gradle的部署與Maven是100%相容,因為使用了本機Maven Ant任務。

如果沒有POM檔案,Gradle可以根據它具有的依賴性資訊為您生成一個POM檔案。

1.4.2 部署到Maven儲存倉庫

如果專案只生成預設的jar檔案,要將此jar檔案部署到遠端Maven儲存庫,在build.gradle新增以下程式碼:

apply plugin: 'maven' // 啟用Maven Plugin

uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: "file://localhost/tmp/myRepo/") // url的值為儲存倉庫地址
        }
    }
}

執行uplaodArchives任務,Gradle會生成一個POM檔案,並將jar檔案上傳發布到儲存倉庫中。

如果需要支援除file以外的協議,還有更多工作要做。在這種情況下,Maven程式碼需要額外的庫。具體需要哪些庫取決於所使用的協議。

  • Maven釋出協議依賴庫
協議 依賴庫
http org.apache.maven.wagon:wagon-http:2.2
ssh org.apache.maven.wagon:wagon-ssh:2.2
ssh-external org.apache.maven.wagon:wagon-ssh-external:2.2
ftp org.apache.maven.wagon:wagon-ftp:2.2
webdav org.apache.maven.wagon:wagon-webdav:1.0-beta-2
file -

加入需要使用ssh協議,需要在build.gradle這麼做:

// 宣告一個configuration
configurations {
    deployerJars
}

repositories {
    mavenCentral()
}

dependencies {
	// deployJar是前面configuration宣告的
    deployerJars "org.apache.maven.wagon:wagon-ssh:2.2" // ssh依賴庫
}

uploadArchives {
    repositories.mavenDeployer {
        configuration = configurations.deployerJars
        repository(url: "scp://repos.mycompany.com/releases") {
            authentication(userName: "me", password: "myPassword") // 這裡是倉庫賬號認證設定,使用者名稱和密碼
        }
    }
}

Maven釋出有許多配置項,這些配置項是依賴Groovy構建器完成的。配置項的所有元素都是Java bean。配置簡單的屬性,可以直接對映到bean的元素。如果新增bean元素到他的父元素,可以使用閉包。(在上面的例子中,repositoryauthentication就是新增到父元素的bean元素),下標列出了可用的bean】元素及只想相應類的javadoc的連結。

  • MavenDeployer可用的配置元素(Configuration elements of the MavenDeployer)
元素 Javadoc連結(只想Gradle官網)
root MavenDeployer
repository org.apache.maven.artifact.ant.RemoteRepository
authentication org.apache.maven.artifact.ant.Authentication
releases org.apache.maven.artifact.ant.RepositoryPolicy
snapshots org.apache.maven.artifact.ant.RepositoryPolicy
proxy org.apache.maven.artifact.ant.Proxy
snapshotRepository org.apache.maven.artifact.ant.RemoteRepository

在Maven中,可以定義儲存倉庫和可選的快照儲存倉庫。如果沒有定義快照儲存倉庫,會將版本和快照部署到這個repository元素配置的儲存倉庫,如果配置了快照,快照將部署到snapshortRepository元素配置的儲存倉庫中。

1.4.3 安裝到本地儲存庫(Installing to the local repository)

Maven Plugin會往專案中新增install任務。這個任務依賴於所有archives配置的歸檔任務。它將安裝這些歸檔檔案到本地倉庫儲存中(如果在Maven在string.xml中重新配置了預設倉庫的位置,這個任務將會根據改配置指向新的儲存位置)。

1.4.4 Maven POM檔案的生成(Maven POM generation)

當釋出構件到Maven倉庫時,Gradle會自動生成一個POM檔案。POM檔案包含groupIdartifactIdversionpackagingdependency元素(參考下表),dependency元素通過專案的依賴定義建立。

  • Maven POM檔案元素的預設值(Default Values for Maven POM generation)
Maven元素 預設值 備註
groupId project.group 組id
artifactId uploadTask.repositories.mavenDeployer.pom.artifactId (if set) or archiveTask.baseName. 構件id
version project.version 釋出版本
packaging archiveTask.extension 檔案打包字尾,如jar,aar

在這裡,uploadTaskarchiveTask任務是分別用來上傳和生成歸檔檔案的(比如:uploadArchivesjar)。archiveTask.basename預設是archiveTask.archivesBasename的值,而archiveTask.archivesBasename的預設值是project.name的值。

當你設定arhiveTask.baseName屬性值代替預設值是,還必須設定uploadtask.prepositories.mavenDeployer.pom.artifactId為相同值,否則,在同一個構建中的不同專案裡,可能會在生成POM檔案時引用錯誤artifaceId。

生成的POM檔案可以在<buildDir>/poms目錄下找到,他們可以通過MavenPom API進行自定義。例如,你可以將部署到Maven儲存倉庫的工件具有與Gradle編譯生成的工件有不同的版本或者名稱。要做到這些,可以根據以下方法:

  • build.gradle
uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: "file://localhost/tmp/myRepo/")
            pom.version = '1.0Maven' // 釋出到倉庫的構建版本
            pom.artifactId = 'myMavenName' // 釋出到倉庫的構建id
        }
    }
}

新增額外的內容到POP檔案,可用pom.project構建器,使用這個而構建起,所有在Maven POM引用中列出的元素都可以新增到裡面。

  • build.gradle
uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: "file://localhost/tmp/myRepo/")
            pom.project {
                licenses {
                    license {
                        name 'The Apache Software License, Version 2.0'
                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                        distribution 'repo'
                    }
                }
            }
        }
    }
}

注意:groupIdartifactIdversionpackaging應始終在pom物件中進行設定。

Maven外掛還支援同時釋出多個工件,這時需要為要釋出的每個工件宣告一個過濾器。此過濾器定義了一個布林表示式,它接受Gradle工件。每個過濾器都有一個與之關聯的POM,您可以配置它。要了解更多相關資訊,請檢視PomFilterContainer及其相關課程。

1.5 依賴關係對映(Dependency mapping)

通過Java和War外掛新增的Gradle配置與Maven作用域之間,Maven外掛配置了預設對映。大多數情況下,您可以跳過這部分而不需要關注它。對映的工作原理是:您可以將配置對映到一個且僅一個作用域,可以將不同的配置對映到一個或不同的作用域,您還可以為特定的配置到作用域對映分配優先順序。看看Conf2ScopeMappingContainer瞭解更多。

1.6 在AndroidStudio中釋出到遠端倉庫

在AndroidStudio中使用Maven外掛釋出工件到遠端倉庫儲存,在需要釋出的模組下面的build.gradle新增以下配置

apply plugin: maven

 uploadArchives {
        repositories {
            mavenDeployer {
                // 倉庫地址
                repository(url: repositoryUrl) {
                    // 使用者校驗 使用者名稱/密碼
                    authentication(userName: uname, password: pwd)
                }
                // 快照倉庫地址(可選)
                snapshotRepository(url: repositorySnapshotUrl) {
                    // 使用者校驗 使用者名稱/密碼
                    authentication(userName: uname, password: pwd)
                }

                pom.project {
                    name artifactName // artifact名稱
                    version versionName // artifact版本
                    artifactId _artifactId // artifact id
                    groupId _groupId // artifact所屬Group Id
                    packaging packagingType // 檔案格式,例如jar、aar
                    description _description // 描述
                }
            }
        }
    }

配置好後,開啟Gradle皮膚,雙擊模組名稱/Tasks/upload/uploadArchives任務或者在命令列輸入gradle 模組名稱:uploadArchives執行命令釋出到遠端倉庫,如果出現BUILD SUCCESS字樣說明發布成功。

2 Maven Publish Plugin(新版)

官方文件

2.1 使用

Maven Publish Plugin通過專案中以publishing命名,PublishingExtension型別的擴充套件來實現。該擴充套件提供了一個稱為publications的容器和一個稱為repositories的容器,Maven Publish Plugin適用於MavenPublication釋出和MavenArtifactRepository倉庫。

使用Maven Publish Plugin,需要在構建指令碼中新增程式碼啟用以下外掛

  • build.gradle
apply plugin: 'maven-publish'

2.2 出版物(Publications)

出版物物件描述建立的出版物的結構/配置,出版物通過任務釋出到倉庫儲存,出版物配置明確釋出內容。專案中的出版物都在 PublishingExtension.getPublications()容器中定義。

要使Maven Publish Plugin生效,必須將MavenPublication新增到出版物集合中,此出版物確定釋出的工件以及關聯的POM文中包含的詳細資訊。出版物可以通過新增元件、自定義工件以及修改生成的POM檔案來配置釋出。

2.3 釋出程式元件(Publishing a Software Component)

釋出Gradle專案到Maven倉庫最簡單的方式,就是通過SoftwareComponent來發布。該元件目前支援的出版物包括:

名稱 內容提供者 工件 依賴
java Java Plugin 生成jar檔案 依賴來自runtime配置
web War Plugin 生成war檔案 沒有依賴

說明:因為java外掛與com.android.librarycom.android.application不相容,所以在AndroidStudio中,使用maven-plugin外掛時不可同時使用java外掛。

2.4 在AndroidStudio中釋出到遠端倉庫

在AndroidStudio中使用Maven外掛釋出工件到遠端倉庫儲存,在需要釋出的模組下面的build.gradle新增以下配置。

apply plugin: 'maven-publish'

publishing {
    repositories {
        maven {
            credentials {
                username 'username' // 倉庫釋出使用者名稱
                password 'password' // 倉庫釋出使用者密碼
            }
            url 'trunk_url' // 倉庫地址
        }
    }
    publications {
        maven(MavenPublication) {
            groupId 'group_id' // groupId
            artifactId 'artifact_id' // artifactId
            version '1.0.0' // 釋出版本
            description 'This is a liberary to test v1.0.0' // 說明描述
        }
    }
}

配置好後,開啟Gradle皮膚,雙擊模組名稱/Tasks/publishing/publishMavenPublicationToMavenRepository任務或者在命令列輸入gradle 模組名稱:publishMavenPublicationToMavenRepository執行命令釋出到遠端倉庫,如果出現BUILD SUCCESS字樣說明發布成功。

2.5 錯誤及解決方案

2.5.1 釋出出現Read timeout網路異常

報錯資訊似以下的例子

Upload http://192.168.33.110:8081/repository/RastarGameSdkOversea/com/test/maven/plugin/rastar-sdk-line/1.0.0/rastar-sdk-line-1.0.0.pom
Could not transfer artifact com.test.maven.plugin:rastar-sdk-line:pom:1.0.0 from/to remote (http://192.168.33.110:8081/repository/RastarGameSdkOversea/): Could not write to resource 'com/test/maven/plugin/rastar-sdk-line/1.0.0/rastar-sdk-line-1.0.0.pom'
:rsdk_line:publishAarPublicationToMavenRepository FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':rsdk_line:publishAarPublicationToMavenRepository'.
> Failed to publish publication 'aar' to repository 'maven'
   > Could not write to resource 'http://192.168.33.110:8081/repository/RastarGameSdkOversea/com/test/maven/plugin/rastar-sdk-line/1.0.0/rastar-sdk-line-1.0.0.pom'.
      > Read timed out

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 44s

根據報錯資訊,是設定了代理,檢查AnroidStudio是否設定了代理,如果沒有,開啟Gradle使用者目錄(一般是在C:\Users\使用者名稱\.gradle),開啟gradle.properties檔案,看看是否設定了代理,如果設定了,將其去掉。

  • 在Gradle使用者目錄下gradle.properties設定代理的配置如下。
systemProp.http.proxyHost=127.0.0.1
systemProp.http.proxyPort=1080

2.5.2 ERROR: Cannot configure the 'publishing' extension after it has been accessed.

配置好後,重新整理Gradle的時候,如果出現ERROR: Cannot configure the 'publishing' extension after it has been accessed.錯誤,可以將以上的配置修改一下

apply plugin: 'maven-publish'

publishing {
    repositories {
        maven {
            credentials {
                username 'username' // 倉庫釋出使用者名稱
                password 'password' // 倉庫釋出使用者密碼
            }
            url 'trunk_url' // 倉庫地址
        }
    }
    publications {
        maven(MavenPublication) {
            groupId 'group_id' // groupId
            artifactId 'artifact_id' // artifactId
            version '1.0.0' // 釋出版本
            description 'This is a liberary to test v1.0.0' // 說明描述
        }
    }
}

將多級閉包改為少一級,將publishing跟閉包下面的使用.連結在一起,如下:

apply plugin: 'maven-publish'

publishing.repositories {
	maven {
		credentials {
			username 'username' // 倉庫釋出使用者名稱
			password 'password' // 倉庫釋出使用者密碼
		}
		url 'trunk_url' // 倉庫地址
	}
}
publishing.publications {
	maven(MavenPublication) {
		groupId 'group_id' // groupId
		artifactId 'artifact_id' // artifactId
		version '1.0.0' // 釋出版本
		description 'This is a liberary to test v1.0.0' // 說明描述
	}
}

相關文章