How to convince jenkins to share a build number fo

2020-03-01 17:22发布

I do have a requirement from the development team to setup the build system so each build will have an unique build number for all branches.

The builds are made by jenkins using jobs for each branch.

There is a jenkins plugin that can setup the next buildnumber for a job but this is kinda useless for at least two reasons:

  • it will set the build number for a single job and you cannot know all how to setup it for all branches because they can be removed or added at any time
  • it doesn't set it for current build

How to we get the build numbers: we do make a HTTP call with the branch name and the revision number in git/mercurial. Based on this the centralized sever is giving us a build number as a response. If you call it twice with the same parameters, you will get the same response (desired behaviour).

Now, how can we tweak jenkins to use the same build numbers as us? Obviously I could use the build number returned from the script, but the job number would be different and I doubt jenkins will know that I touched the BUILD_NUMBER variable inside my script.

Mainly, what I need is some kind of pre-job-start script that I can run, one that would run before the build number is assigned to the job.

3条回答
Lonely孤独者°
2楼-- · 2020-03-01 17:31

You can use the Environment Injector Plugin to evaluate a Groovy script before your run. I have almost the same requirement, however for me, only the jobs with the same job_prefix_ in their name share the same unique nextBuildNumber (in other words, other jobs with job_prefix2_ in their name share a different nextBuildNumber).

In the Evaluated Groovy Script section, please use:

import jenkins.model.*

// Access to the Jenkins instance
jenkins_instance = jenkins.model.Jenkins.instance

// Select jobs that match.
job_name = "^job_prefix_.*"
allItems = jenkins_instance.items
chosenJobs = allItems.findAll{ job -> job.name.matches(job_name) }

// Get the max
build_number = chosenJobs.collect{ it -> it.nextBuildNumber }.max()

// Increase next build number
currentJob.nextBuildNumber = build_number + 1

// and use it.
def map = [BUILD_NUMBER: build_number]
return map
查看更多
一纸荒年 Trace。
3楼-- · 2020-03-01 17:40

I took dnozay's answer, but at least for Jenkins 1.586, this doesn't work quite well for me. Here are the problems I had:

  1. The build number in Jenkins build history is different from BUILD_NUMBER variable I use in the job. It appears that setting BUILD_NUMBER at this point, even if Override Build Parameters is set, is too late.
  2. The next build number will be current + 2, instead of current + 1. I think that is because the nextBuildNumber is incremented both by this script and Jenkins.

So here is an updated version based on his answer:

import jenkins.model.*

// Access to the Jenkins instance
jenkinsInstance = jenkins.model.Jenkins.instance

// Select jobs that match.
jobName = "^job_prefix.*"
allItems = jenkinsInstance.items
chosenJobs = allItems.findAll{ job -> job.name.matches(jobName) }

// Get the max
buildNumber = chosenJobs.collect{ job -> job.nextBuildNumber }.max()

// Increase next build number for all matching jobs
chosenJobs.each{ job -> job.updateNextBuildNumber(buildNumber) }

return [:]

Again, all credit goes to dnzay for the original script.

Edit: when creating new jobs, an old one has to be run before running the new ones, otherwise they will start with 1.

查看更多
太酷不给撩
4楼-- · 2020-03-01 17:53

Check out the Build Name Setter Plugin and Description Setter Plugin. They use RegEx and/or variables to set build properties after the build, based on the build output.

For example, you could use this RegEx:

At revision (\d)+

and this replacement string

Build number is ${BUILD_NUMBER}; Subversion revision \1 

you can set the build's description.

If your replacement string does not contain something unique to a build (e.g., ${BUILD_NUMBER}), I suggest that you don't change the build name because there could be several builds for the same repository revision.


Now, how to get several jobs built on the same repository revision is another thing! It seems that parameterized builds can be started via an HTTP POST. So, you could have a job that gets triggered by an SCM change and uses an HTTP tool (e.g., wget) to schedule each parameterized job.

查看更多
登录 后发表回答