V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bryan31
V2EX  ›  Java

记录自己发布开源项目到中央仓库的过程

  •  
  •   bryan31 · 2020-09-02 14:42:49 +08:00 · 552 次点击
    这是一个创建于 1551 天前的主题,其中的信息可能已经有所发展或是发生改变。

    1

    以前在 github 发开源项目,都因为懒,从来不构建到中央仓库。最近因为其他人要用,联系我。希望可以发到中央仓库。我想,不就是 mvn deploy 嘛,开搞。一圈弄下来,发现真没那么简单。当中遇到了无数的坑,让我每一次都心里默默念到,发个项目,为何如此痛苦。

    现将痛苦的过程详细记录下来。希望可以帮助到其他小伙伴少踩点坑。

    首先,你需要到sonatype这个站点上去注册一个账号。这个页面长这个样子:

    1

    我当时以为我进错地方了,这不是 jira 吗。好吧。看 url 还是提 issue 的地方,这和发布项目有毛的关系...

    好吧,点新建,项目选Community Support - Open Source,问题类型选New Project

    2

    填就是了。注意的是 Group Id 这里要填你自己的拥有的域名,比如 com.xxxx,没有的话,自己去注册域名去。填好之后就是等待审核。我搜了下,网上小伙伴说要等待 3,5 天。

    3 个小时后,我上去再去看,管理员给我回复了:

    3

    大致意思就是要你证明这个域名是属于你自己的。有 2 种方法,加一个 txt 类型的解析到你的域名里是最快的方法。

    我的域名申请在腾讯云。登陆进去。找到域名解析设置。加进去 txt 类型的解析。主机记录填那个 jira ticket 名字,记录值是你这个 ticket 的链接 url 。

    4

    设置完了后,去回复管理员。然后继续等待。

    管理员大概很快就回复了我。并通过了验证。接下来,就要捣鼓项目了。



    2

    要上传中央仓库,你的项目必须要符合一些规范才行。

    首先 pom 文件是有要求的,在你的项目顶层 pom 文件里一定要有以下标签:

    • name
    • description
    • url
    • licenses
    • developers
    • issueManagement
    • scm

    照着一个个填,我参考了一个开源项目的 pom,例子如下:

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.yomahub</groupId>
    <artifactId>liteflow</artifactId>
    <packaging>pom</packaging>
    <version>2.2.0</version>
    <name>liteflow</name>
    <description>a lightweight and practical micro-process framework</description>
    <url>https://github.com/bryan31/liteflow</url>
    <licenses>
        <license>
            <name>MIT License</name>
            <url>https://opensource.org/licenses/MIT</url>
            <distribution>repo</distribution>
        </license>
    </licenses>
    <developers>
        <developer>
            <email>[email protected]</email>
            <name>bryan.zhang</name>
            <url>https://github.com/bryan31</url>
            <id>bryan31</id>
        </developer>
    </developers>
    <issueManagement>
        <system>Github Issue</system>
        <url>https://github.com/bryan31/liteflow/issues</url>
    </issueManagement>
    <scm>
        <connection>scm:[email protected]:bryan31/liteflow.git</connection>
        <developerConnection>scm:[email protected]:bryan31/liteflow.git</developerConnection>
        <url>[email protected]:bryan31/liteflow.git</url>
    </scm>
    

    补全了 pom 的信息后,还需要补全一些 maven 插件,主要有:

    • maven-source-plugin
    • maven-site-plugin
    • maven-javadoc-plugin
    • maven-gpg-plugin

    例子如下:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.18.1</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <attach>true</attach>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-site-plugin</artifactId>
                <version>3.7.1</version>
            </plugin>
            <!-- Javadoc -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>3.0.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <!-- Gpg Signature -->
            <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>
    

    当然还需要加上distributionManagement

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

    你的 sonatype 的用户名和密码当然不能写在项目 pom 里,你得在 maven 的setting.xml里添加 server

    <server>
        <id>sonatype</id>
        <username>your username</username>
        <password>your password</password>
    </server>
    


    3

    补全了 pom 的一些规定信息和插件后。可以试下是否可以正确无误的生成 javadoc,在项目根目录下运行

    mvn site
    

    接下去就是无尽的等待,等待从中央仓库下载各种插件。这里最好搭个梯子翻墙,速度会快点。我全程用梯子,也等了 40 分钟,这时候可以去干点别的事情。。40 分钟后,终于 build 成功了:

    6

    接下去就是签名了。想要上传到仓库,jar 包必须被正确签名。

    用 gpg 来进行签名,网上搜了下,windows 的用户可下载 gpg4win,我这里用的是 mac,不能用这个软件。只能自己安装个命令行 gpg 工具了

    brew install gpg
    

    安装成功后,执行命令生成秘钥对:

    gpg --gen-key
    

    根据提示,填写用户名和邮件地址。然后确认。

    我 mac 上用的是 iterm2,确认后一直卡着,提示正在生成字节。然后等了很久也没有反应。我一直以为这就是正常现象,已经生成秘钥对了。只不过命令行不友好,没有告诉我。。。导致了我后面签名一直签不成功。

    后来我换了一个 ssh 工具,electerm,才正确生成。最后是要让你输入 passphase 。以下是正确生成秘钥对的界面

    7

    接下去就是要利用maven-gpg-plugin对 jar 包进行签名了。在进行之前,需要在setting.xml文件的当前 profile 里加上

    <properties>
        <gpg.executable>gpg</gpg.executable>
        <gpg.passphrase>your passphrase</gpg.passphrase>
    </properties>
    

    然后运行 mvn install 。

    我这里一直签名不成功,报以下错:

    8

    网上搜索了下,原来是我本地的 gpg 工具版本太新了,和 maven 的插件版本不匹配。需要在~/.gnupg 这个目录下增加 2 个配置:

    gpg.conf

    use-agent
    pinentry-mode loopback
    

    gpg-agent.conf

    allow-loopback-pinentry
    

    折腾了半天,终于可以 mvn install 正确执行 gpg 的 jar 包签名了。接下去准备进行激动人心的 mvn deploy 了。

    由于之前已经解决了 jar 包签名的问题,deploy 过程也是相当的顺利。deploy 过程中,会把你项目的 jar 包,加签信息,javadoc,javasource 等包一并上传到 sonatype 服务器。

    deploy 好,你就可以在 sonatype 的 staging repo 里看到了,staging repo 相当于暂存的状态,还没有正式发布到 release 仓库,sonatype 需要校验你上传 jar 包的规范性,合法性。

    选中你提交的暂存信息,点 close,等一段时间,refresh 之后底下会有校验结果。全部通过后才能点 release 。底下是我第一次校验的结果:

    9

    可以看到,有 2 项没通过,第 1 项是我 pom 不规范,原因是我第一次 pom 提交的时候少了<name>标签。关键是第 2 项签名校验失败,从右边的详细信息里可以看到,sonatype 在校验我的 jar 包签名时找不到我的 public key 。

    gpg 生成的是 RSA 的 key,有公钥和私钥。我本地加签之后,应该把公钥给到 sonatype,否则 sonatype 无法验证我的 jar 包的加签信息是否有效。所以我之前流程应该缺少了这一步!

    看详细信息,sonatype 应该是到以下 3 个地方去拿 key,发现都没有,所以才报了错。

    http://pgp.mit.edu:11371
    http://keyserver.ubuntu.com:11371
    http://pool.sks-keyservers.net:11371
    

    所以我们只需要上传 key 到任意一个 key server 就可以了。

    gpg 上传公钥的命令是

    gpg --keyserver hkp://keyserver.ubuntu.com:11371 --send-keys yourkeyid
    

    这里我踩了 2 个坑,第一个是上传的协议是 hkp,不是 http,网上一搜才知道。sonatype 报错的地方都是 http 。

    第二个是 gpg 在发送公钥的时候并不是直接指定公钥发上去,而是需要你的 keyid,个人推测可能是根据这个 keyid 再在文件系统中找到公钥进行发送吧。它需要什么,我们只能给什么。问题是这个 keyId 是什么呢,从哪来呢

    在生成秘钥对的时候,我注意到给了一个 fingerprint,也能用 gpg --list-keys 这个命令进行查看:

    10

    难道这个就是 keyId ?我尝试着用这个作为 keyId,进行发送,也能成功。但是在 sonatype 上进行检测却过不了。

    这个 keyId 卡了我很久,最后还是依靠万能的谷歌查到了。原来所谓的 KeyId 就是 fingerprint 的后 16 个字符。我 Fxx...(省略 N 个赞美的词语)。

    拿到了正确的 KeyId,继续执行 gpg 的上传命令,上传好,然后运行查看 key 的命令:

    gpg --keyserver hkp://keyserver.ubuntu.com:11371 --recv-keys yourkeyid
    

    也能在 key server 上找到

    11



    4

    我们继续在 sonatype 的 staging repo 进行 close 操作校验,这个操作其实我已经做了 n 遍了,各种坑,所以见到以下这个画面的时候有点激动:

    12

    可以看到,所有的校验都通过了,没有报错了。Release 的按钮也已经点亮。通往中央仓库的大门已经敞开!

    坚定的点下 release 按钮。输入备注后,成功提交。

    在 sonatype 进行 Release 后 ,要真正在中央仓库看到,可能要等上个 5 到 6 小时。

    最后。终于,在中央仓库的地址我看到了提交的包,大功告成

    13

    原本以为提交中央仓库可能不是那么困难,实际操作一遍,发现需要注意的细节有很多。而项目本身也有很多需要规范的地方。整个过程花了一天时间,碰了无数的坑,我工位旁边的小伙伴之前操作过,但是时间久远,细节又很多。所以对很多坑印象比较模糊了。所以记录下来。

    个人开发的项目被其他人所使用,是一件很有成就感的事情。所以提交中央仓库是必然途径。虽然我希望整个过程能简单点,但是中央仓库就一个,只能按照它的规范来做。希望有人看到这篇记录,能让你少走点弯路~

    5

    觉得有用的话,请关注下我的公众号「元人部落」,作者坚持原创的内容技术分享,也有开源作品,欢迎关注

    开源仓库为: https://gitee.com/bryan31

    公众号一般周更,分享科技谈开发技术,陪你一起成长

    关注后回复“资料”领取 50G 的视频资料,包括一套企业级微服务的视频教学

    img

    1 条回复    2020-09-02 17:19:34 +08:00
    slyang5
        1
    slyang5  
       2020-09-02 17:19:34 +08:00
    我当时也搞了 2 天,各种心酸啊
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2706 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 09:03 · PVG 17:03 · LAX 01:03 · JFK 04:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.