如何阻止Maven的验证阶段重建工件?

And*_*wan 5 java continuous-integration maven-2 hudson continuous-deployment

想象一下使用Maven构建的Java项目,我有:

  • 一些快速运行的单元测试:
    • 开发人员应该在提交之前运行
    • 我的CI服务器(Hudson,FWIW)应该在检测到新提交时运行,在出现故障时提供几乎即时的反馈
  • 一些慢速运行的自动验收测试:
    • 开发人员可以选择运行,例如重现和修复故障
    • 我的CI服务器应该在成功运行单元测试后运行

这似乎是一个典型的场景.目前,我正在运行:

  • 该单元在"测试"阶段进行测试
  • "验证"阶段的验收测试

配置了两个CI作业,两者都指向项目的VCS分支:

  1. "Commit Stage",运行"mvn package"(编译和单元测试代码,构建工件),如果成功,则触发:
  2. "自动验收测试",运行"mvn verify"(设置,运行和拆除验收测试)

问题是作业2单元测试并重新构建被测工件(因为验证阶段会自动调用包阶段).由于几个原因(重要性降低),这是不可取的:

  • 作业2创建的工件可能与作业1创建的工件不同(例如,如果同时存在新的提交)
  • 将反馈循环延长到进行提交的开发人员(即他们需要更长时间才能发现他们破坏了构建)
  • 在CI服务器上浪费资源

所以我的问题是,如何配置作业2以使用作业1创建的工件?

我意识到我可以只有一个运行"mvn verify"的CI作业,它只会创建一次工件,但是我想拥有上面描述的单独的CI作业,以实现Farley风格的部署管道.


万一它可以帮助任何人,这里是接受答案中"项目2"的完整Maven 2 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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example.cake</groupId>
    <artifactId>cake-acceptance</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>
    <name>Cake Shop Acceptance Tests</name>
    <description>
        Runs the automated acceptance tests for the Cake Shop web application.
    </description>
    <build>
        <plugins>
            <!-- Compiler -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
            <!-- Suppress the normal "test" phase; there's no unit tests -->
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.5</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
            <!-- Cargo (starts and stops the web container) -->
            <plugin>
                <groupId>org.codehaus.cargo</groupId>
                <artifactId>cargo-maven2-plugin</artifactId>
                <version>1.0.5</version>
                <executions>
                    <execution>
                        <id>start-container</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>start</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>stop-container</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>stop</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <!-- Don't wait for CTRL-C after starting the container -->
                    <wait>false</wait>

                    <container>
                        <containerId>jetty7x</containerId>
                        <type>embedded</type>
                        <timeout>20000</timeout>
                    </container>

                    <configuration>
                        <properties>
                            <cargo.servlet.port>${http.port}</cargo.servlet.port>
                        </properties>
                        <deployables>
                            <deployable>
                                <groupId>${project.groupId}</groupId>
                                <artifactId>${target.artifactId}</artifactId>
                                <type>war</type>
                                <properties>
                                    <context>${context.path}</context>
                                </properties>
                            </deployable>
                        </deployables>
                    </configuration>
                </configuration>
            </plugin>
            <!-- Failsafe (runs the acceptance tests) -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <id>integration-test</id>
                        <goals>
                            <goal>integration-test</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>verify</id>
                        <goals>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <includes>
                        <include>**/*Test.java</include>
                    </includes>
                    <skipTests>false</skipTests>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
            <!-- Add your tests' dependencies here, e.g. Selenium or Sahi,
                with "test" scope -->
        <dependency>
            <!-- The artifact under test -->
            <groupId>${project.groupId}</groupId>
            <artifactId>${target.artifactId}</artifactId>
            <version>${target.version}</version>
            <type>war</type>
        </dependency>
    </dependencies>
    <properties>
        <!-- The artifact under test -->
        <target.artifactId>cake</target.artifactId>
        <target.version>0.1.0-SNAPSHOT</target.version>
        <context.path>${target.artifactId}</context.path>
        <http.port>8081</http.port>
        <java.version>1.6</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>
Run Code Online (Sandbox Code Playgroud)

请注意,即使这个"测试"项目没有创建工件,它也必须使用某种打包(我在这里使用"jar"),否则在验证阶段不会运行任何测试.

Pet*_*tze 4

尝试两个 Maven 项目。第一个包含构建和单元测试。您将工件安装在本地存储库中。第二个作业运行第二个 Maven 项目,该项目将第一个项目的工件声明为依赖项并运行功能测试。

不确定我刚才描述的场景是否可能,但我认为是可能的。

为了快速改进,您可以使用 绕过单元测试-Dmaven.test.skip=true。如果您将 scm 中代码的修订号传递给第二个作业,您应该能够签出相同的源代码。

您还可以检查克隆工作区 SCM 插件。这可能会为您提供一些额外的选择。