The Jenkins Git Plugin Starts Multiple Builds For The Same Branch

This post describes a workaround for a Jenkins Git plugin bug that triggered duplicate builds when polling multiple branches with wildcards. It provides a Perl script that compares commit hashes and uses the Jenkins REST API to trigger only genuinely changed branches.

Coveros Staff

November 19, 2014

On my current project, we have recently moved to a CI infrastructure that poll and build from multiple branches — using a wildcard. We noticed with the version of the Git plugin we were using, there was a known bug that would kick off multiple builds when polling from multiple branches. This wouldn’t be a big deal except our resources are very constrained, and it would sometimes kick off 5 builds for the same branch all within a second of each other. In order to correct this issue, I created a simple perl script and a Jenkins job, to call the perl script. The logic of the perl script is simple. It compares hashes and uses the REST API to call a Jenkins job.

#!/usr/bin/perl
`git fetch --all`;
@branches = `git branch -a | grep "remotes/origin/Prefix-*"`;

#open file to read
open (INPUT, '<DIR/hash.txt');

#read file
%currentHashes=();
while (<INPUT>){
     my($line) = $_;
     chomp($line);
     @values = split(',', $line);
     $currentHashes{"$values[0]"} = "$values[1]";
}

#open file to write
open (OUTPUT, '>DIR/hash.txt');
foreach $branch (@branches){
     chomp($branch);
     $commit = `git log -n 1 --pretty=format:'%H' $branch`;
     $newHashes{"$branch"} = "$commit";
     print OUTPUT "$branch,$commit\n";
}

foreach $key (keys %newHashes){
     if($newHashes{$key} eq $currentHashes{$key}){
          print "the hashes are the same for branch:$key \n";
     }else{
          print "the hashes are different for branch:$key \n";
          #remove spaces
          $key =~ s/^[ ]*//g;
          #remove remotes/origin
          $key =~ s/remotes\/origin\/*//g;
          #call jenkins job through rest api
          `curl -X POST \"{JENKINS_IP}/job/{SPECIFIC JOB}/buildWithParameters?&GIT_BRANCH_NAME=$key\"`;
     }
}

#close files
close (INPUT);
close (OUTPUT);

The corresponding Jenkins job would then need to be a parameterized build that includes the parameter GIT_BRANCH_NAME, for more information on the corresponding Jenkins job, please see the next blog.

Coveros Staff

Coveros Staff

This post represents the collective insights of the Coveros team. Our staff consists of software experts who bring deep experience in secure agile development, DevOps, testing, and software quality. Over the past 20 years, Coveros has trained more than 30,000 professionals and worked with half of the Fortune 100 companies on mission-critical software development challenges. We draw on this extensive experience to share practical insights, proven strategies, and real-world solutions that help organizations build better software faster and more securely.