1. 程式人生 > >Gradle 釋出 JAR 包到 maven 中央倉庫(sonatype )

Gradle 釋出 JAR 包到 maven 中央倉庫(sonatype )

釋出包到 maven 倉庫

本文不與 https://zq99299.github.io/note-book/gradle/push-to-maven.html 同步更新

關於本文一些跳轉 404 問題,不知道 csdn 怎麼進行頁內跳轉;覺得閱讀不方便可檢視上面的地址

在 sonatype 做準備工作

效果:釋出到 https://oss.sonatype.org/#nexus-search;quick~mrcode 倉庫中

首先需要到這個頁面註冊賬戶:https://issues.sonatype.org/

登入之後,建立點選頂部導航欄的 create 建立專案
在這裡插入圖片描述

建立完成之後就會出一個 issues, 比如這個: https://issues.sonatype.org/browse/OSSRH-43803

在這裡插入圖片描述

流程:

  1. 建立賬戶
  2. 建立 issues 型別為新專案
  3. 他們工作人員會要求你證明你提供的 group id 的域名是屬於你自己的
  4. 如果不能提供證明,你將不能使用這個域名作為你的 group id
  5. 他也告知你可以使用 github 等域名作為你的 group id
  6. 證明 group id 是你的域名之後,就可以釋出包到倉庫了。

我選擇的是在 dns 中增加 txt;如下圖,很快就通過認證了
在這裡插入圖片描述

關於 gradle 的最終配置在最後部分。下面的幾個配置都是探索的配置過程記錄;

gradle 配置

可直接看後面的 最終打包配置

plugins {
    id 'java'
    id 'maven-publish'  // 新增外掛
}

group 'cn.mrcode.mycat'
version '0.1.0-SNAPSHOT'

sourceCompatibility = 1.8

compileJava {
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
    [compileJava]*.options*.encoding = 'UTF-8'
}
compileTestJava {
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
    [compileTestJava]*.options*.encoding = 'UTF-8'
}
repositories {
    mavenCentral()
}

dependencies {
    compile 'org.slf4j:slf4j-api:1.7.25'
    testCompileOnly 'junit:junit:4.12'
    testCompileOnly 'org.apache.commons:commons-lang3:3.8.1'
    testCompileOnly 'ch.qos.logback:logback-core:1.1.7'
    testCompileOnly 'ch.qos.logback:logback-classic:1.1.7'
    testCompileOnly 'org.apache.commons:commons-csv:1.6'
}

// 最主要的是這裡
publishing {
    publications {
        // 這一個推送專案名稱,mavenJava 相當於是一個 task name
        mavenJava(MavenPublication) {
            groupId project.group
            artifactId project.name
            version "${version}"
            from components.java
            artifact sourceJar

            // 新增 pom 相關資訊
            // https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenPublication.html
            pom {
                name = "fast-csv"
                description = "load csv file for Mycat"
                url = "https://github.com/zq99299/fast-csv"
                licenses {
                    license {
                        name = "The Apache License, Version 2.0"
                        url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
                    }
                }
                developers {
                    // 新增開發者描述,這個id不知道是什麼
                    developer {
                        id = "zq99299"
                        name = "mrcode"
                        email = "
[email protected]
" } } // 新增你的 git 倉庫 資訊 scm { connection = "scm:git:https://github.com/zq99299/fast-csv.git" developerConnection = "scm:git:https://github.com/zq99299/fast-csv.git" url = "https://github.com/zq99299/fast-csv" } } } } repositories { // 新增一個遠端倉庫地址 // releases 倉庫 maven { // 在對 task 中會生成對應的名稱 publishMavenJavaPublicationToxxx // 後面的 xxx 就是你這裡的名稱,表示你要把jar 上傳到這個倉庫中 name 'sonatypeRepository' // 為你這個倉庫起名 url 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' credentials { username = "${NEXUS_USERNAME}" // 之前在 sonatype 註冊的賬戶名 password = "${NEXUS_PASSWORD}" // 對應的密碼 } } // snapshots 倉庫 maven { name = 'sonatypeSnapshotRepository' url = 'https://oss.sonatype.org/content/repositories/snapshots/' credentials { username = "${NEXUS_USERNAME}" password = "${NEXUS_PASSWORD}" } } } } task sourceJar(type: Jar, dependsOn: classes) { description = "打包原始碼" classifier = 'sources' from sourceSets.main.allSource }

釋出

對於釋出來說,有兩個地址:

  • releases :
    • 表示正式版,穩定版本
    • 聽說需要 gpg 簽名才可以釋出成功
    • 不需要 -SNAPSHOT 字尾
  • snapshots :
    • 快照版, 不穩定的,開發的時候常用;
    • 必須攜帶 -SNAPSHOT 字尾

上面的配置對於 snapshots 已經可以釋出了,只要執行 task publishMavenJavaPublicationToxxx 對應的倉庫名稱即可;

GPG 生成

配置之前需要你現有 gpg 的簽名檔案,我這裡下載 windows 的軟體

gpg4win-3.1.5 :https://gpg4win.org/thanks-for-download.html

這個軟體支援中文。建立很簡單。直接新建金鑰對即可。

在這裡插入圖片描述

下一步後面的資訊都是選填的。傻瓜式下一步即可生成。

在這裡插入圖片描述

  • 匯出 : 可以匯出一個 .gpg 的檔案
  • 在伺服器上釋出。彈出詢問框,同意之後,會發自動上傳到公共伺服器上。
  • 細節:相當於一個詳細資訊。裡面包含了你這個祕鑰的指紋。後面配置需要用到這個指紋的後8位

注意:這個 gpg 你在上傳到伺服器之前需要生成 吊銷證書.rev 。以後還可以使用這個證書進行取消的。不然就沒法取消了

gpg 的詳細教程可以參考 阮一峰的教程:http://www.ruanyifeng.com/blog/2013/07/gpg.html

簽名配置

可直接看後面的 最終打包配置

首先在頂部 plugins 中增加簽名外掛 id ‘signing’

在配置一下依賴,讓外掛任務執行

// 1. 簽名配置
signing {
    sign configurations.archives
}

// 2.
// 這裡的 dependsOn 依賴了 signArchives 這個被外掛自動新增的任務
// 目的是在 source 前執行簽名
task sourceJar(type: Jar, dependsOn: [classes, signArchives]) {
    description = "配置source的路徑"
    classifier = 'sources'
    from sourceSets.main.allSource
}

// 3. 在之前的配中增加一項
publishing {
    publications {
        mavenJava(MavenPublication) {
            groupId project.group
            artifactId project.name
            version "${version}"
            from components.java
            artifact sourceJar
            // 增加這個簽名名稱所在的位置,
            // signArchives 輸出檔案中以你專案名作為的 key。這裡獲取這一個簽名檔案
            artifact signArchives.outputFiles.get('fast_csv')

這裡可以執行 gradle task publishToMavenLocal 這個任務來檢視打到本地 maven 倉庫的jar

可以發現如下的目錄結構

fast-csv-0.1.0-SNAPSHOT.asc   -> 簽名檔案
fast-csv-0.1.0-SNAPSHOT.jar
fast-csv-0.1.0-SNAPSHOT.pom
fast-csv-0.1.0-SNAPSHOT-sources.jar
maven-metadata-local.xml

這一步執行肯定會報錯的,因為你沒有指定你的簽名信息:

在 gradle 中增加以下配置

signing.keyId=上面說過 gpg 的祕鑰指紋後八位
signing.password=你建立 gpg 金鑰對的設定的密碼
signing.secretKeyRingFile=C:/Users/Administrator/Desktop/xxxx.gpg   // gpg 路徑

對於生成之後的這個目錄,jar 檔案。我們也可以使用之前生成金鑰對的工具進行校驗

在這裡插入圖片描述

嘗試 release 版本

這裡只是一個嘗試釋出的過程記錄;

執行 gradle publishMavenJavaPublicationToSonatypeRepository 任務,將會打包推送到遠端倉庫

不過只是被暫存了在 https://oss.sonatype.org/#stagingRepositories 中了,如下圖(需要登入後,在最底部才能看到)

在這裡插入圖片描述

在這裡插入圖片描述

選中關閉,會自動重新整理。但是應該需要手動重新整理獲取執行的結果

在這裡插入圖片描述

如下圖,這個就構建失敗了;

在這裡插入圖片描述

經過嘗試發現以下幾個是必須的:

  1. 提交的所有檔案必須簽名
  • fast-csv-0.1.0.jar
  • fast-csv-0.1.0.pom
  • fast-csv-0.1.0-sources.jar
  1. javadoc 也必須隨包一起釋出

其實第一個任務就告訴了,這些規則都是必須的。。
在這裡插入圖片描述

最終的打包配置

百度了好長時間,不知道怎麼配置,最後還是在官網找到了配置教程 : https://docs.gradle.org/current/userguide/publishing_overview.html

build.gradle

plugins {
    id 'java'
    id 'maven-publish'  // maven 釋出外掛
    id 'signing'  // 簽名外掛
}

//  組 和 版本配置
group 'cn.mrcode.mycat'
//version '0.1.0-SNAPSHOT'
version '0.1.0'

// 編譯版本和編碼配置
sourceCompatibility = 1.8

compileJava {
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
    [compileJava]*.options*.encoding = 'UTF-8'
}
compileTestJava {
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
    [compileTestJava]*.options*.encoding = 'UTF-8'
}
// 測試用例沒有寫好,還不能自動測試
// 跳過所有檔案的編譯測試;不是跳過compileTestJava task 而是在執行該task的時候,跳過所有的測試檔案
test {
    exclude '**/*.class'
}

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.slf4j:slf4j-api:1.7.25'
    testCompileOnly 'junit:junit:4.12'
    testCompileOnly 'org.apache.commons:commons-lang3:3.8.1'
    testCompileOnly 'ch.qos.logback:logback-core:1.1.7'
    testCompileOnly 'ch.qos.logback:logback-classic:1.1.7'
    testCompileOnly 'org.apache.commons:commons-csv:1.6'
}

// 後面的都是打包的配置
task sourcesJar(type: Jar) {
    classifier = 'sources'
    from sourceSets.main.allJava
}
// 生成 javadoc jar
task javadocJar(type: Jar) {
    classifier = 'javadoc'
    from javadoc.destinationDir
}
// javadoc 配置,這裡是自定義了 java doc 的一些配置
javadoc {
    description = "Generates project-level javadoc for use in -javadoc jar"

    options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
    options.author = true
    options.version = true
    options.header = project.name
    options.addStringOption('Xdoclint:none', '-quiet')

    // suppress warnings due to cross-module @see and @link references;
    // note that global 'api' task does display all warnings.
    logging.captureStandardError LogLevel.INFO
    logging.captureStandardOutput LogLevel.INFO // suppress "## warnings" message
    options.encoding = "UTF-8"  //編碼一定要配置否則直接出錯
    options.charSet = 'UTF-8'
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            groupId project.group
            artifactId project.name
            version "${version}"
            from components.java
            artifact sourcesJar
            artifact javadocJar

            // https://docs.gradle.org/current/dsl/org.gradle.api.publish.maven.MavenPublication.html
            pom {
                name = "fast-csv"
                description = "load csv file for Mycat"
                url = "https://github.com/zq99299/fast-csv"
                licenses {
                    license {
                        name = "The Apache License, Version 2.0"
                        url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
                    }
                }
                developers {
                    developer {
                        id = "zq99299"
                        name = "mrcode"
                        email = "[email protected]"
                    }
                }
                scm {
                    connection = "scm:git:https://github.com/zq99299/fast-csv.git"
                    developerConnection = "scm:git:https://github.com/zq99299/fast-csv.git"
                    url = "https://github.com/zq99299/fast-csv"
                }
            }
        }
    }
    repositories {
        maven {
            name 'sonatypeRepository'
            url 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
            credentials {
                username = "${NEXUS_USERNAME}"
                password = "${NEXUS_PASSWORD}"
            }
        }
        maven {
            name = 'sonatypeSnapshotRepository'
            url = 'https://oss.sonatype.org/content/repositories/snapshots/'
            credentials {
                username = "${NEXUS_USERNAME}"
                password = "${NEXUS_PASSWORD}"
            }
        }
    }
}

// 簽名配置,注意這裡的順序,今天第一次知道 gradle 中的 task 等配置也是有順序的
// 必須在 publishing 配置之後
signing {
    sign publishing.publications.mavenJava
}

gradle.properties

NEXUS_USERNAME= sonatype 註冊的使用者名稱
NEXUS_PASSWORD= sonatype 對應的密碼

signing.keyId= 8 位數的祕鑰指紋 id。後 8 位
signing.password= gpg 檔案的密碼
signing.secretKeyRingFile= C:/Users/xxx.gpg // 你的 gpg 檔案路徑

最後看圖

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

再去之前 issues 專案頁面 https://issues.sonatype.org/browse/OSSRH-43803 回覆下

優化 gradle 配置

現在的配置遇到一個問題。有敏感資訊,如何才能讓敏感資訊不上傳到 git 上呢?又能不影響專案的構建?

這些問題在 gradle 官網教程中找到了答案:

實踐步驟:

  1. 把使用者名稱和密碼還有簽名的配置 移動到 GRADLE_USER_HOME 目錄下的 gradle.properties 檔案中;

    專案目錄下的 gradle.properties 中相同的變數則為覆蓋 GRADLE_USER_HOME/gradle.properties 中的配置

  2. 專案目錄下的 gradle.properties 中只保留使用者名稱和密碼並且寫上錯誤的使用者名稱和密碼

    在執行 build 的時候,使用者名稱和密碼會被讀取,如果不存在的話會報錯(比如別人下載了你的原始碼除錯,將不能構建成功)

  3. 在打包構建的時候,手動去除掉專案中 gradle.properties 的使用者名稱和密碼配置。

    讓構建的時候獲取 GRADLE_USER_HOME/gradle.properties 中的配置,構建完成後,再還原回來(防止別人構建失敗)