在本文中,我們将使用 Mavin Publish Plugin 配置一個 android 庫并将其釋出到 Azure Artifacts,然後在 android 應用程式中使用它
首先讓我們假設您已經建立了一個現有的 android 庫并配置了 gradle并假設您的庫子產品created 被稱為“common-utils”。您的項目結構應類似于以下結構:
基本概念和術語
為了能夠将庫釋出到 maven 存儲庫,我們需要使用 Mavin Publish Gradle 插件配置庫,但首先我們需要解釋一些概念和定義,這就是我們要做的(以下所有定義都被視為來自文檔,在其他時候我編輯了定義以便更容易了解)。
工件:由建構生成的檔案或目錄,例如 JAR、ZIP 分發或本機可執行檔案。
子產品:随着時間的推移而發展的軟體,例如 Google Guava。每個子產品都有一個名稱。子產品的每個版本都由子產品版本最佳地表示。
子產品中繼資料:子產品的釋出提供中繼資料。中繼資料是更詳細地描述子產品的資料,例如有關工件位置或所需傳遞依賴關系的資訊。Gradle 提供了自己的中繼資料格式,稱為 Gradle 子產品中繼資料(.module 檔案),但也支援 Maven 中繼資料(.pom)。
子產品版本:表示已釋出子產品的一組不同的更改。例如 18.0 表示子產品的版本,坐标為com.google:guava:18.0。
存儲庫:存儲庫托管一組子產品,每個子產品可以提供一個或多個由子產品版本訓示的版本(元件)。
Maven Repository:包含額外中繼資料的打包 JAR 檔案的目錄(中繼資料由 POM 檔案表示)并包含所有項目 jar、庫 jar、插件和任何其他項目特定的工件。這些打包的 JAR 檔案可以被 Maven、Gradle 和其他了解 Maven 存儲庫格式的工具使用,并在将它們添加為依賴項後在其他項目中使用。
Gradle 插件:它們添加新任務(例如 JavaCompile)、域對象(例如 SourceSet)、約定(例如 Java 源代碼位于 src/main/java)以及從其他插件擴充核心對象和對象。Gradle 的核心是故意為現實世界的自動化提供很少的東西,所有有用的特性,比如編譯 Java 代碼的能力,都是由插件添加的。
釋出:是将正在建構的事物提供給消費者的過程。它可以是其他軟體項目使用的庫,也可以是最終使用者的應用程式。在 Gradle 中,該過程如下所示:
- 定義要釋出的内容
- 定義将其釋出到的位置
- 做出版
這些步驟中的每一個都取決于您要将工件釋出到的存儲庫的類型。
Maven Publish Plugin:是一個 gradle 插件,它提供了将建構工件釋出到 Apache Maven 存儲庫的能力,并允許您配置要釋出的内容并以最少的努力執行釋出。釋出到 Maven 存儲庫的子產品可以被 Maven、Gradle 和其他了解 Maven 存儲庫格式的工具使用。
Gradle Maven Publication:發往 Maven 存儲庫的出版物,其中包括:
- 一個或多個工件——通常由項目建構。
- Gradle 子產品中繼資料檔案将描述已釋出元件的變體。
- Maven POM 檔案将識别主要工件及其依賴項。主要工件通常是項目的生産 JAR,次要工件可能由“-sources”和“-javadoc”JAR 組成。
現在我們已經了解了一些術語和定義,讓我們繼續了解如何使用 Mavin Publish Gradle 插件配置 android 庫。
使用 Maven 釋出插件配置 Android 庫
- 讓我們首先将 Maven Publish Plugin 添加到 android 庫中,方法是将此插件添加到“common-utils”子產品(這是我們現有庫的 gradle 子產品)中 build.gradle 檔案的 plugins 部分:
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'maven-publish'
}
- 将插件添加到插件部分後,您将看到 gradle 檔案已更改的選項,并建議同步 gradle 檔案。單擊“立即同步”并等待 gradle 同步完成。
- 我們需要定義兩件事:publications(釋出什麼)和repositories(在哪裡釋出)。Maven Gradle 插件提供了通過在依賴塊之後的“common-utils”子產品的 build.gradle 檔案中添加以下釋出塊(由 PublishingExtension 支援)來定義釋出的能力。
publishing {
}
- 我們需要定義釋出塊并定義一個maven釋出塊(我們将詳細解釋)。為此,請在釋出塊中添加以下代碼塊。
publishing {
publications {
release(MavenPublication) {
from components.release
groupId 'com.example'//<GROUP_ID>
artifactId 'commonutils-release'//<ARTIFACT_ID>
version '0.1.0'// Your package version
}
}
}
讓我們更詳細地解釋我們添加的代碼塊以及每一行的含義:
- release(MavenPublication) { }:建立一個名為“release”的 Maven 釋出塊,該塊可以釋出到由大括号之間的類型訓示的 Maven 存儲庫。
- from components.release:表示此釋出僅包含釋出 AAR 工件及其中繼資料,方法是應用項目的釋出元件來建構釋出建構變體(将在 gradle 生成的任務中使用)。
- groupId ‘com.example’:定義此釋出的包的組 ID(将在其他項目中使用該庫時使用)。
- artifactId ‘commonutils-release’:定義此釋出的包的工件ID(将在其他項目中使用該庫時使用)。
- version ‘0.1.0’:定義此釋出的包的版本(将在其他項目中使用該庫時使用)。
注意:Maven 将 groupId 和 artifactId 限制為有限的字元集 ([A-Za-z0-9_-.]+),Gradle 強制執行此限制。對于版本(以及工件擴充和分類器屬性),Gradle 将處理任何有效的 Unicode 字元。明确禁止的唯一 Unicode 值是 \、/ 和任何 ISO 控制字元。提供的值在釋出的早期就得到驗證。
- 我們需要定義存儲庫塊,這些存儲庫是 gradle 可以向它們釋出工件的存儲庫。為此,請在釋出塊中添加以下代碼塊。
repositories {
maven {
name = 'azure'
url 'https://pkgs.dev.azure.com/'
credentials {
username "user name"
~~password "password"~~ #由于不能這個不能發出來,前面和後面的~~是多餘的
}
}
}
讓我們更詳細地解釋我們添加的代碼塊以及每一行的含義:
- maven {}:訓示存儲庫的類型,在這種情況下,它是一個 Maven 存儲庫。
- name = ‘azure’: 确定 maven 存儲庫的名稱(将在 gradle 生成的任務中使用)。
- url ‘https://pkgs.dev.azure.com/’:确定我們要釋出到它的 maven 存儲庫的 url 位置。
- credentials {},username "user name"和password “password”: 配置連接配接到之前定義的存儲庫 url 所需的任何身份驗證詳細資訊(稍後将詳細讨論)。
筆記:
- Gradle 需要與存儲庫互動,這就是為什麼您必須提供存儲庫的類型、位置以及連接配接到存儲庫所需的身份驗證詳細資訊的原因。
- 您可以定義多個存儲庫,隻要它們在建構腳本的存儲庫塊中具有唯一名稱。您還可以聲明一個(并且隻有一個)沒有名稱的存儲庫。該存儲庫将采用“Maven”的隐式名稱。
- 如果我們嘗試單擊“立即同步”(在 build.gradle 檔案更改後出現),我們将收到錯誤消息A problem occurred evaluating project ‘:common-utils’. > Could not get unknown property ‘release’ for SoftwareComponentInternal set of type org.gradle.api.internal.component.DefaultSoftwareComponentContainer.。 這是由于 gradle 中的一些更改和棄用而發生的,這是Removal of deferred configuration behaviorgradle 官方文檔解釋如下:
在 Gradle 5.0 之前,釋出 {} 塊(預設情況下)被隐式處理,就好像它内部的所有邏輯都是在評估項目後執行的。這種行為引起了相當多的混亂,并在 Gradle 4.8 中被棄用,因為它是唯一具有這種行為的塊。您的釋出塊或插件中可能有一些依賴于延遲配置行為的邏輯,這種邏輯現在必須包裝在 afterEvaluate {} 塊中。
換句話說,這意味着the components are created only during the afterEvaluate phase and you must configure your publications using the afterEvaluate() lifecycle method(有關更多詳細資訊,請檢視有關項目生命周期的官方文檔)。是以,我們需要将釋出塊(其中包含釋出塊和存儲庫塊)包裝在 afterEvaluate {} 塊中,如下面的代碼所示:
afterEvaluate {
publishing {
publications {
release(MavenPublication) {
from components.release
// You can then customize attributes of the publication as shown below.
groupId 'com.example'//<GROUP_ID>
artifactId 'commonutils-release'//<ARTIFACT_ID>
version '0.1.0'// Your package version
}
}
repositories {
maven {
name = 'azure'
url 'https://pkgs.dev.azure.com/'
credentials {
username "user name"
password "password"
}
}
}
}
}
并且不要忘記在 android studio 提示時點選“立即同步”!
恭喜!,您終于在現有的 android 庫中完成了 maven 釋出插件的配置。接下來,我們将深入探讨如何配置和準備 Azure 以使用 Azure Artifacts 托管 maven 存儲庫。
配置和準備 Azure 工件以托管 Maven 存儲庫
Azure Artifacts 是 Azure DevOps 中的一項服務,由官方文檔定義:
Azure Artifacts 使開發人員能夠共享和使用來自不同源和公共系統資料庫的包。包可以在同一團隊、同一組織甚至公開共享。Azure Artifacts 支援多種包類型,例如 NuGet、npm、Python、Maven 和通用包。
我們對 Maven 支援感興趣,因為它是我們可以将現有 maven android 庫釋出到的存儲庫類型,為此我們需要按照以下步驟配置 Azure DevOps:
您需要在 Azure DevOps 上建立一個名為“CommonUtils”的天藍色項目(這是我們要釋出的庫的名稱)。如果您不知道如何在 Azure DevOps 上建立項目,請參閱本指南并按照上述步驟進行操作。按照步驟建立新項目後,您應該在選擇建立的項目時看到以下内容。
單擊左側菜單中的 Artifacts,您将進入 Artifacts 的登入頁面,該頁面将包含您在項目中擁有的所有 Feed。預設情況下,標明的提要稱為“CommonUtilsDemo”(這是為該項目所屬的組織建立的預設提要,組織名稱為“CommonUtilsDemo”,它是為本文目的而建立的)。
什麼是 Azure 工件源?
Artifacts Feeds 是一種組織結構,允許您存儲、管理和分組您的包并控制與誰共享它。提要不依賴于包類型。您可以将以下所有包類型存儲在一個提要中:npm、NuGet、Maven、Python 和通用包(有關工件提要的更多詳細資訊,請檢視本指南)。
您可以使用預設提要釋出您的庫,也可以建立一個新提要。對于我們來說,我們将使用名為“CommonUtilsDemo”的預設提要。
從“建立提要”按鈕旁邊的菜單中選擇目标提要後,您将看到一條消息,鼓勵您連接配接到提要,并在其下方标有“連接配接到提要”的按鈕。
單擊此按鈕時,您将獲得可供選擇的工件類型清單。在 Maven 部分下,您将找到 Gradle 和 Maven,單擊 Gradle。
當您單擊 Gradle 時,您将在頁面右側打開一個項目設定指南。從 maven{} 塊内的設定說明中,您将找到一個帶有值的 url 和一個名稱變量,儲存這些值,因為我們需要它們來配置我們添加的存儲庫塊中的 maven{} 塊。
您需要建立一個個人通路令牌(當我們想要在 azure 工件上釋出 android 庫或當 gradle 想要将其作為依賴項下載下傳時,我們将在身份驗證中使用它)。為此,您可以從上一步頁面右側打開的相同設定說明通路您的個人令牌,您将被重定向到個人通路令牌頁面以建立一個新令牌,或者您可以按照本指南建立一個新的個人通路令牌。
建立個人通路令牌後,請将其與我們在上一步中儲存的 url 和名稱值一起儲存,因為我們稍後将需要它們。
打開 Android Studio 并在項目的根目錄下建立一個名為“ azure-configs.properties ”的新檔案。建立此檔案後,将 [您的提要名稱]、[個人通路令牌] 和 [提要的 URL] 的值替換為您在前兩個步驟中儲存的值,然後在其中粘貼以下内容。
azureMavenAccessToken=[you personal access token]
userName=[name of the feed]
repositoryUrl=[url of the feed]
當您将此檔案中的值替換為您儲存的值時,您應該會得到與以下内容類似的結果:
azureMavenAccessToken=r6qezlulkov72amh2kzbhhkuzulgssbecqlw4k3enttdcnx5hlza
userName=CommonUtilsDemo
repositoryUrl=https://pkgs.dev.azure.com/CommonUtilsDemo/_packaging/CommonUtilsDemo/maven/v1
注意:不要嘗試使用個人通路令牌,因為它隻是為了本文的目的而建立的,并且出于安全原因在我完成文章後立即删除;)
建立檔案“ azure-configs.properties ”後,打開“common-utils”庫子產品的 build.gradle 檔案,并在 plugins 塊之後添加以下代碼(加載我們建立的檔案的值“ azure -configs.properties ”,以便能夠在釋出塊内的 gradle 腳本中使用它們以及我們接下來要做的事情)。
def keystorePropertiesFile = rootProject.file("azure-configs.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
注意:您不應檢查版本控制中的“ azure-configs.properties ”,因為這樣做會特别暴露個人通路令牌(如果它是開源項目)。我這樣做隻是為了向本文的讀者提供包含此檔案的完整示例項目。
打開“common-utils”庫子產品的 build.gradle 檔案并在 maven 塊内添加以下代碼(在 afterEvaluate 塊内的釋出塊内的 repositories 塊内)。
maven {
name = 'azure'
url keystoreProperties['repositoryUrl']
credentials {
username keystoreProperties['userName']
password keystoreProperties['azureMavenAccessToken']
}
}
通過添加這個代碼塊,我們使 gradle 建構腳本能夠從我們建立的檔案中讀取值,并将它們與釋出塊中的 maven publish gradle 插件一起使用。
當android studio提示時,不要忘記點選“立即同步”!
恭喜!您已經在 Azure DevOps 上配置了 Azure Artifacts,準備好托管一個 maven 存儲庫,并将配置添加到 maven 釋出 gradle 插件,以便能夠在 Azure Artifacts 上釋出您現有的 android 庫,我們将要做下一節。
将 Android 庫釋出到 Azure Artifacts
我知道你很高興看到所有這些如何與釋出 android 庫相關聯,但在我們這樣做之前,我們需要了解一些我們之前跳過的概念。
Maven Publish Plugin 在項目中使用了一個名為 publishing 的擴充,類型為 PublishingExtension,我們之前在添加帶有釋出和存儲庫塊的釋出塊時使用了該擴充。Maven Publish Plugin 提供了一些 gradle 任務來處理釋出并提供我們将要使用的功能。是以,讓我們探索一下這些任務以及每個任務的用途,因為它們由官方文檔定義如下:
generatePomFileForPubNamePublication — GenerateMavenPom 為名為 PubName 的釋出建立 POM 檔案,填充已知的中繼資料,例如項目名稱、項目版本和依賴項。POM 檔案的預設位置是 build/publications/$pubName/pom-default.xml。
publishPubNamePublicationToRepoNameRepository — PublishToMavenRepository 将 PubName 釋出釋出到名為 RepoName 的存儲庫。如果您有一個沒有明确名稱的存儲庫定義,則 RepoName 将為“Maven”。
釋出 取決于:所有 publishPubNamePublicationToRepoNameRepository 任務 将所有已定義的釋出釋出到所有已定義存儲庫的聚合任務。它不包括将釋出複制到本地 Maven 緩存。
要将這些任務映射到我們現有的 android 庫,我們希望有這些任務:
- generatePomFileForReleasePublication(因為 PubName = Release)
- publishReleasePublicationToAzureRepository(因為 PubName = Release 和 RepoName = Azure)
- 釋出
我們隻對 publishReleasePublicationToAzureRepository 感興趣,我們将使用它來示範如何釋出庫并按照以下步驟進行操作:
- 在 Android Studio 中,打開 gradle 工具視窗,其中包含“根項目”中的所有 gradle 任務、“app”子產品中的 gradle 任務以及“common-utils”子產品中的所有 gradle 任務。
- 單擊“common-utils”旁邊的箭頭->“任務”->“釋出”。您将找到我們之前提到的 Maven Publish Gradle 插件為我們為“common-utils”生成的任務。我們可以輕按兩下這些任務中的任何一個來觸發 gradle 來執行這個任務,或者點選名為“釋出”的任務來觸發所有的任務。
- 要釋出我們現有的 android 庫,我們将執行名為“publishReleasePublicationToAzureRepository”的任務,它将我們的庫的釋出版本(AAR 釋出)部署到我們之前配置的 Azure 存儲庫。我們可以通過在打開的 gradle 工具視窗中簡單地輕按兩下它來執行此任務(或者通過在根項目目錄中打開終端并運作指令./gradlew publishReleasePublicationToAzureRepository),這将建構 android 庫和所有必需的檔案并将其釋出到 Azure Artifacts
- 導航到 Azure DevOps 上名為“CommonUtils”的項目并打開 Artifacts 服務,将找到已釋出的庫,如下所示: 恭喜!您已經在 Azure Artifacts 上釋出了現有的 android 庫,現在可以在其他 android 項目中使用它,我們将在下一節中介紹。
在另一個應用程式中使用已釋出的 Android 庫
要在應用子產品中使用已釋出的 android 庫,我們需要删除對“common-utils”的本地依賴,并将其替換為對 Azure Artifacts 上已釋出庫的依賴。為此,您可以按照以下步驟操作:
- 打開“settings.gradle”檔案并删除dependencyResolutionManagement {} 塊(如果有)。我們這樣做是為了能夠在我們将在下一步中執行的應用程式子產品中定義存儲庫塊。
- 删除 dependencyResolutionManagement {} 塊後,您的 settings.gradle 檔案應該隻有以下代碼:
rootProject.name = "CommonUtils"
include ':app'
include ':common-utils'
- 打開 ‘app’ 子產品的 build.gradle 檔案,在 plugins {} 塊之後添加以下代碼(它加載我們建立的檔案“ azure-configs.properties ”的值,以便能夠在 gradle 中使用它們稍後編寫腳本):
def keystorePropertiesFile = rootProject.file("azure-configs.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
- 打開 ‘app’ 子產品的 build.gradle 檔案,在 dependencies{} 塊implementation project(path: ‘:common-utils’)中将implementation ‘com.example:commonutils-release:0.1.0’. 添加此行後,我們将應用程式子產品的依賴項從對“common-utils”庫的本地依賴項更改為依賴于 Azure Artifacts 上的遠端釋出庫。
- 打開 ‘app’ 子產品的 build.gradle 檔案,在 dependencies{} 塊之後添加 repository 塊(這将有助于 gradle 在安裝 app 子產品的所有依賴項時找到已釋出的庫),方法是添加以下代碼:
repositories {
maven {
name = 'azure'
url keystoreProperties['repositoryUrl']
credentials {
username keystoreProperties['userName']
password keystoreProperties['azureMavenAccessToken']
}
}
}
- 您将看到 gradle 檔案已更改的選項以及同步 gradle 檔案的建議。單擊“立即同步”并等待 gradle 同步完成(當 gradle 同步時,gradle 會周遊依賴項并下載下傳它們,包括已釋出的 android 庫)。
- 打開子產品“common-utils”(這是子產品中唯一的檔案)中的 Utils.kt 檔案,您隻會看到一個定義為“concatenateTwoStrings()”的函數。然後在第 21 行打開 app 子產品中的 MainActivity.kt,您會發現我們正在使用已釋出庫中的實用程式函數,沒有錯誤(這意味着您實際上添加了從 azure Artifacts 存儲庫到您的項目的庫)。
- 為確定一切正常,您可以建構并運作該應用程式,您将獲得以下資訊:
這意味着我們将 Azure Artifacts 中已釋出的 utils android 庫添加到了應用程式子產品中,并在另一個應用程式中成功使用了它!
最後
在本文中,我們介紹了如何配置現有的 android 庫以使用Mavin Publish Gradle 插件将 android 庫釋出到Azure Artifacts,然後在另一個 android 應用程式中使用已釋出的庫。