4
votes

UPDATE #1 9/18

My company has decided to entirely revamp their development/release cycle to fit a growing number of developers.

The git process will be similar to the successful branching model with a few changes. Instead of developers having direct push access to the "develop" branch, developers would need to make a merge/pull request, requiring code review and basic unit testing.

The version system would be Major.Minor.Patch, where Major versions mark backwards compatibility breaks, Minor versions mark new features and minor bug fixes, and Patch marks critical hot fixes. This new version system will remove the Jenkins build number as a useful piece of information, but attach it to the deployed artifacts for historical purposes.

The "develop" branch will be tracked by Jenkins to build and deploy a SNAPSHOT to our local Nexus, so unreleased but accepted features are available to the developers. The "master" branch will also be tracked by Jenkins to build and deploy release artifacts.

The release process would:

  • Update the POM version based on the released features
  • Git tag the branch with the new version
  • Perform unit, integration, and system testing.
  • Build, obfuscate, and deploy the release artifacts to our Nexus
  • Update the "develop" branch version to "Major.Minor++-SNAPSHOT" for the new development SNAPSHOT.

ORIGINAL POST

I am attempting to build a JAR library that is obfuscated, uses a dynamic build number based on a Jenkins/Hudson build, and is deployed to an in-house Sonatype Nexus.

My issue is that Maven install/deploy does not honor changes to finalName, and setting the version with an expression like the following is considered "bad practice":

    <version>1.0.${buildNumber}</version>

Despite this being bad practice, it properly installs/deploys the artifacts with the proper version, both local and remote. The build number is based off of a pair of profiles that are linked to the existence of the build number environment variable of a Jenkins build system, and defaults to 0 in the absence of that variable:

    <profile>
        <id>static_build_number</id>
        <activation>
            <property>
                <name>!env.BUILD_NUMBER</name>
            </property>
        </activation>
        <properties>
            <buildNumber>0</buildNumber>
        </properties>
    </profile>
    <profile>
        <id>dynamic_build_number</id>
        <activation>
            <property>
                <name>env.BUILD_NUMBER</name>
            </property>
        </activation>
        <properties>
            <buildNumber>${env.BUILD_NUMBER}</buildNumber>
        </properties>
    </profile>

We do not use SNAPSHOT versions, as any version that is committed and pushed to the Nexus is considered a tested release version.

Is there a "proper" way to set the Maven version based on a Jenkins/Hudson dynamic build number, allowing it to be deployed with that updated version?

1
@Anton, that question is similar, but my buildNumber is always resolved due to the profile setup defaulting to 0. My solution works 100% of the time, but is considered bad practice by Maven due to the expression in the project version.Nick Johnson

1 Answers

1
votes

The maven way says a version changes only when you release the code, and that two successive builds of the same version, should produce the same output.

In your case, you're going against those two good practices.

If truly every commit is a new release, then what you're doing doesn't sound terribly wrong (but it does sound funny to me). One drawbacks is that it doesn't look like you are createing a tag from your VCS (which is another good practice).

I'll be honest. I can't believe that each commit is a production-ready release. I've never seen this, even in Continuous-Delivery environments, where each commit needs to pass a lot of automated testing and sometimes the revision is rejected (maybe for functional or performance reasons).