Reputation: 703
I am trying to make a Parameterized build
in Jenkins. In this way user can choose the git branch he/she wants to deploy from a cascade menu.
There are two possible ways:
Writing branch names in file and configuring Jenkins to read this file (project configuration > extend choice parameter and selecting Property file
).
Problem : You have to make a local repository as a mirror of remote repo and keep this local repo in sync with remote repo. In the other words, you have to update the file containing the available branch name updated. This needs a scheduled job by cron and I am not allowed using this approach.
Using Groovy script (project configuration > extend choice parameter and selecting "Groovy script"
). Then you need a groovy script to retrieve the branch name as follows: branches=master,feature/Feature-1,feature/Feature-2,hotfix/Hotfix-1,release/Release-1
.
I found a groovy script in here but it doesn't work. I have installed groovy on my machine.
Can anybody help me? To make the story short: I need a groovy script which returns the available branch names of a remote repository.
Upvotes: 15
Views: 57272
Reputation: 3690
This approach describe the settings required to compose a Jenkins pipeline that "polls" (list) dynamically all branches of a particular repository, which then lets the user run the pipeline with some specific branch when running a build of this job.
The assumptions here are:
First thing to do is to provide Jenkins credentials to connect (and "fetch") to the private repository in BitBucket. This can be done by creating an SSH key pair to "link" between the Jenkins (!!) user on the machine that hosts the Jenkins server and the (private) BitBucket repository.
First thing is to create an SSH key to the Jenkins user (which is the user that runs the Jenkins server - it is most likely created by default upon the installation):
guya@ubuntu_jenkins:~$ sudo su jenkins
[sudo] password for guya:
jenkins@ubuntu_jenkins:/home/guya$ ssh-keygen
The output should look similar to the following:
Generating public/private rsa key pair. Enter file in which to save the key
(/var/lib/jenkins/.ssh/id_rsa): Created directory '/var/lib/jenkins/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /var/lib/jenkins/.ssh/id_rsa. Your public key has been saved in /var/lib/jenkins/.ssh/id_rsa.pub. The key fingerprint is: SHA256:q6PfEthg+74QFwO+esLbOtKbwLG1dhtMLfxIVSN8fQY jenkins@ubuntu_jenkins The key's randomart image is: +---[RSA 2048]----+ | . .. o.E. | | . . .o... o | | . o.. o | | +.oo | | . ooX..S | |..+.Bo* . | |.++oo* o. | |..+*..*o | | .=+o==+. | +----[SHA256]-----+ jenkins@ubuntu_jenkins:/home/guya$
Settings --> Access keys --> Add key
.cat /var/lib/jenkins/.ssh/id_rsa.pub
jenkins
this "privilege".This can be done by adding a new SSH User name with private key to the Jenkins --> Credentials --> System --> Global Credentials --> Add credentials
.
jenkins
.~/.ssh/id_rsa
. This is the private key which start with the string:-----BEGIN RSA PRIVATE KEY-----
and ends with the string: -----END RSA PRIVATE KEY-----
. Note that this entire "block" should be copied-paste into the above section.Install the Git Parameter plugin that can be found in its official page here
The very minimum pipeline that is required to list (dynamically) all the branches of a given repository is as follows:
pipeline
{
agent any parameters
{
gitParameter branchFilter: 'origin/(.*)', defaultValue: 'master', name: 'BRANCH', type: 'PT_BRANCH'
}
stages
{
stage("list all branches")
{
steps
{
git branch: "${params.BRANCH}", credentialsId: "SSH_user_name_with_private_key", url: "ssh://[email protected]:port/myRepository.git"
}
}
}
}
NOTES:
defaultValue
is set to master
so that if no branches exist - it will be displayed in the "drop list" of the pipeline.credentialsId
has the name of the credentials configured earlier.Upvotes: 1
Reputation: 461
I was following this https://stackoverflow.com/a/47880463/11951486 , and it is working perfectly fine. But the issue is, now github will disable using access_token in the url, more detail can be found here
So i changed the groovy script to use curl with username and token or password
Please find the code below for repos.
import groovy.json.JsonSlurper;
try{
def user = "<username>"
def tokenId = "<tokenid>"
def url = "https://api.github.com/user/repos?per_page=200"
def command = "curl -u $user:$tokenId $url"
List<String>params = new ArrayList<String>()
apiUrl = command.execute().text
List json = new JsonSlurper().parseText(apiUrl)
for (repo in json ) {
params.add(repo.name)
}
return params
}
catch(IOException ex){
print ex
}
Please find below code for the branches
import groovy.json.JsonSlurper;
try{
def user = "<username>"
def tokenId = "<tokenID>"
def url = "https://api.github.com/repos/<org_name>/${REPO}/branches?per_page=400"
def command = "curl -u $user:$tokenId $url"
List<String>params = new ArrayList<String>()
apiUrl = command.execute().text
List json = new JsonSlurper().parseText(apiUrl)
for (branch in json ) {
params.add(branch.name)
}
params.add(0, 'master:selected')// this is for default select master branch
return params
}
catch(IOException ex){
print ex
}
${REPO} = This is the parameter name for listing the repos, so based on the repo you selected , the above code will list the branches.
Upvotes: 1
Reputation: 1280
This was the only technique I came up with that doesn't require you to dig git repo information out of the workspace. This uses Groovy code to inspect the job parameters for the Git URI, and then shells out to git
to do the rest of the work.
It should be possible to use JGit to access the repository in native Groovy way, but I can't figure it out.
import jenkins.*
import jenkins.model.*
import hudson.*
import hudson.model.*
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.URIish;
def build = Thread.currentThread().toString()
def regexp= ".+?/job/([^/]+)/.*"
def match = build =~ regexp
def jobName = match[0][1]
def job = Jenkins.instance.getJob(jobName)
def workspace = job.lastBuild.workspace
for(project in Hudson.instance.items) {
scm = job.scm;
if (scm instanceof hudson.plugins.git.GitSCM) {
for (RemoteConfig cfg : scm.getRepositories()) {
for (URIish uri : cfg.getURIs()) {
gitUri = uri
}
}
}
}
def branchlist = ["/bin/bash", "-c", "git ls-remote --heads ${gitUri}"].execute() | ["/bin/bash", "-c", "cut -f2"].execute()
branchlist.waitFor()
return branchlist.in.text.readLines()
Set that as the Groovy Script for your Source for Value on an Extended Choice Parameter like this:
And then you'll be able to select from a list of branches as build parameters:
Upvotes: 0
Reputation: 791
Try Using
Use the following steps:
Add an extensible choice parameter to your job
select System Groovy Choice parameter in Choice parameter field
Place the following script in Groovy script text box and replace the place holders "< >" with required values.
import groovy.json.JsonSlurper;
try{
List<String>params = new ArrayList<String>()
URL apiUrl = "https://api.github.com/users/<repo-owner>/repos?access_token=<github-access-token>".toURL()
List branches = new JsonSlurper().parse(apiUrl.newReader())
for (branch in branches ) {
params.add(branch.name)
}
return params
}
catch(IOException ex){
print ex
}
Add an active choice reactive parameter to your job
Place Reference Parameter as repository and following script in Groovy Script text box
import groovy.json.JsonSlurper;
try{
List<String>params = new ArrayList<String>()
URL apiUrl = "https://api.github.com/repos/<repo-owner>/$repository/branches?access_token=<github-access-token>".toURL()
List json = new JsonSlurper().parse(apiUrl.newReader())
for (repo in json ) {
params.add(repo.name)
}
return params
}
catch(IOException ex){
print ex
}
Note:
$repository
takes dynamic value from repository parameter.Now try build job with parameter
checkout github api docs for more informations. Hope this yould be helpful..!! ;-)
Upvotes: 6
Reputation: 16971
You can use Extensible Choice Parameter plugin to retrieve Git branches of your cloned repository. To do so, add to Master-Node property an environment variable of .git directory path, e.g.:
Then add an Extensible Choice parameter with the following groovy script (and check "Use predefined variables"):
def envVars = jenkins.getNodeProperties()[0].getEnvVars()
def NODE_PROJECT_PATH = envVars.get('NODE_PROJECT_PATH')
def gettags = "git ls-remote -t --heads origin".execute(null, new File(NODE_PROJECT_PATH))
return gettags.text.readLines()
.collect { it.split()[1].replaceAll('\\^\\{\\}', '').replaceAll('refs/\\w+/', '') }
.unique()
.findAll { !it.startsWith('Branch_') }
That should list your branches (I filtered out all "Branch_*" from the list):
Notes: In case you see nothing when validating the script (with "Run the script now" button), it's probably due to required user/password prompt - so initially run "git ls-remote -t --heads origin" in .git directory. To save credential on Windows, try to run "git config --global credential.helper wincred".
Upvotes: 2
Reputation: 31161
You don't need a Groovy Script for this. The Git Parameter Plugin lets you add git branches as a parameter.
Upvotes: 4
Reputation: 2789
The script below should be helpful. It's based on the scripts from linked question. It filters git command output with simple regular expression and creates list of branch names for specified git repository. Tested on grails-core github repo:
def gitURL = "https://github.com/grails/grails-core.git"
def command = "git ls-remote -h $gitURL"
def proc = command.execute()
proc.waitFor()
if ( proc.exitValue() != 0 ) {
println "Error, ${proc.err.text}"
System.exit(-1)
}
def branches = proc.in.text.readLines().collect {
it.replaceAll(/[a-z0-9]*\trefs\/heads\//, '')
}
println branches
Upvotes: 16