Aritz
Aritz

Reputation: 31679

Retrieve svn last changed revision number with the buildnumber-maven-plugin

I'm currently developing a microservice based architecture for my application. I've got a maven multi-module project which has many services, so I can easily deploy them to the docker hub using the maven deploy command and also a maven docker plugin.

Still, the docker image tags are based in the project version number, while I would like to have them tagged with each repository's last changed revision number. From the time being, I'm trying just to add this field as a manifest entry using the buildnumber-maven-plugin:

Let's say that's my multi-module project:

<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>
...

    <modules>
        <module>module-a</module>
        <module>module-b</module>
    </modules>

...

</project>

And the model for module-a would be:

<?xml version="1.0" encoding="UTF-8"?>
<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">
    ...


    <scm>
        <connection>scm:svn:http://myrepo.com/svn/application/module-a</connection>
    </scm>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>buildnumber-maven-plugin</artifactId>
                <version>1.4</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>create</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <doCheck>false</doCheck>
                    <doUpdate>true</doUpdate>
                    <useLastCommittedRevision>true</useLastCommittedRevision>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifestEntries>
                            <SCM-Revision>${buildNumber}</SCM-Revision>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>
            ....
        </plugins>
    </build>

    <dependencies>
        ...
    </dependencies>

</project>

The issue is that {buildNumber} evaluates to my working copy number, which is the one referring to the last commit made to the repository and not to the scm:svn:http://myrepo.com/svn/application/module-a location. To explain it better, when I display the properties of module-a from tortoise I've got this:

enter image description here

What I want is to retrieve 3248 which refers to the last real change made to module-a, instead of 3257 (working copy), which is what I'm getting from the plugin. That way the docker plugin would know if it's a different image tag and push it only if changes were made to the module in the repo.

Upvotes: 5

Views: 2659

Answers (5)

Benjamin Seiller
Benjamin Seiller

Reputation: 2905

Having stumbled upon this issue as well, I felt compelled to get to the bottom of it: This seems to be a rather old issue in buildnumber-maven-plugin itself: Implement "Last Changed Rev" instead of "Revision" field

A fix was actually committed, but no new version has been released since then.

The easiest option would be to checkout/download the code and build it locally, making sure to put it into the central repository of your organization.

If this is not an option try jitpack to get the latest version as maven dependency directly: Can I use a GitHub project directly in Maven? => https://stackoverflow.com/a/28483461/167865

...
<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>
...
<dependency>
    <groupId>com.github.mojohaus</groupId>
    <artifactId>buildnumber-maven-plugin</artifactId>
    <version>e74e373</version>
</dependency>
...

Upvotes: 1

Andrew
Andrew

Reputation: 140

This is well-known bug in maven-scm-provider-svnexe. Still not fixed.

Upvotes: 0

karmarok
karmarok

Reputation: 51

I couldn't get buildnumber-maven-plugin to work for this same scenario either. <useLastCommittedRevision> does not work in v1.4 and in v1.3 it does not return the last changed revision but the penultimate one in some situations.

There is a crafty workaround you can do to get the last changed revision number from svn info command output. Two options depending on your SVN version:

  1. For SVN v1.9 or newer versions, use maven-antrun-plugin to run svn info --show-item=last-changed-revision and save the output into a property.

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.8</version>
        <executions>
            <execution>
                <phase>validate</phase>
                <goals>
                    <goal>run</goal>
                </goals>
                <configuration>
                    <exportAntProperties>true</exportAntProperties>
                    <target>
                        <exec executable="svn" outputProperty="svn.info">
                            <arg value="info"/>
                            <arg value="--show-item=last-changed-revision"/>
                        </exec>
                    </target>
                </configuration>
            </execution>
        </executions>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
            <archive>
                <manifestEntries>
                    <SCM-Revision>${svn.info}</SCM-Revision>
                </manifestEntries>
            </archive>
        </configuration>
    </plugin>
    
  2. For SVN versions older than v1.9 (v1.8.13 in my case) you can use maven-antrun-plugin to run svn info --xml and save the output into a property, and build-helper-maven-plugin to parse the contents of that property with a regular expression, matching the last changed revision number and saving it into a second property.

    I chose to add the --xml parameter because basic svn info output is translated depending on the language of the installation, but the xml output format is always the same.

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.8</version>
        <executions>
            <execution>
                <phase>validate</phase>
                <goals>
                    <goal>run</goal>
                </goals>
                <configuration>
                    <exportAntProperties>true</exportAntProperties>
                    <target>
                        <exec executable="svn" outputProperty="svn.info">
                            <arg value="info"/>
                            <arg value="--xml"/>
                        </exec>
                    </target>
                </configuration>
            </execution>
        </executions>
    </plugin>
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>3.0.0</version>
        <executions>
            <execution>
                <id>regex-svn-last-rev</id>
                <goals>
                    <goal>regex-property</goal>
                </goals>
                <configuration>
                    <!-- Output property -->
                    <name>svn.last.rev</name>
                    <value>${svn.info}</value>
                    <regex>^[\s\S]*?commit[\s\S]*?revision=\"(\d+?)\"[\s\S]*?$</regex>
                    <replacement>$1</replacement>
                    <failIfNoMatch>false</failIfNoMatch>
                </configuration>
            </execution>
        </executions>
    </plugin>       
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
            <archive>
                <manifestEntries>
                    <SCM-Revision>${svn.last.rev}</SCM-Revision>
                </manifestEntries>
            </archive>
        </configuration>
    </plugin>
    

Upvotes: 4

Soumya Kanti
Soumya Kanti

Reputation: 1479

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>buildnumber-maven-plugin</artifactId>
    <version>1.3</version>
    <executions>
        <execution>
            <phase>validate</phase>
            <goals>
                <goal>create</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <doCheck>false</doCheck>
        <doUpdate>true</doUpdate>
        <useLastCommittedRevision>true</useLastCommittedRevision>
    </configuration>
</plugin>

This worked for me.

Upvotes: 3

mvk_il
mvk_il

Reputation: 960

I think the only thing you missed here is

<doCheck>false</doCheck>

I think it should be true.

Upvotes: 1

Related Questions