Best Practice for Build Numbers with Gradle and Jenkins - jenkins

We have a small java dev environment which uses gradle, Jenkins, and Git. We use an in-house built Gradle plugin to increment build numbers using a file to store the current number. The build number is baked into each build as part of its version data. The build number file is checked into the git workspace for the project.
We are now adding Jenkins to the environment for CI. Jenkins has its own build number which we can access via env var $BUILD_NUMBER.
The downside to our in-house Gradle build number plugin is that it uses a local file and thus builds by multiple developers do not sync build numbers. If we use Jenkins BUILD_NUMBER than that is completely different sequence than the Gradle build number plugin.
What is the best practice for this type of scenario?

If you state that only builds provided by your CI are valid for future usage it seems that you have to rely on Jenkins BUILD_NUMBER.
If you want Jenkins job BUILD_NUMBER to be started from specific value do the following:
Manage Jenkins -> Script Console
Jenkins.instance.getItemByFullName("YOUR_JOB_NAME").updateNextBuildNumber(YOUR_BUILD_NUMBER)

Related

How to get Jenkins old build inside Jenkins

I just tried to find out the old success full build in Jenkins, I did not find any way.
can any one help to find the old build in Jenkins ?
Jenkins has a setting where you can control for how long or how many builds you keep the build history or the build artefacts.
If you still have the build in history but you lost the artefacts you can rebuild it from the same hash. If the build definiton and the build environment (jenkins slave) is the same, you should obtain the same build result.
In this moment all the build engineering good practices that you kept will pay of.
To help you more, you need to tell us:
is it a UI (traditional) build definition, a pipeline defined in jenkins or a pipeline based on a jenkinsfile committed in the repository?
do you tag the sorce code repository (hopefully git) with the version of the build, or at least do you have in the build artefact the hash from which was built ?
do you store your build artefact in a repository so you can trace the history ? (artefactory, nexus, docker repo, GCP repo etc)

Global build number for Jenkins pipeline

We are in the process of switching from VSoft Continua CI to Jenkins for our build management environment. As we use a slightly modified Gitflow process we would like Jenkins to be able to build from any feature, release or hotfix branch and pull requests, we decided to go for the Jenkins Pipeline.
The version number for builds from the release and hotfix branches are based on the branch name (e.g. release/2.1.0) while builds from any other branch or pull request is based on the date (e.g. September 6th 2018 resolves to 18.9.6). Continua CI provides a auto increment build number across all build configurations that is why we use this build number as the final part of our build number (e.g. 2.1.0.10, 18.9.6.11, 2.1.0.12, ...). This generated version number is passed as parameter to MSBuild using this version number as the file version and assembly version of our .NET binaries.
I'm looking for a similar solution in Jenkins. The Jenkins Pipeline assigns a separate auto increment build number per branch and pull request which might lead to two builds from different branches having the same version. I already tried using global environment variables to store the version and increase the value with every build but it seems that global enviroment variables cannot be set from Pipeline tasks.
Is there a way for a Jenkins Pipeline project to share a build number across all branches/pull requests?
Here are a few ideas:
have it file based: have your stage execute on, say, the master node; pick a file and decide on the format (properties file can be a good start); lock, read, update, write, unlock.
delegate this to an external service (for instance, a service with a
REST endpoint that you use to request an ID).
write a plugin for it.

How to retrieve jenkins build pipeline number?

In Jenkins I would like to build my test environment based on the "Build Pipeline Number" to make tests and deployment repeatable (on the same source version), but I didn't find any environment variable to retrieve this number. I tried to use the BUILD_ID but it is different for each job (downstream project).
Is it possible to retrieve the Build Pipeline Number? Or is there any other control number that I can use that is the same for all the jobs (increases on a new build)?
If you are using the less popular Delivery pipeline plugin there is a PIPELINE_VERSION environment variable. Otherwise, with the Build pipeline plugin you would probably have to use your VCS revision number and pass it downstream with Parameterized Trigger Plugin
If you would like to see the list of all current available environment variables just run a batch command SET from your build step (or if linux in shell env)

TFS Build Services, environment variables and multiple build agents

I have a MsBuild process that start as part of build using TFS Build Services 2013. I need to pass a few parameters to this process (for example the build number). I've done this previously by modifying the build template and added these parameters to the list of parameters sent into MSBuild, something that has worked fine.
I did however found that TFS Build Services writes a number of environment variables for run (build number being one of them) and as I easily can change my MSBuild script I'd rather just use these directly variables instead of modifying the build template.
My question is however how this will work when I have several build agents? Won't they write over each others values in the environment variables? Can I be 100% certain in my MSBuild script that I didn't get the build number of the next build that might have started in parallel?
Each TFS build is done using a specific build number. If you have multiple agents working on a 'parallel' build, they will all use the same build number. Each build agent will be running in their own specific environment and will not have any issue if other agents are running in parallel - the build number for one agent will not 'clobber' another during a build.

Do I specify binary artifact settings in the build scripts or the CI server?

I'm prototyping a new build system using Jenkins, Gradle, and Artifactory. There seems to be conflicting or rather overlapping features in these tools, in regards to specifying the build artifacts and their destination. I see three paths going forward:
Specify the artifact settings on the particular task in Jenkins, using the Jenkins Artifactory plugin.
Specify the artifact settings in the Gradle build scripts, using the Gradle Artifactory plugin.
Specify generic maven repo settings in the Gradle build scripts, using the standard Gradle "maven" plugin.
I see pro's and con's to all of these approaches, but nothing is missing a critical feature for our builds, as far as I can see.
To further my confusion, the Gradle Artifactory plugin wiki states:
Build Server Integration - When running Gradle builds in your
continuous integration build server, it is recommended to use one of
the Artifactory Plugins for Jenkins, TeamCity or Bamboo to configure
resolution and publishing to Artifactory with build-info capturing,
via your build server UI.
So, some questions to get the conversation going:
Does it make sense to clutter the build scripts with artifact logic? It might help to add that developer's don't deploy. Currently, I only see build artifacts being uploaded from the Jenkins task.
Does leaving all of this build logic in the task configuration expose us to issues, in the event that the CI server is down?
What about version control for artifact changes done through the CI interface?
I've seen simple Bamboo configurations that specify the build artifacts through the CI server UI, rather than the pom's. Is this just a bad build practice?
Is there a killer tool integration feature that separates one of these approaches from the other?
How useful is the build info object? Is that only available in the Jenkins Artifactory plugin and not the Gradle Artifactory plugin?
I am really hoping to hear from existing users of these tools and what pitfalls/requirements may have led them to one of the approaches above (or perhaps even a better one that I haven't considered yet).
Does it make sense to clutter the build scripts with artifact logic? It might help to add that developer's don't deploy. Currently, I only see build artifacts being uploaded from the Jenkins task.
I'd say that's the way to go. Your build server is the single point of truth, and only artifacts built in the build server should be deployed.
Does leaving all of this build logic in the task configuration expose us to issues, in the event that the CI server is down?
That one is simple - you shouldn't deploy while your CI server is down. Building on local machine might produce wrong artifacts, which shouldn't be deployed.
What about version control for artifact changes done through the CI interface?
Not sure I understood your question.
I've seen simple Bamboo configurations that specify the build artifacts through the CI server UI, rather than the pom's. Is this just a bad build practice?
This configuration ignores Maven's ability to deploy, and I am not sure I can find a good scenario to justify it. The only thing I can think of is deferred deploy, but Artifactory plugin can take care of that.
Is there a killer tool integration feature that separates one of these approaches from the other?
Now we got to the essence :)
Well, the advantage of defining what you deploy in your build script (in case of Gradle) gives you the flexibility to fine-tuning every aspect of the deployment (think about the dynamic properties you might want to add in certain cases). Another very serious advantage is that your build is source, which means it is versionable in your version control.
The advantage of defining the deployment details in the build server configuration is that the build server is the only place the deployment should occur. So, if you don't have the deployment details in your build script, you know for sure it won't be deployed standalone.
So, how can you combine between the two to get the advantages of both worlds?
Code your deployment logic in your Gradle script using the Artifactory plugin DSL. Provide details like username and password from properties, which exists on build server only.
How useful is the build info object?
Extremely useful. The information in buildInfo was harvested during the build process and the buidInfo is the only place it exists. Having this information is the only option you will be able to reproduce this build in the future.
Is that only available in the Jenkins Artifactory plugin and not the Gradle Artifactory plugin?
'artifactory' and 'artifactory-publish' Gradle plugins both generate the buildInfo object, regardless of where are they running (be it your local machine or Jenkins build server).

Resources