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 中的配置,構建完成後,再還原回來(防止別人構建失敗)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章