发布Jar到Maven中央仓库--Maven版

摘要

一、将项目推送到远程仓库,如 Github或者Gitee

二、注册 Sonatype 账户 – 就是一个JIRA

进入 https://issues.sonatype.org/secure/Dashboard.jspa 注册一个账号,邮箱要真实。

三、登录 Sonatype 创建工单–每部署一个新项目就创建一个工单

1
2
3
4
Summary:工单摘要,随便给个名称
Group Id:填写项目的Group Id
Project URL:填写远程仓库的浏览器地址
SCM url:填写下载项目的git地址
  • 注意:Group Id:最好填写你拥有的域名,比如我的域名是hanqunfeng.com,这里就填写com.hanqunfeng,这样后面验证domain时会方便一些。我第一次就是不知道这个事情,所以随便填的hanqf.org

  • 创建好工单后会收到两封邮件:

    • 第一封,通知你创建工单成功。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      hanqunfeng created OSSRH-62247:
      ----------------------------------

      Summary: reactive-redis-cache-annotation
      Key: OSSRH-62247
      URL: https://issues.sonatype.org/browse/OSSRH-62247
      Project: Community Support - Open Source Project Repository Hosting
      Issue Type: New Project
      Reporter: hanqunfeng
      Assignee: Joel Orlina


      reactive-redis-cache-annotation-spring-boot-starter



      --
      This message was sent by Atlassian Jira
      (v8.5.7#805007)
    • 第二封邮件,要求你验证domain,两封邮件间隔大约5分钟。同时你在工单的注释中也能看到系统回复的同样的信息。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      [ https://issues.sonatype.org/browse/OSSRH-62247?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

      Central OSSRH updated OSSRH-62247:
      ----------------------------------
      Status: Waiting for Response (was: Open)

      Do you own the domain hanqf.org? If so, please verify ownership via one of the following methods:
      * Add a TXT record to your DNS referencing this JIRA ticket: OSSRH-62247 (Fastest)
      * Setup a redirect to your Github page (if it does not already exist)

      If you do not own this domain, please read:
      http://central.sonatype.org/pages/choosing-your-coordinates.html
      You may also choose a groupId that reflects your project hosting, in this case, something like io.github.hanqunfeng or com.github.hanqunfeng


      > reactive-redis-cache-annotation
      > -------------------------------
      >
      > Key: OSSRH-62247
      > URL: https://issues.sonatype.org/browse/OSSRH-62247
      > Project: Community Support - Open Source Project Repository Hosting
      > Issue Type: New Project
      > Reporter: hanqunfeng
      > Assignee: Joel Orlina
      > Priority: Major
      >
      > reactive-redis-cache-annotation-spring-boot-starter
  • 看邮件说明,如果是自己的域名,添加一条TXT record 是最快速的验证方式,刚好我有一个域名,于是修改了工单的Group Id,修改工单时需要填写注释,随便填就行。

  • 然后去设置了DNS,一条TXT记录,key是工单号,我这里就是OSSRH-62247,值是工单地址,这里就是https://issues.sonatype.org/browse/OSSRH-62247,创建好后,在工单中添加一条注释

1
I have change the group Id to com.hanqunfeng,and I own the domain hanqunfeng.com,and I have added a dns record TXT.

其它验证方式我并未尝试。

  • 过一会你就会收到回复邮件,通知你验证完成,可以发布了,并且给出了发布地址。

    • 注意这里是先发布到https://oss.sonatype.org,而不是maven中央仓库的地址。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      [ https://issues.sonatype.org/browse/OSSRH-62247?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

      Central OSSRH resolved OSSRH-62247.
      -----------------------------------
      Resolution: Fixed

      com.hanqunfeng has been prepared, now user(s) hanqf can:
      * Deploy snapshot artifacts into repository https://oss.sonatype.org/content/repositories/snapshots
      * Deploy release artifacts into the staging repository https://oss.sonatype.org/service/local/staging/deploy/maven2
      * Release staged artifacts into repository 'Releases'

      please comment on this ticket when you promoted your first release, thanks

      > reactive-redis-cache-annotation
      > -------------------------------
      >
      > Key: OSSRH-62247
      > URL: https://issues.sonatype.org/browse/OSSRH-62247
      > Project: Community Support - Open Source Project Repository Hosting
      > Issue Type: New Project
      > Reporter: hanqunfeng
      > Assignee: Joel Orlina
      > Priority: Major
      >
      > reactive-redis-cache-annotation-spring-boot-starter



      --
      This message was sent by Atlassian Jira
      (v8.5.7#805007)

四、发布

  • 1.准备签名

    • 可以使用工具创建密钥对
      需要下载一个签名工具,我是mac电脑,下载的是https://gpgtools.org
      安装后点击新建,按照提示创建一个密钥对即可,注意高级选项里有个过期时间,默认是3年。创建好后会主动提示你是否将公钥发布到key server,点击Upload Public key即可。也可以在创建后的证书列表页面邮件选择证书–>Send Public Key To Key Server

    导出证书时,勾选密码并设置密码就是私钥和公钥证书,不勾选密码就是公钥,看生成文件的名称就可以,公开就是公钥,私密就是私钥,格式都是asc,其实就是字符串,可以用记事本打开查看。

    如果windows系统,可以下载https://www.gpg4win.org/ ,使用方式差不多,最后点击“将公钥上传的目录服务”。

    公钥发布到key server后要稍微等一会,大约10分钟吧,因为key server有多个,同步需要一些时间。
    记住你创建密钥对时的密码,发布项目时要使用。

    • 也可以使用命令行创建密钥对,版本[gpg (GnuPG/MacGPG2) 2.2.24]

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      # 创建密钥对,按提示输入用户名称和邮箱地址
      gpg --generate-key

      # 列出密钥,hanqunfeng就是创建密钥对是的用户名,此处也可以使用邮箱
      # 结果中第二行一长串的后8位就是keyId,比如:30FF8D58,gradle构建时会用到
      gpg --list-keys hanqunfeng
      # 也可以直接通过id查询
      gpg --list-keys 30FF8D58

      # 上传公钥到server key,默认上传到hkps://keys.openpgp.org,但是提示上传失败
      # 看到网上的示例可以通过--keyserver指定上传的服务器地址,但是我这个版本[gpg (GnuPG/MacGPG2) 2.2.24]没有这个参数
      # 使用 https://gpgtools.org 上传公钥就会成功
      gpg --send-keys 30FF8D58

      # 查看指纹
      gpg --fingerprint 30FF8D58

      # 删除私钥,这里也可以使用用户名称或者邮箱,如果唯一的话
      gpg --delete-secret-keys 30FF8D58

      # 删除公钥
      gpg --delete-keys 30FF8D58
  • 2.settings.xml
    配置 mavensettings.xml 文件,设置一个 server,里面添加 Sonatype 的账号和密码。
    注意当前已经不再支持帐号密码的认证方式,需要配置为 User Token

登录https://oss.sonatype.org–>点击右上角的用户名称—>Profile–>下拉选择User Token–>Generate Token

1
2
3
4
5
6
7
8
9
10
11
<settings>
[...]
<servers>
[...]
<server>
<id>ossrh</id>
<username>Sonatype账号</username>
<password>Sonatype密码</password>
</server>
</servers>
</settings>
  • 3.pom.xml,重点是后面几个plugin
    这里重点说一下nexus-staging-maven-plugin这个插件,该插件会将我们发布到https://oss.sonatype.orgjar自动发布到maven中央仓库,如果没有这个插件,我们需要登录https://oss.sonatype.org,然后手工点击Staging Repositories ,找到你发布的包(GroupId开头的),然后点击close,再点击release。有说这种方式容易失败(我没有测试),推荐使用插件自动发布。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.hanqunfeng</groupId>
<artifactId>reactive-redis-cache-annotation-spring-boot-starter</artifactId>
<version>1.0.1</version>
<name>redis-cache-annotation-reactive</name>
<description>redis cache function annotation for webflux</description>
<url>https://blog.hanqunfeng.com</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>hanqf</id>
<name>hanqunfeng</name>
<email>qunfeng_han@126.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/hanqunfeng/reactive-redis-cache-annotation-spring-boot-starter.git</connection>
<developerConnection>scm:git:https://github.com:hanqunfeng/reactive-redis-cache-annotation-spring-boot-starter.git</developerConnection>
<url>https://github.com/hanqunfeng/reactive-redis-cache-annotation-spring-boot-starter</url>
</scm>

<properties>
<java.version>1.8</java.version>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.0</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>


<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-source</id>
<phase>verify</phase>
<goals>
<!--生成源代码的jar -->
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>attach-javadoc</id>
<phase>verify</phase>
<goals>
<!--生成javadoc的jar -->
<goal>jar</goal>
<!--生成javadoc的html -->
<goal>javadoc</goal>
</goals>
<configuration>
<!--不显示javadoc警告-->
<additionalOptions>-Xdoclint:none</additionalOptions>
<additionalJOption>-Xdoclint:none</additionalJOption>
</configuration>
</execution>
</executions>
</plugin>

<!-- gpg plugin,用于签名认证 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<!--staging puglin,用于自动执行发布阶段(免手动)-->
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.8</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
<!-- release plugin,用于发布到release仓库部署插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
</plugin>



</plugins>
</build>

<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>

</project>
  • 4.执行命令

1
2
3
mvn clean package # 完成打包和测试
mvn clean verify # 完成源码打包和javadoc打包,同时完成签名
mvn clean deploy # 完成本地部署和maven中央仓库部署

4.1 执行过程中会提示你输入创建密钥对时的密码,如果不想人工参与,也可以使用如下方式(参考:http://maven.apache.org/plugins/maven-gpg-plugin/usage.html)

  • a.在执行命令时指定密码:

    1
    mvn clean deploy -Dgpg.passphrase=thephrase
  • b.setting.xml中创建一个server

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <settings>
    [...]
    <servers>
    [...]
    <server>
    <id>gpg.passphrase</id>
    <passphrase>clear or encrypted text</passphrase>
    </server>
    </servers>
    </settings>
  • 5.执行成功后即说明发布到maven中央仓库成功了,过一会就会收到邮件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[ https://issues.sonatype.org/browse/OSSRH-62247?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Central OSSRH 更新了 OSSRH-62247:
------------------------------

Central sync is activated for com.hanqunfeng. After you successfully release, your component will be published to Central, typically within 10 minutes, though updates to search.maven.org can take up to two hours.

> reactive-redis-cache-annotation
> -------------------------------
>
> 关键字: OSSRH-62247
> URL: https://issues.sonatype.org/browse/OSSRH-62247
> 项目: Community Support - Open Source Project Repository Hosting
> 问题类型: New Project
> 报告人: hanqunfeng
> 经办人: Joel Orlina
> 优先级: 重要
>
> reactive-redis-cache-annotation-spring-boot-starter



--
这条信息是由Atlassian Jira发送的
(v8.5.7#805007)

这封邮件的大意是提示你,大约10分钟后你就可以将依赖添加到项目中进行下载了,不过要通过https://search.maven.org(现已重定向到https://central.sonatype.com)检索到需要等待两个小时,毕竟更新索引也是需要时间的。
另外,如果你确认发布是成功的,记得要回到工单添加个注释,如

1
I've released Releases successfully.Thank you!