4

At the moment, we're doing "traditional" deployment, where every couple of weeks, we roll a release. We rely on Semantic Versioning, which has worked well for us.

However, we now want to release faster, using Jenkins Pipelines etc, but I'm not sure what the best versioning strategy would be. Not having any versions (only Snapshots) is a step backwards, creating new versions all the time seems to be a lot of work.

So, if you are doing CD with Maven, what's your strategy?

2
  • 1
    Can you add why creating versions is a lot of work in your workflow?
    – AnoE
    Aug 3, 2018 at 18:12
  • Basically, since the artifacts depend on each other, we need to release them in the correct sequence. And since there's a lot of them, it takes some time.
    – eerriicc
    Aug 6, 2018 at 7:08

3 Answers 3

1

I've just done this and so far it's working well for us.

Basically we use a Jenkinsfile and retrieve the version from the POM (which is using semantic versioning) and remove the snapshot.

stage('Build Docker Container') {
        steps {
             script {
                pom = readMavenPom file: 'pom.xml'
                pom_version_snapshot = pom.version

                version = pom_version_snapshot.split("-")[0]
                echo version

            }
            sh "docker build -f 'Dockerfile' -t repo/container:${version}-${env.BRANCH_NAME} ."
        }
    }

We then do a Docker build and use that version to tag the image, which is later deployed to a Kubernetes cluster.

3
  • But then you don't have a release version of your artifact in some repository (like Nexus), right? Your Docker container is the released artifact.
    – eerriicc
    Aug 6, 2018 at 12:06
  • The Docker container is the release artifact in our use case (it's published to a Docker Hub repository). However you could just create a new 'stage' in your Jenkinsfile that uploads the artifact produced by the Maven build to Amazon S3 or some other cloud storage. You could do that and the Docker container if you really wanted. Aug 7, 2018 at 8:55
  • Nice! Did you try to combine your approach with maven.apache.org/maven-ci-friendly.html ? I’m thinking to use this approach and have ${revision} set as a property to the SemVer version, and ${changelist} set to -SNAPSHOT so the local workspace build will behave like old maven, and instead tell to jenkins to build with the -Dchangelist=<perforce changelist> so to make a release at every build. Note that in order to deploy to a Repository Manager, need to configure maven flatten plugin (to replace the Pom.xml with one with the actual resolved variable when installing/deploy) Jul 4, 2021 at 9:25
1

we now want to release faster

And from your comment:

Basically, since the artifacts depend on each other, we need to release them in the correct sequence. And since there's a lot of them, it takes some time.

I think you're having an X/Y problem. Yes, versioning plays a role, but it seems like you would benefit from solving the source of your problem first, which is that you have to release something in the correct sequence; presumably you also have to release everything at the same time, with a large downtime of the whole system.

Try to reach a state where you can release new versions of each artifact in arbitrary order. This basically means:

  • Employing some form of Dependency Injection (which is a big word, but can be something pretty simple, depending on how your software works).
  • You need to be able to have multiple versions of each artifact on the server at the same time, and to switch between them without much effort. That "switch" should be be on the side of the "user" of an artifact, not on the artifact itself, if you can do so at all.
  • Wherever you can, it also is great to be able to run multiple instances simultaneously (obviously this is restricted for data management stuff, databases and such).

I'm not telling you how to do that or that it is easy - I don't know your architecture or technical constraints. But this should give you a general roadmap.

When you have that capability in place (at least conceptionally), then you will be able to release smaller parts more often, and a little more independently. And - to answer your actual question - sticking with SemVer is then not the worst you can do.

0

Before this can be answered I think we need understand what does a version mean to you?

  • Is it a customer facing product version (version 8.1.2 contains these features and bug fixes)?
  • Or is it just for highlighting what version of the code is deployed where?

If it is the later you could just use the commit id and tag the commit with Jenkins build number. However, if you loose your Jenkins build history it gets slightly confusing therefore some form of CMDB managed by a container platform like k8 would be best.

1
  • The version is shown to the customer. But the bigger issue is being able to recreate (or for us, fetch from Nexus) a version which consists of a lot of artifacts, a dozen EARs etc. Also, with semantic versioning, the version has a meaning that goes beyond a commit ID.
    – eerriicc
    Aug 6, 2018 at 7:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.