发布通用JAR到Maven Central Repository

Posted by Simon Dong on 2019-07-25

0x01 准备工作

  • 域名一个,主要是为了申请group id,无域名可能可以,不过没试过。

官方参考文档

How to Publish Your Artifacts to Maven Central

0x02 帐号注册

  1. Sonatype Jira 上注册一个Jira帐号。

  2. 提交一个Issue,主要说明这个项目的用途,以及项目地址和Git地址。参考

    1564063099010

  3. 在你的域名解析服务器中加入一个TXT记录,内容指向这个Issue地址。

    1564067665210

  4. 大约半个小时左右,这个Issue就会有人处理

0x03 签名证书

  1. 安装GNU PGP,用以生成签名证书,由于我使用WSL,自带了PGP软件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    $ gpg --version
    gpg (GnuPG) 2.2.4
    libgcrypt 1.8.1
    Copyright (C) 2017 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.

    Home: /home/simon/.gnupg
    Supported algorithms:
    Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
    Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
    CAMELLIA128, CAMELLIA192, CAMELLIA256
    Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
    Compression: Uncompressed, ZIP, ZLIB, BZIP2
  2. 生成签名证书,此步骤要求输入一个gpg passphrase,请记住这一密码

    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
    $ gpg --full-gen-key
    gpg (GnuPG) 2.2.4; Copyright (C) 2017 Free Software Foundation, Inc.
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.

    Please select what kind of key you want:
    (1) RSA and RSA (default)
    (2) DSA and Elgamal
    (3) DSA (sign only)
    (4) RSA (sign only)
    Your selection? 1
    RSA keys may be between 1024 and 4096 bits long.
    What keysize do you want? (3072) 2048
    Requested keysize is 2048 bits
    Please specify how long the key should be valid.
    0 = key does not expire
    <n> = key expires in n days
    <n>w = key expires in n weeks
    <n>m = key expires in n months
    <n>y = key expires in n years
    Key is valid for? (0) 5y
    Key expires at Tue 23 Jul 2024 10:32:16 PM CST
    Is this correct? (y/N) y

    GnuPG needs to construct a user ID to identify your key.

    Real name: Simon Dong
    Email address: snovian@outlook.com
    Comment:
    You selected this USER-ID:
    "Simon Dong <snovian@outlook.com>"

    Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
    We need to generate a lot of random bytes. It is a good idea to perform
    some other action (type on the keyboard, move the mouse, utilize the
    disks) during the prime generation; this gives the random number
    generator a better chance to gain enough entropy.
    We need to generate a lot of random bytes. It is a good idea to perform
    some other action (type on the keyboard, move the mouse, utilize the
    disks) during the prime generation; this gives the random number
    generator a better chance to gain enough entropy.
    gpg: key 7D41A81484E43B5E marked as ultimately trusted
    gpg: revocation certificate stored as '/home/simon/.gnupg/openpgp-revocs.d/0F62AC3CD3EC262C73CB9CC27D41A81484E43B5E.rev'
    public and secret key created and signed.

    pub rsa2048 2019-07-25 [SC] [expires: 2024-07-23]
    0F62AC3CD3EC262C73CB9CC27D41A81484E43B5E
    uid Simon Dong <snovian@outlook.com>
    sub rsa2048 2019-07-25 [E] [expires: 2024-07-23]
  1. 发布PGP Key到公网服务器

    1
    2
    $ gpg --keyserver pool.sks-keyservers.net --send-keys 0F62AC3CD3EC262C73CB9CC27D41A81484E43B5E
    gpg: sending key 7D41A81484E43B5E to hkp://pool.sks-keyservers.net

    可用key server列表有:

    • pool.sks-keyservers.net
    • gnupg.net:11371
    • keys.pgp.net
    • surfnet.nl
    • mit.edu

0x04 本地Maven Settings.xml修改

<Servers>节点加入ossrh服务器信息

1
2
3
4
5
<server>
<id>ossrh</id>
<username>[Your Sonatype Jira Account]</username>
<password>[Your PASSWORD]</password>
</server>

<profiles>节点加入一个profile

1
2
3
4
5
6
7
8
9
<profile>
<id>ossrh</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<gpg.passphrase>[生成签名证书时输入的passphrase]</gpg.passphrase>
</properties>
</profile>

0x05 准备项目POM文件

  1. 以下POM节点信息是Sonatype必须的节点
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
<modelVersion>4.0.0</modelVersion>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<name></name>
<url></url>
<description></description>

<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>

<contributors>
<contributor>
<name></name>
<email></email>
<organization></organization>
<organizationUrl></organizationUrl>
</contributor>
</contributors>

<scm>
<connection></connection>
<developerConnection>
</developerConnection>
<url></url>
<tag></tag>
</scm>

<issueManagement>
<url></url>
</issueManagement>

<developers>
<developer>
<email></email>
<name>g</name>
</developer>
</developers>

<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>

我的配置文件:

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
<modelVersion>4.0.0</modelVersion>
<groupId>cc.springworks</groupId>
<artifactId>springworks-boot-starter</artifactId>
<version>0.0.2-SNAPSHOT</version>

<name>springworks-boot-starter</name>
<url>https://dev.azure.com/springworks/springworks-boot-starter</url>
<description>springworks framework</description>

<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>

<contributors>
<contributor>
<name>Simon Dong</name>
<email>snovian@outlook.com</email>
<organization>springworks</organization>
<organizationUrl>http://springworks.cc</organizationUrl>
</contributor>
</contributors>

<scm>
<connection>scm:git:https://dev.azure.com/springworks/springworks-boot-starter/_git/springworks-boot-starter</connection>
<developerConnection>scm:git:https://dev.azure.com/springworks/springworks-boot-starter/_git/springworks-boot-starter
</developerConnection>
<url>https://dev.azure.com/springworks/springworks-boot-starter/_git/springworks-boot-starter</url>
<tag>HEAD</tag>
</scm>

<issueManagement>
<url>https://dev.azure.com/springworks/springworks-boot-starter/_workitems</url>
</issueManagement>

<developers>
<developer>
<email>snovian@outlook.com</email>
<name>Simon Dong</name>
</developer>
</developers>

<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>
  1. Maven 签名插件,将插件配置在一个profile中,以便在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
<profiles>
<!-- GPG Signature on release -->
<profile>
<id>release-sign-artifacts</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<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>
</plugins>
</build>
</profile>
</profiles>
  1. RELEASE发布插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<localCheckout>true</localCheckout>
<pushChanges>false</pushChanges>
<mavenExecutorId>forked-path</mavenExecutorId>
<arguments>-Dgpg.passphrase=${gpg.passphrase}</arguments>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-gitexe</artifactId>
<version>1.9.5</version>
</dependency>
</dependencies>
</plugin>
  1. SNAPSHOT发布插件
1
2
3
4
5
6
7
8
9
10
11
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.7</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
  1. 源代码打包
1
2
3
4
5
6
7
8
9
10
11
12
13
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>

0x06 发布

SNAPSHOT版本

1
mvn deploy

RELEASE版本

1
2
3
4
5
mvn clean
#准备版本信息,并创建下一版本的SNAPSHOT
mvn release:prepare
#正式发版本
mvn release:perform

GPG Key尽量发布到多个Key服务器上,我在发布过程中出现过GPG无法找到的情形。