如何在持续集成情况下使用 Maven 在存储库中安装版本化工件?

发布于 2024-07-09 03:13:42 字数 687 浏览 8 评论 0原文

我们正在将主要构建流程从 ant 转换为 Maven。 我们使用 TeamCity 作为持续集成服务器 (CI)。

我们希望使用 CI 服务器来启动(每晚)版本包含构建号的构建,如 1.0.0.build# 中所示。 这些构建将安装在我们的本地 Maven 存储库中,以供其他项目使用。 因此 CI 服务器将管理版本,maven 将构建项目,maven 存储库将使构建可供其他项目访问。

我打算使用以下命令从 CI 服务器启动构建:

mvn -Dversion=1.0.0.25 install

该项目的 pom 将有一个伪造的版本号,并且 -D 标志将覆盖它,如下所示:

<version>0.0.0.0</version>

此方法的问题是 maven install 插件仅使用pom文件中的版本,而不是命令行传入的版本。 此 Maven 问题 中对此进行了说明。

因此,由于这个问题自 08/2006 年以来就已经存在并且尚未得到解决,我认为这在某种程度上不是“maven 方式”。 所以我的问题是,如何在持续集成情况下使用 Maven 在存储库中安装版本化工件?

We are in the process of converting our main build process from ant to maven. We use TeamCity for our Continuous Integration server (CI).

We'd like to use the CI server to kick off (nightly) builds whose version contain a build number, as in 1.0.0.build#. These builds would be installed in our local maven repository to be used by other projects. So the CI server would manage the versions, maven would build the project, and the maven repository would make the builds accessible to other projects.

I intended to initiate the build from the CI server using the following command:

mvn -Dversion=1.0.0.25 install

The project's pom would have a bogus version number, and the -D flag would override it, as in:

<version>0.0.0.0</version>

The problem with this method is that the maven install plugin only uses the version in the pom file, not the version passed in on the command line. This is noted in this maven issue.

So since this issue has existed since 08/2006 and has not been fixed, I assume that this is somehow not 'the maven way'. So my question is, how can maven be used in a continuous integration situation to install versioned artifacts in the repository?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

忘你却要生生世世 2024-07-16 03:13:42

听起来您想构建具有独特版本的快照版本。

因此,在 POM 中将版本声明为:

<version>#.#.#-SNAPSHOT</version>

然后,在 POM 的 distributionManagement 部分中,通过以下方式为 snapshotRepository 启用唯一版本(请参阅 Maven 的 POM 参考 ):

<snapshotRepository>
  <uniqueVersion>true</uniqueVersion>
  <id>your-snapshot-repo-id</id>
  <name>Your Snapshots</name>
  <url>http://your-snapshot-repo-url/maven</url>
</snapshotRepository>

仅供参考,请注意 Maven 约定 建议将版本声明为major.minor.revision。 因此,1.0.25 而不是 1.0.0.25。 如果您能够使用此版本控制方案,那么在 Maven 世界中一切都会工作得更加顺利。

Sounds like you want to build SNAPSHOT versions with unique versions.

So, in your POM declare the version as:

<version>#.#.#-SNAPSHOT</version>

Then, in the distributionManagement section of your POM, enable unique versions for the snapshotRepository via (see Maven's POM reference on this):

<snapshotRepository>
  <uniqueVersion>true</uniqueVersion>
  <id>your-snapshot-repo-id</id>
  <name>Your Snapshots</name>
  <url>http://your-snapshot-repo-url/maven</url>
</snapshotRepository>

FYI, note that Maven conventions recommend versions be declared as major.minor.revision. So, 1.0.25 instead of 1.0.0.25. If you're able to use this versioning scheme, things will work more smoothly in a Maven world.

浅笑轻吟梦一曲 2024-07-16 03:13:42

Matthew 的回答提供了一个解决方案,其中工件被上传到具有所需版本号的本地和远程存储库,即内部路径存储库包含正确的版本号,但是,Maven 安装和部署的源 POM 文件始终在版本元素中包含 ${ciVersion}

如果您有一个具有公共父级的多模块,如下所示:

<project xmlns="..." xmlns:xsi="..." xsi:schemaLocation="...">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <artifactId>myParent</artifactId>
    <groupId>com.stackoverflow</groupId>
    <version>${ciVersion}</version>
  </parent>
  <artifactId>myChild</artifactId>
  ...
</project>

您将无法引用 myChild 模块的专用版本,因为依赖项解析将存在无法找到的错误版本为 ${ciVersion}myParent 模块。

但是,您可以使用 resolve-pom-maven-plugin将 POM 上传到本地和远程存储库,其中 POM 内的所有变量都将替换为其实际值。 为此,您必须将以下代码片段添加到您的(父)POM 中:

...
<build>
  <plugins>
    <plugin>
      <groupId>com.sap.prd.mobile.ios.maven.plugins</groupId>
      <artifactId>resolve-pom-maven-plugin</artifactId>
      <version>1.0</version>
      <executions>
        <execution>
          <id>resolve-pom-props</id>
          <goals>
            <goal>resolve-pom-props</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
...

Matthew's answer provides a solution where the artifacts get uploaded into the local and remote repository having the desired version number, i.e. the paths inside the repository are contain the correct version numbers, however, Maven installs and deploys always the source POM file that would still contain the ${ciVersion} in the version element.

If you have a multi-module with a common parent like this:

<project xmlns="..." xmlns:xsi="..." xsi:schemaLocation="...">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <artifactId>myParent</artifactId>
    <groupId>com.stackoverflow</groupId>
    <version>${ciVersion}</version>
  </parent>
  <artifactId>myChild</artifactId>
  ...
</project>

you won't be able to reference a dedicated version of the myChild module, as the dependency resolution will exist with an error that it cannot find the myParent module with version ${ciVersion}.

However, you could use the resolve-pom-maven-plugin that uploads a POM into the local and remote repository where all variables inside the POM get substituted by their actual values. In order to do this, you have to add the following snippet into your (parent) POM:

...
<build>
  <plugins>
    <plugin>
      <groupId>com.sap.prd.mobile.ios.maven.plugins</groupId>
      <artifactId>resolve-pom-maven-plugin</artifactId>
      <version>1.0</version>
      <executions>
        <execution>
          <id>resolve-pom-props</id>
          <goals>
            <goal>resolve-pom-props</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
...
陈年往事 2024-07-16 03:13:42

Shek的答案可能是“行家之道”,所以我会接受它作为正确的答案。 然而,我们还没有准备好改变我们的约定,所以这是我们正在使用的解决方法。

通过使用一定程度的间接,您可以在构建时将版本号传递给 pom,并让安装和部署插件使用它们。 例如:

<project xmlns="..." xmlns:xsi="..." xsi:schemaLocation="...">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.stackoverflow</groupId>
  <artifactId>stackoverflow</artifactId>
  <version>${ciVersion}</version>
  <packaging>jar</packaging>
  <name>StackOverflow</name>

  <properties>
    <ciVersion>0.0.0.0</ciVersion>
  </properties>

  ...

</project>

我们不能直接覆盖${project.version}。 因此,我们添加第二个名为“ciVersion”的属性,并在属性部分为其指定默认值“0.0.0.0”。 现在,CI 服务器可以通过覆盖命令行上的 ciVersion 属性来指定版本号。 如:

mvn -DciVersion=1.0.0.25 install

安装和部署插件将使用每当引用 ${project.version} 时传入的 ciVersion 属性的值(如预期),并且当命令行上未提供版本时将使用默认值。 这使我们能够切换到 Maven,同时对我们的流程影响最小。 此外,这种解决方法并不引人注目,可以在需要时轻松切换到快照功能。

Shek's answer is probably 'the maven way', so I'll accept it as the correct answer. However, we are not ready to change our conventions, so here is the workaround that we are using.

By using a level of indirection you can pass a version number in to the pom at build time and have the install and deploy plugins use them. For example:

<project xmlns="..." xmlns:xsi="..." xsi:schemaLocation="...">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.stackoverflow</groupId>
  <artifactId>stackoverflow</artifactId>
  <version>${ciVersion}</version>
  <packaging>jar</packaging>
  <name>StackOverflow</name>

  <properties>
    <ciVersion>0.0.0.0</ciVersion>
  </properties>

  ...

</project>

We cannot override ${project.version} directly. So instead, we add a second property called 'ciVersion' and give it a default value of '0.0.0.0' in the properties section. Now the CI server can specify a version number by overriding the ciVersion property on the command line. As in:

mvn -DciVersion=1.0.0.25 install

The install and deploy plugins will use the value of the ciVersion property that was passed in whenever ${project.version} is referenced, as expected, and the default value will be used when no version is provided on the command line. This allows us to switch to maven with minimal impact on our process. In addition, this workaround is unobtrusive, allowing for an easy switch to the SNAPSHOT functionality when desired.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文