自动部署到sonatype的oss maven存储库

时间:2023-01-20 20:39:13

I've got several github java projects. One of them I've manually deployed to sonatype's repository so that it gets published in maven central.

我有几个github java项目。其中之一是我手工部署到sonatype的存储库,以便在maven central中发布。

This has been a somewhat painful process in the sense that it seems to involve too many hoops to jump through and a lot of manual work and I'd like to automate that. So I actually stopped doing that because it was just too much work. There's plenty of documentation that suggests this is possible and quite a bit that suggest that it somehow involves doing something with the nexus-staging-maven-plugin. Unfortunately all of that documentation is (in typical maven style) skipping over the essential details that would allow me to figure out in a straightforward way the minimum amount of steps necessary that allow me to automatically publish release builds to the sonatype repository (i.e. without me manually approving things).

这是一个有点痛苦的过程因为它似乎涉及太多的麻烦和大量的手工工作,我想把它自动化。我就不做了,因为工作量太大了。有大量的文档表明这是可能的,也有相当多的文档表明它在某种程度上涉及到对下一个阶段-maven-plugin的一些操作。不幸的是,所有这些文档都(在典型的maven风格中)跳过了一些基本的细节,这些细节让我能够以一种简单的方式计算出允许我自动将发布版本发布到sonatype存储库(即不需要人工批准的东西)的最少步骤。

So, what is the blurb that needs to be present in my pom (assume a otherwise bog standard uncomplicated java project), including urls for the sonatype repository, all documentation I've found seems to insist localhost:8081 is it, and the required maven incantations to make it do a release (preferably via the mvn release plugin), have it sign the artifacts, and have it deploy the resulting artifacts to sonatype, approved and all ready to be synced to maven central, etc.

那么,什么是需要的广告出现在我的pom(假设其他沼泽标准简单的java项目),包括sonatype存储库url,所有文档我发现似乎坚持localhost:8081,和所需的maven咒语让它做一个版本(最好是通过mvn版本插件),签署工件,并让它部署生成的工件sonatype,批准和所有可以同步到maven*,等等。

So, I'm sort of looking for the maven replacement of a "gem push" in the ruby world, which gets the job done in a convenient one liner. It's a simple case of given a jar file approved by me, how do I get it to end up in maven central with the least amount of fuss.

因此,我正在寻找maven替代ruby世界中的“gem push”,它在方便的一行代码中完成工作。这是一个简单的例子,给定一个由我批准的jar文件,如何让它以最少的麻烦进入maven中心。

I'd very much appreciate some examples of pom files already setup to do this that I can copy and adapt.

我非常感谢一些pom文件的例子,这些文件已经准备好了,我可以复制和修改。

Edit:

Here's my working pom file:

这是我的工作pom文件:

<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.jillesvangurp</groupId>
    <artifactId>jsonj</artifactId>
    <version>1.34-SNAPSHOT</version>

    <name>JsonJ</name>
    <description>A framework for working with json in Java the "proper" way. No mappings or model classes, it's all just lovely json, but in Java.</description>
    <url>https://github.com/jillesvangurp/jsonj</url>

    <licenses>
        <license>
            <name>MIT license</name>
            <url>https://github.com/jillesvangurp/jsonj/blob/master/LICENSE</url>
            <distribution>repo</distribution>
        </license>
    </licenses>

    <scm>
        <url>git://git@github.com:jillesvangurp/jsonj.git</url>
        <connection>scm:git:git@github.com:jillesvangurp/jsonj.git</connection>
        <developerConnection>scm:git:git@github.com:jillesvangurp/jsonj.git</developerConnection>
    </scm>

    <repositories>
        <repository>
            <id>sonatype-nexus-snapshots</id>
            <name>Sonatype Nexus Snapshots</name>
            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <distributionManagement>
        <snapshotRepository>
            <id>sonatype-nexus-snapshots</id>
            <name>Sonatype Nexus Snapshots</name>
            <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
        </snapshotRepository>
        <repository>
            <id>sonatype-nexus-staging</id>
            <name>Nexus Release Repository</name>
            <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
        </repository>
    </distributionManagement>

    <developers>
        <developer>
            <id>jillesvangurp</id>
            <name>Jilles van Gurp</name>
            <url>http://www.jillesvangurp.com</url>
            <timezone>gmt+1</timezone>
            <roles>
                <role>Main Developer</role>
            </roles>
        </developer>
    </developers>

    <organization>
        <name>www.jillesvangurp.com</name>
        <url>http://jillesvangurp.com</url>
    </organization>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <verbose>true</verbose>
                    <fork>true</fork>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>2.8.1</version>
                <executions>
                    <execution>
                        <id>documentation</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.2</version>
                <executions>
                    <execution>
                        <id>gathersource</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.sonatype.plugins</groupId>
                <artifactId>nexus-staging-maven-plugin</artifactId>
                <version>1.6</version>
                <extensions>true</extensions>                
                <configuration>
                    <!-- The Base URL of Nexus instance where we want to stage -->
                    <nexusUrl>https://oss.sonatype.org/</nexusUrl>
                    <serverId>sonatype-nexus-staging</serverId>
                </configuration>
            </plugin>            
        </plugins>
        <extensions>
            <extension>
            <artifactId>wagon-webdav-jackrabbit</artifactId>
            <groupId>org.apache.maven.wagon</groupId>
            <version>2.2</version>
            </extension>
        </extensions>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-release-plugin</artifactId>
                    <version>2.1</version>
                    <configuration>
                        <mavenExecutorId>forked-path</mavenExecutorId>
                        <useReleaseProfile>false</useReleaseProfile>
                        <arguments>-Psonatype-oss-release</arguments>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>        
    </build>
    <profiles>
        <profile>
            <id>sonatype-oss-release</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-source-plugin</artifactId>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-javadoc-plugin</artifactId>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-gpg-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>sign-artifacts</id>
                                <phase>verify</phase>
                                <goals>
                                    <goal>sign</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>        
    </profiles>

    <dependencies>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.8.7</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-all</artifactId>
            <version>1.3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.googlecode.json-simple</groupId>
            <artifactId>json-simple</artifactId>
            <version>1.1.1</version>
            <exclusions>
                <exclusion>
                    <artifactId>junit</artifactId>
                    <groupId>junit</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>xom</groupId>
            <artifactId>xom</artifactId>
            <version>1.2.5</version>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>com.jillesvangurp</groupId>
            <artifactId>efficientstring</artifactId>
            <version>1.11</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.2.3</version>
        </dependency>
    </dependencies>
</project>

The comment (@aurelien-thieriot) below put me on the right track but was not enough by itself.

下面的评论(@aurelien-thieriot)让我走上了正确的道路,但还不够。

In the end I took the sonatype parent pom and flattened it into my pom file.

最后,我将sonatype父pom压缩到pom文件中。

This allows me to use the mvn release plugin normally. It uploads the artifacts to the sonatype staging repository. Then to release the artifacts, I actually needed the staging repository id. You can find this from the repositories view in https://oss.sonatype.org/index.html#stagingRepositories.

这允许我正常使用mvn发布插件。它将构件上载到sonatype暂存库。然后,为了发布工件,我实际上需要登台存储库id,您可以从https://oss.sonatype.org/index.html# stagingrepository视图中找到它。

In my case the command line became:

在我的例子中,命令行变成:

mvn nexus-staging:release -Ddescription="Release 1.33" -DstagingRepositoryId=comjillesvangurp-1002

Without the right id it doesn't figure it out and still fails: Sonatype Maven Staging Plugin Issue

如果没有正确的id,它不会发现它,并且仍然失败:Sonatype Maven暂存插件问题

So 95% automated but I still need to figure out the stagingRepositoryId every time.

95%都是自动的,但我还是需要每次都算出停滞库。

Edit:

mvn release:perform actually tells you the id of the staging repository. I guess you could write a script that extracts this id from the output and then passes it in to the next step. If somebody knows some mvn voodoo to make mvn release:perform do the staging release as well, it would be much appreciated.

mvn版本:执行实际上告诉您登台存储库的id。我猜您可以编写一个脚本,从输出中提取这个id,然后将其传递到下一步。如果有人知道一些mvn巫毒教来制作mvn发行版:也执行临时发行版,那将非常感谢。

2 个解决方案

#1


2  

For the convenience of Maven projects, Sonatype is providing a parent POM you can add to your project with all the basic configuration:

为了方便Maven项目,Sonatype提供了一个父POM,您可以将所有基本配置添加到项目中:

https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide#SonatypeOSSMavenRepositoryUsageGuide-Changesto%7B%7Bpom.xml%7D%7D

https://docs.sonatype.org/display/Repository/Sonatype + OSS +使用Maven +库+ +指南# SonatypeOSSMavenRepositoryUsageGuide-Changesto % 7 b % 7 bpom.xml % 7 d % 7 d

The important bits are:

重要的部分是:

  <parent>
    <groupId>org.sonatype.oss</groupId>
    <artifactId>oss-parent</artifactId>
    <version>7</version>
  </parent>

And the source code repository details:

以及源代码库的详细信息:

  <scm>
    <connection>scm:svn:http://foo.googlecode.com/svn/trunk/</connection>
    <developerConnection>scm:svn:https://foo.googlecode.com/svn/trunk/</developerConnection>
    <url>http://foo.googlecode.com/svn/trunk/</url>
  </scm>

You will also need GPG to be install on your computer (Required to sign the packages) and our settings.xml correctly filled with your credentials:

您还需要在您的计算机上安装GPG(需要签署包)和我们的设置。正确填写您的凭证的xml:

  <servers>
    <server>
      <id>sonatype-nexus-snapshots</id>
      <username>your-jira-id</username>
      <password>your-jira-pwd</password>
    </server>
    <server>
      <id>sonatype-nexus-staging</id>
      <username>your-jira-id</username>
      <password>your-jira-pwd</password>
    </server>
  </servers>

After that, you should be able to use the two steps release:

之后,您应该能够使用这两个步骤发布:

$ mvn release:prepare

$ mvn release:perform

Unfortunately, I don't know any way of automate the manual approval part of the process (In oss.sonatype.org). But that should already save you some times.

不幸的是,我不知道有什么方法可以自动完成流程的手工批准部分(在oss.sonatype.org)。但这已经为你节省了一些时间。

The documentation, as shown above, is probably a bit convoluted but is very complete and gives you all you need to know for various scenarios.

如上所示,文档可能有点复杂,但是非常完整,并且提供了各种场景所需的所有信息。

EDIT:

编辑:

In fact I think I am wrong and there is a part on automate approval process. Interesting.

事实上,我认为我错了,有一部分是关于自动审批流程的。有趣。

And for this part you are right, the details are quite limited. Though, I hope the first part of the configuration already helps you a little bit. I need to look further into this staging stuff (Or maybe someone else would have already done it !)

对于这一部分,你是对的,细节是非常有限的。不过,我希望配置的第一部分已经对您有所帮助。我需要进一步研究这个阶段的东西(或者可能已经有人做过了!)

EDIT_AGAIN:

EDIT_AGAIN:

I need to actually try it but it would sound like something as follow:

我需要试一试,但听起来像是

        <plugins>
            <plugin>
                <groupId>org.sonatype.plugins</groupId>
                <artifactId>nexus-staging-maven-plugin</artifactId>
                <version>1.6</version>
                <extensions>true</extensions>
                <configuration>
                    <!-- The Base URL of Nexus instance where we want to stage -->
                    <nexusUrl>https://oss.sonatype.org/service/local/staging/deploy/maven2/</nexusUrl>
                    <serverId>sonatype-nexus-staging</serverId>
                </configuration>
            </plugin>
        </plugins>

According to the documentation, the deploy should be replaced by the right staging workflow (Including the close) and it would left the latest step:

根据文件,部署应该被正确的暂存工作流(包括关闭工作流)取代,并留下最新的步骤:

$ mvn nexus-staging:release -Ddescription="Yippie!"

TO BE TESTED...

要测试……

#2


2  

So 95% automated but I still need to figure out the stagingRepositoryId every time.

95%都是自动的,但我还是需要每次都算出停滞库。

You can use mvn nexus-staging:rc-list

您可以使用mvn nexus-staging:rc-list

Specifically, by doing mvn release:rc-list and using grep or whatever to filter the output from that by some form of the group ID or other substring that you know the stagingRepositoryId to be, you can determine the full stagingRepositoryId value

具体地说,通过做mvn发布:rc-list,使用grep或其他任何形式来过滤来自于您所知道的stagingRepositoryId的组ID或其他子字符串的输出,您可以确定完整的stagingRepositoryId值。

For example, the group ID for my project is nu.validator and my stagingRepositoryId values are all in the form nuvalidator-NNNN where the NNNN part is a number that started from 1000 with my first release and that the system increments by 1 each time I release; so nuvalidator-1000, nuvalidator-1001, and so on.

例如,我的项目的组ID是nu。验证器和我的stagingRepositoryId值都在表单nuvalidator-NNNN中,其中NNNN部分是一个从1000开始的数字,我的第一次发布,每次释放时系统都会增加1;nuvalidator-1000, nuvalidator-1001,等等。

So in the python script I use for my build, I just do this:

在我构建的python脚本中,我这样做:

output = subprocess.check_output("mvn nexus-staging:rc-list  -DnexusUrl=https://oss.sonatype.org/ -DserverId=ossrh")
for line in output.split('\n'):
    if "nuvalidator" in line:
        stagingRepositoryId = "nuvalidator-" + line[8:23]
        ...

That's because the relevant lines returned in the mvn nexus-staging:rc-list output are in the form:

这是因为在mvn nexus-staging中返回的相关行:rpc -list输出是:

...
[INFO] central_bundles-3514 OPEN     Implicitly created (auto staging).
[INFO] central_bundles-3515 OPEN     Implicitly created (auto staging).
[INFO] central_bundles-3521 OPEN     Implicitly created (auto staging).
[INFO] nuvalidator-1008     OPEN     Implicitly created (auto staging).
...

#1


2  

For the convenience of Maven projects, Sonatype is providing a parent POM you can add to your project with all the basic configuration:

为了方便Maven项目,Sonatype提供了一个父POM,您可以将所有基本配置添加到项目中:

https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide#SonatypeOSSMavenRepositoryUsageGuide-Changesto%7B%7Bpom.xml%7D%7D

https://docs.sonatype.org/display/Repository/Sonatype + OSS +使用Maven +库+ +指南# SonatypeOSSMavenRepositoryUsageGuide-Changesto % 7 b % 7 bpom.xml % 7 d % 7 d

The important bits are:

重要的部分是:

  <parent>
    <groupId>org.sonatype.oss</groupId>
    <artifactId>oss-parent</artifactId>
    <version>7</version>
  </parent>

And the source code repository details:

以及源代码库的详细信息:

  <scm>
    <connection>scm:svn:http://foo.googlecode.com/svn/trunk/</connection>
    <developerConnection>scm:svn:https://foo.googlecode.com/svn/trunk/</developerConnection>
    <url>http://foo.googlecode.com/svn/trunk/</url>
  </scm>

You will also need GPG to be install on your computer (Required to sign the packages) and our settings.xml correctly filled with your credentials:

您还需要在您的计算机上安装GPG(需要签署包)和我们的设置。正确填写您的凭证的xml:

  <servers>
    <server>
      <id>sonatype-nexus-snapshots</id>
      <username>your-jira-id</username>
      <password>your-jira-pwd</password>
    </server>
    <server>
      <id>sonatype-nexus-staging</id>
      <username>your-jira-id</username>
      <password>your-jira-pwd</password>
    </server>
  </servers>

After that, you should be able to use the two steps release:

之后,您应该能够使用这两个步骤发布:

$ mvn release:prepare

$ mvn release:perform

Unfortunately, I don't know any way of automate the manual approval part of the process (In oss.sonatype.org). But that should already save you some times.

不幸的是,我不知道有什么方法可以自动完成流程的手工批准部分(在oss.sonatype.org)。但这已经为你节省了一些时间。

The documentation, as shown above, is probably a bit convoluted but is very complete and gives you all you need to know for various scenarios.

如上所示,文档可能有点复杂,但是非常完整,并且提供了各种场景所需的所有信息。

EDIT:

编辑:

In fact I think I am wrong and there is a part on automate approval process. Interesting.

事实上,我认为我错了,有一部分是关于自动审批流程的。有趣。

And for this part you are right, the details are quite limited. Though, I hope the first part of the configuration already helps you a little bit. I need to look further into this staging stuff (Or maybe someone else would have already done it !)

对于这一部分,你是对的,细节是非常有限的。不过,我希望配置的第一部分已经对您有所帮助。我需要进一步研究这个阶段的东西(或者可能已经有人做过了!)

EDIT_AGAIN:

EDIT_AGAIN:

I need to actually try it but it would sound like something as follow:

我需要试一试,但听起来像是

        <plugins>
            <plugin>
                <groupId>org.sonatype.plugins</groupId>
                <artifactId>nexus-staging-maven-plugin</artifactId>
                <version>1.6</version>
                <extensions>true</extensions>
                <configuration>
                    <!-- The Base URL of Nexus instance where we want to stage -->
                    <nexusUrl>https://oss.sonatype.org/service/local/staging/deploy/maven2/</nexusUrl>
                    <serverId>sonatype-nexus-staging</serverId>
                </configuration>
            </plugin>
        </plugins>

According to the documentation, the deploy should be replaced by the right staging workflow (Including the close) and it would left the latest step:

根据文件,部署应该被正确的暂存工作流(包括关闭工作流)取代,并留下最新的步骤:

$ mvn nexus-staging:release -Ddescription="Yippie!"

TO BE TESTED...

要测试……

#2


2  

So 95% automated but I still need to figure out the stagingRepositoryId every time.

95%都是自动的,但我还是需要每次都算出停滞库。

You can use mvn nexus-staging:rc-list

您可以使用mvn nexus-staging:rc-list

Specifically, by doing mvn release:rc-list and using grep or whatever to filter the output from that by some form of the group ID or other substring that you know the stagingRepositoryId to be, you can determine the full stagingRepositoryId value

具体地说,通过做mvn发布:rc-list,使用grep或其他任何形式来过滤来自于您所知道的stagingRepositoryId的组ID或其他子字符串的输出,您可以确定完整的stagingRepositoryId值。

For example, the group ID for my project is nu.validator and my stagingRepositoryId values are all in the form nuvalidator-NNNN where the NNNN part is a number that started from 1000 with my first release and that the system increments by 1 each time I release; so nuvalidator-1000, nuvalidator-1001, and so on.

例如,我的项目的组ID是nu。验证器和我的stagingRepositoryId值都在表单nuvalidator-NNNN中,其中NNNN部分是一个从1000开始的数字,我的第一次发布,每次释放时系统都会增加1;nuvalidator-1000, nuvalidator-1001,等等。

So in the python script I use for my build, I just do this:

在我构建的python脚本中,我这样做:

output = subprocess.check_output("mvn nexus-staging:rc-list  -DnexusUrl=https://oss.sonatype.org/ -DserverId=ossrh")
for line in output.split('\n'):
    if "nuvalidator" in line:
        stagingRepositoryId = "nuvalidator-" + line[8:23]
        ...

That's because the relevant lines returned in the mvn nexus-staging:rc-list output are in the form:

这是因为在mvn nexus-staging中返回的相关行:rpc -list输出是:

...
[INFO] central_bundles-3514 OPEN     Implicitly created (auto staging).
[INFO] central_bundles-3515 OPEN     Implicitly created (auto staging).
[INFO] central_bundles-3521 OPEN     Implicitly created (auto staging).
[INFO] nuvalidator-1008     OPEN     Implicitly created (auto staging).
...