7

我们正在将我们的主要构建过程从 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 在存储库中安装版本化的工件?

4

3 回答 3

6

听起来您想构建具有唯一版本的 SNAPSHOT 版本。

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

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

然后,在你的 POM 的distributionManagement部分,通过(参见 Maven 的POM 参考)为snapshotRepository启用唯一版本:

<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 世界中一切都会更加顺利。

于 2008-12-03T02:30:01.013 回答
5

马修的回答提供了一个解决方案,其中工件被上传到具有所需版本号的本地和远程存储库中,即存储库内的路径包含正确的版本号,但是,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模块的专用版本,因为依赖解析将存在一个错误,即它无法找到myParent具有版本的模块${ciVersion}

但是,您可以使用将 POM 上传到本地和远程存储库的resolve-pom-maven-plugin,其中 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>
...
于 2012-09-07T06:18:57.780 回答
4

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。此外,此解决方法不显眼,允许在需要时轻松切换到 SNAPSHOT 功能。

于 2008-12-08T20:57:13.893 回答