Maven 3.0's “mvn release:perform” doesn't

2019-03-19 02:12发布

问题:

I have a question about Maven, the maven-release-plugin, git integration, pom.xml's, and having pom.xml's in subdirectories of the repo's local copy rather than in the root.

Here's the setup:

  • I have a github account with a limited number of private repositories
  • I want to (am just learning to) use Maven to organize my builds/releases
  • I might need to create many Maven "projects", several projects per git repository
  • Each maven project requires a "pom.xml" to define its characteristics
  • I can't, or at least it's not convenient to, put all project pom.xml files in the root of the git repository
  • So I end up with this folder layout for projects:
    • git_repo_root_dir
      • project_A folder
        • pom.xml
        • other_code
      • project_B folder
        • pom.xml
        • other_code
      • etc.
      • ...
  • I can successfully go to directory git_repo_root_dir/project_A and do an "mvn release:prepare"
  • I fail with this step in git_repo_root_dir/project_A: "mvn release:perform"
    • The problem seems to be that the git-tagged code is successfully checked out to git_repo_root_dir/project_A/target/checkout/project_A in preparation for the release build, but then after the checkout the "maven-release" plugin goes to directory git_repo_root_dir/project_A/target/checkout/. instead of git_repo_root_dir/project_A/target/checkout/project_A/. to do the actual build, and there's no way to tell the "maven-release" plugin to step into a subdirectory of the special tagged copy of the source before trying to mess with the pom.xml
  • QUESTION: is there a way around this? Is there an option to somehow tell "mvn release:perform" to go to the subdirectory?

Here's the actual error I get during this process:

[INFO] --- maven-release-plugin:2.0:perform (default-cli) @ standard_parent_project ---
[INFO] Checking out the project to perform the release ...
[INFO] Executing: /bin/sh -c cd "/Users/___/DEV c8ion 01/maven_based_code/0maven/standard_parent_project/target" && git clone git@github.com:clarafaction/0maven.git '/Users/___/DEV c8ion 01/maven_based_code/0maven/standard_parent_project/target/checkout'
...
/* note, the pom.xml the build should go out of at this point is at
   '/Users/___/DEV c8ion 01/maven_based_code/0maven/standard_parent_project/target/checkout/standard_parent_project/pom.xml'
*/
...
[INFO] [ERROR] The goal you specified requires a project to execute but
    there is no POM in this directory
    (/Users/___/DEV c8ion 01/maven_based_code/0maven/standard_parent_project/target/checkout).
    Please verify you invoked Maven from the correct directory. -> [Help 1]

Thanks.

回答1:

This should do the trick:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-release-plugin</artifactId>
    <version>2.3.2</version>
    <executions>
        <execution>
            <id>default</id>
            <goals>
                <goal>perform</goal>
            </goals>
            <configuration>
                <pomFileName>your_path/your_pom.xml</pomFileName>
            </configuration>
        </execution>
    </executions>
</plugin>


回答2:

You can do it in the same way you normally tell Maven to run from a POM that's somewhere else: the -f option. mvn --help describes it thusly:

-f,--file <arg>    Force the use of an alternate POM
                   file.

To do that in a release, you just need to pass the appropriate option to the release plugin. You can use the perform goal's "arguments" property to do that. This property just tells the release plugin some additional arguments to append to the mvn command it runs when doing the release. You can set it from the command line by appending -D arguments="-f path/to/pom" or set it permanently in the pom in the release plugin's configuration, something like

<plugin>
    <artifactId>maven-release-plugin</artifactId>
    <version>2.3</version>
    <configuration>
        <arguments>-f path/to/pom</arguments>
    </configuration>
</plugin>


回答3:

The first thing is to understand git which has it's convention that every project has it's own repository. The next thing is that Maven has it's conventions and putting the pom.xml into the root of it's project is the most obvious one. Furthermore you are trying to fight against Maven and i will predict that you will lose the combat and make your life not easy. If your projects A and B are related (same versio number or same release times) in some kind you should think about a multi-module build which results in a structure like this:

root (Git Repos)
  +-- pom.xml
       +--- projectA (pom.xml)
       +--- projectB (pom.xml)

and you can do a release of both projectA (better calling it a module) and module b in a single step from the root.