10

Each commit to my git repo triggers a build of my Jenkins pipeline.

I want to retrieve the buildNumber of an old build by commit hash. How can I do that?

I know this information exists because I can find it in the UI.


Some background as to why I want this: When someone tags a commit I want to create a release (by tagging a docker image). Each build will push an image containing the build number. So I want to find out which build number corresponds to that commit so that I can find the image that I want to release.

herm
  • 14,613
  • 7
  • 41
  • 62

5 Answers5

6

Install Lucene plugin https://wiki.jenkins.io/display/JENKINS/Lucene-Search and you will be able to search by commit hash just via default Jenkins search bar! (but read plugin docs, for old builds to be searchable you need to rebuild database)

If you want to do it programatically you can use jenkins api, for example http://jenkinsapi.readthedocs.io/en/latest/using_jenkinsapi.html#example-5-getting-version-information-from-a-completed-build

Just modify function in example not to get latest successful build, but to get all builds and get their git hashes then filter this set.

ka4eli
  • 5,294
  • 3
  • 23
  • 43
  • Thanks for your answer. I'm sure this can be helpfull to manually find an old build. I need to access this information programatically (not in UI) can this be done with lucene? – herm Oct 06 '17 at 06:16
3

Based on @akostadinov bit I poked around and found build number and other goodies but not GIT_COMMIT.

Maybe this would be useful to someone else so thought I would share what I found.

Open your admin script console with http://yourjenkins:8080/script and check it out for yourself.

def job = hudson.model.Hudson.instance.getItem("Foo Project")
def builds = job.getBuilds()

def thisBuild = builds[0]
def fourBuildsAgo = builds[4] 

println('env' + builds[0].getEnvironment().keySet() )
println('each job has previous job e.g "' + thisBuild.getPreviousBuild() + '"')

fourBuildsAgo.getChangeSets().each {
  println('Num of commits in this build ' + (it.getLogs()).size() )

  it.getLogs().each {
     println('commit data : '  + it.getRevision() + ' ' + it.getAuthor() + ' ' + it.getMsg()) 
  }
}

I used this GitChangeSet API to poke around at the methods in groovy.

This code will fetch and display the commit hashes of each commit 4 builds ago. you can format your currentBuild.description with this text if you want and it will show on your status page.

This resulted in output ( real commit details hidden )

each job has previous job e.g "Foo Project #191"
Num of commits in this build 8
commit data : 288f0e7d3664045bcd0618aacf32841416519d92 user1 fixing the build  
commit data : b752ee12b3d804f9a674314bef4de5942d9e02f5 user2 Fix handling to the library foo
commit data : 9067fd040199abe32d75467734a7a4d0d9b6e8b2 user2 Implemented Foo Class
...
...
...
Peter Moore
  • 1,632
  • 1
  • 17
  • 31
  • but it's does show the HEAD commit if it's a merge commit – Abdennour TOUMI Aug 11 '21 at 23:17
  • nothing resembling git like commits come out for me. The entire keyset is `BUILD_DISPLAY_NAME BUILD_ID BUILD_NUMBER BUILD_TAG BUILD_URL CLASSPATH HUDSON_HOME HUDSON_SERVER_COOKIE HUDSON_URL JENKINS_HOME JENKINS_SERVER_COOKIE JENKINS_URL JOB_BASE_NAME JOB_DISPLAY_URL JOB_NAME JOB_URL LD_LIBRARY_PATH RUN_ARTIFACTS_DISPLAY_URL RUN_CHANGES_DISPLAY_URL RUN_DISPLAY_URL RUN_TESTS_DISPLAY_URL TEST_TIMEOUT TMPDIR` .. All commits are rebased. So some plugin aint working for me. – Peter Moore Aug 12 '21 at 22:22
  • without pluguns, see my answer (not comment) above or below ! – Abdennour TOUMI Aug 13 '21 at 07:36
  • 1
    without plugins? git is a plugin ! – Peter Moore Aug 13 '21 at 15:54
  • This method is not working for me. The thisBuild.getChangeSets() size is zero for me. – Ganesh Chowdhary Sadanala Feb 03 '22 at 08:03
  • make sure the name of the job is correct `hudson.model.Hudson.instance.getItem("Foo Project")` needs to exist. If it does then `job.getBuilds()` must be returning no builds. @GeneshChowdharySadanala – Peter Moore Feb 09 '22 at 12:41
0

If you want to get commit IDs for builds you can use groovy script like:

    def job = hudson.model.Hudson.instance.getItem("My Job Name")
    def builds = job.getBuilds()

Then for each git repo you are cloning, you can get revision by

    println('last build ' + builds[0].getEnvironment()["GIT_COMMIT"])
    println('2st last build ' + builds[1].getEnvironment()["GIT_COMMIT_4"])

For declarative pipelines see https://stackoverflow.com/a/49251515/520567

akostadinov
  • 17,364
  • 6
  • 77
  • 85
  • I like this example as it illustrates how to get to the build info for each build of a job. However the GIT_COMMIT var is not defined in the current jenkins build 2.207. – Peter Moore Dec 03 '19 at 22:12
  • @PeterMoore, I would guess it depends on the git SCM plugin. I doubt it depends on jeknins version. Are you sure it is missing? – akostadinov Dec 03 '19 at 23:21
  • Yep `builds[0].getEnvironment().keySet()` comes back with `env[BUILD_DISPLAY_NAME, BUILD_ID, BUILD_NUMBER, BUILD_TAG, BUILD_URL, CLASSPATH, HUDSON_HOME, HUDSON_SERVER_COOKIE, HUDSON_URL, JENKINS_HOME, JENKINS_SERVER_COOKIE, JENKINS_URL, JOB_BASE_NAME, JOB_DISPLAY_URL, JOB_NAME, JOB_URL, LD_LIBRARY_PATH, RUN_CHANGES_DISPLAY_URL, RUN_DISPLAY_URL, TEST_TIMEOUT, TMPDIR]` but i got another way... Ill post it to the tread soon. PS im using the standard git plugin for pipelines – Peter Moore Dec 03 '19 at 23:55
  • In the job I'm reading builds from, I'm using `Multiple SCMs`. So there might be a difference. +1 for ` GitChangeSet API`. – akostadinov Dec 04 '19 at 18:25
  • No GIT_COMMIT environment varibale found. – Ganesh Chowdhary Sadanala Feb 03 '22 at 08:11
-1

If I understand your question correctly, then you will first need to create a git hook to trigger a new build. This part is covered in the answer How do I react to new tags in git hooks?', though if you are using something like GitHub, BitBucket or Gitlab, then there may be other ways of going about it.

Then when the build is initiated, then there is build number which is provided as the variable 'BUILD_NUMBER' ,in Jenkins. If you want to include the git tag name, so you can use it in a script, then there seems to be a fews ways:

Typically these plugins will create an environment variable that can be consumed by your scripts. I am not providing more concrete examples, since I am not aware of your exact tooling.

Andre M
  • 6,649
  • 7
  • 52
  • 93
  • Sorry if my question was unclear. I have one build per commit (triggered by a hook). I want to get the number of the build which was triggered by commit X. – herm Aug 21 '17 at 15:46
  • That's in the second paragraph. Look at the 'BUILD_NUMBER' variable. – Andre M Aug 21 '17 at 17:15
  • Thank you for your input. Unfortunately its not what I asked for. I don't want to trigger a build on taging as the version of my build pipeline (shared groovy pipeline) might have changed and be incompatible with the jenkinsfile and will also have other effects (deployments) that I don't want to bother with. I really just want to find out which jenkins build (from the history) is the one that lists the taged commit in its summary – herm Aug 22 '17 at 07:05
-1
build.actions.find { action -> action instanceof jenkins.scm.api.SCMRevisionAction }?.revision?.hash;

ref & credits: https://gist.github.com/ftclausen/8c46195ee56e48e4d01cbfab19c41fc0

Abdennour TOUMI
  • 87,526
  • 38
  • 249
  • 254