How to make a groovy script list files from a git repo? - github

I need to write a groovy script that talks to git, go to a repository, get the list of file names, store it in an array and return. Then I'll show that in a Jenkins choice parameter.
Is this possible, and if so, how?

If you're going to use pipeline it will be easier.
You can use following to get files from a directory recursively:
import groovy.io.FileType
def fileList = []
def dir = new File("your_repo_dir")
dir.eachFileRecurse (FileType.FILES) { file ->
fileList << file
}
And then in job properties you need to add choice param:
choiceParam(name: 'Repo Files', choices: fileList.join("\n"), description: '')

Use activeChoiceReactiveParam with public Git repository:
parameters {
stringParam {
name('BRANCH_NAME')
defaultValue('master')
description('git branche name')
trim(true)
}
activeChoiceReactiveParam('PLAYBOOK') {
description('Select a playbook')
filterable()
choiceType('SINGLE_SELECT')
groovyScript {
script("""
|def fileList = ['/bin/bash', '-c', "git clone --single-branch --branch " + BRANCH_NAME + " https://git.repository.com/scm/project/repo.git > /dev/null 2>&1 ; cd repo ; git ls-tree -r origin/" + BRANCH_NAME + " --name-only"].execute()
|fileList.waitFor()
|return ["playbook-default.yml"] + fileList.text.readLines().findAll { it.startsWith("playbook").endsWith(".yml") }
""".stripMargin())
fallbackScript('return ["playbook-default.yml"]')
}
referencedParameter('BRANCH_NAME')
}
Note: for now, I didn't manage to use credentials (event with SSH). I could be a good improvement.

If you want to get list of branch from HTTPS GIT URL + Jenkins credential, use this activeChoiceReactiveParam:
activeChoiceReactiveParam('BRANCH_NAME') {
description('Branch from git repo')
filterable()
choiceType('SINGLE_SELECT')
groovyScript {
script("""
|credentialsId = '<TO-REPLACE-WITH-YOUR-CREDENTIAL-ID'
|def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials.class, jenkins.model.Jenkins.instance, null, null ).find{it.id == credentialsId}
|def url = 'https://' + creds.username + ':' + java.net.URLEncoder.encode(creds.password.getPlainText()) + '#bitbucket.url.com/scm/project/repo.git'
|def fileList = ['/bin/bash', '-c', 'rm -rf branch-name > /dev/null 2>&1 ; git clone ' + url + ' branch-name > /dev/null 2>&1 ; cd branch-name ; git for-each-ref --format="%(refname)" --sort -committerdate | sed "s|refs/[a-z]*/||g" | sed "s|origin/||g" '].execute()
|fileList.waitFor()
|return fileList.text.readLines()
|""".stripMargin())
fallbackScript('return ["branch-name-not-found"]')
}
}

Related

Visual Studio Code - how to run `code` command from command?

I try to develop an extension which executes this command
code $(git diff --no-commit-id --name-only -r HEAD) -r
if the user calls the command foo.
This is my extension.ts:
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
let disposable = vscode.commands.registerCommand('git-open-modified-files.foo', () => {
// How can I call my `code $(git diff --no-commit-id --name-only -r HEAD) -r` command here?
vscode.commands.executeCommand('code $(git diff --no-commit-id --name-only -r HEAD) -r'); // does not work
});
context.subscriptions.push(disposable);
}
export function deactivate() {}
vscode.commands.executeCommand is to call a VSC command, you want a shell/terminal command
Use/Try
vscode.commands.executeCommand('workbench.action.terminal.sendSequence', { "text": "code $(git diff --no-commit-id --name-only -r HEAD) -r\u000D" });

How to create a tag for specific branch using Jenkinsfile

I have a scenario i need to build and push docker file only when tag is build from master branch.
stage('Tag') {
when {
expression { sh([returnStdout: true, script: 'echo $TAG_NAME | tr -d \'\n\'']) }
}
steps {
script {
echo "tag"
}
}
}
The above code will work.. If at all we create a tag for the develop branch or the test branch even though when condition is getting satisfied. can anyone help me how to over come this issue.
If it is of any help, this is an except of a sequential Jenkinsfile I use to tag branches on repos. It is a two stage process - find the current commit for the branch and then tag that:
steps.withCredentials([steps.usernamePassword(credentialsId: httpCredentials,
usernameVariable: 'GITHUB_USERNAME', passwordVariable: 'GITHUB_TOKEN')]) {
// Need to do this as a two stage activity (need commit sha) but *warning* this api assumes ref is a branch
def json_info = steps.sh(script: "curl -X GET -H \"Authorization: token \$GITHUB_TOKEN\" -H \"Accept: application/vnd.github.v3+json\" ${httpUrlForHost}/repos/${slugForRepo}/branches/${ref}",
returnStdout: true)
def branch_info = steps.readJSON text: json_info
def sha = branch_info?.commit?.sha
if (!sha) {
steps.error("Unexpected sha for branch ${ref} (${json_info})")
}
def jsonPayload = "{\"ref\":\"refs/tags/${new_tag}\",\"sha\":\"${sha}\"}"
steps.sh "curl -X POST -H \"Authorization: token \$GITHUB_TOKEN\" -H \"Accept: application/vnd.github.v3+json\" -d '${jsonPayload}' ${httpUrlForHost}/repos/${slugForRepo}/git/refs"
}

run my test in docker mongo instance using jenkins pipeline

I would like to run my tests against a Docker MongoDB instance using Jenkins pipeline. I have got it working kind of. My problem is the tests are running within the Mongo container. I just want it to load up a container and my tests for it to connect to the Monogo container. At the moment it downloads Gradle within the container and takes about 5 min to run. Hope that makes sense. Here is my JenkinsFile
#!/usr/bin/env groovy
pipeline {
environment {
SPRING_PROFILES_ACTIVE = "jenkins"
}
agent {
node {
label "jdk8"
}
}
parameters {
choice(choices: 'None\nBuild\nMinor\nMajor', description: '', name: 'RELEASE_TYPE')
string(defaultValue: "refs/heads/master:refs/remotes/origin/master", description: 'gerrit refspec e.g. refs/changes/45/12345/1', name: 'GERRIT_REFSPEC')
choice(choices: 'master\nFETCH_HEAD', description: 'gerrit branch', name: 'GERRIT_BRANCH')
}
stages {
stage("Test") {
stages {
stage("Initialise") {
steps {
println "Running on ${NODE_NAME}, release type: ${params.RELEASE_TYPE}"
println "gerrit refspec: ${params.GERRIT_REFSPEC}, branch: ${params.GERRIT_BRANCH}, event type: ${params.GERRIT_EVENT_TYPE}"
checkout scm
sh 'git log -n 1'
}
}
stage("Verify") {
agent {
dockerfile {
filename 'backend/Dockerfile'
args '-p 27017:27017'
label 'docker-pipeline'
dir './maintenance-notifications'
}
}
steps {
sh './gradlew :maintenance-notifications:backend:clean'
sh './gradlew :maintenance-notifications:backend:check :maintenance-notifications:backend:test'
}
post {
always {
junit 'maintenance-notifications/backend/build/test-results/**/*.xml'
}
}
}
}
}
stage("Release") {
when {
expression {
return params.RELEASE_TYPE != '' && params.RELEASE_TYPE != 'None';
}
}
steps {
script {
def gradleProps = readProperties file: "gradle.properties"
def isCurrentSnapshot = gradleProps.version.endsWith("-SNAPSHOT")
def newVersion = gradleProps.version.replace("-SNAPSHOT", "")
def cleanVersion = newVersion.tokenize(".").collect{it.toInteger()}
if (params.RELEASE_TYPE == 'Build') {
newVersion = "${cleanVersion[0]}.${cleanVersion[1]}.${isCurrentSnapshot ? cleanVersion[2] : cleanVersion[2] + 1}"
} else if (params.RELEASE_TYPE == 'Minor') {
newVersion = "${cleanVersion[0]}.${cleanVersion[1] + 1}.0"
} else if (params.RELEASE_TYPE == 'Major') {
newVersion = "${cleanVersion[0] + 1}.0.0"
}
def newVersionArray = newVersion.tokenize(".").collect{it.toInteger()}
def newSnapshot = "${newVersionArray[0]}.${newVersionArray[1]}.${newVersionArray[2] + 1}-SNAPSHOT"
println "release version: ${newVersion}, snapshot version: ${newSnapshot}"
sh "./gradlew :maintenance-notifications:backend:release -Prelease.useAutomaticVersion=true -Prelease.releaseVersion=${newVersion} -Prelease.newVersion=${newSnapshot}"
}
}
}
}
}
and here is my Dockerfile
FROM centos:centos7
ENV container=docker
RUN mkdir -p /usr/java; curl http://configuration/yum/thecloud/artifacts/java/jdk-8u151-linux-x64.tar.gz|tar zxC /usr/java && ln -s /usr/java/jdk1.8.0_151/bin/j* /usr/bin
RUN mkdir -p /usr/mongodb; curl http://configuration/yum/thecloud/artifacts/mongodb/mongodb-linux-x86_64-3.4.10.tgz|tar zxC /usr/mongodb && ln -s /usr/mongodb/mongodb-linux-x86_64-3.4.10/bin/* /usr/bin
ENV JAVA_HOME /usr/java/jdk1.8.0_151/
ENV SPRING_PROFILES_ACTIVE jenkins
RUN yum -y install git.x86_64 && yum clean all
# Set up directory requirements
RUN mkdir -p /data/db /var/log/mongodb /var/run/mongodb
VOLUME ["/data/db", "/var/log/mongodb"]
# Expose port 27017 from the container to the host
EXPOSE 27017
CMD ["--port", "27017", "--pidfilepath", "/var/run/mongodb/mongod.pid"]
# Start mongodb
ENTRYPOINT /usr/bin/mongod

Yocto build fails due to conflict between recipes

I have two recipes, the first, adduser, is based on the useradd example in the meta-skeleton layer, and creates the directory /home/foo/, for the user foo:
SUMMARY = "Example recipe for using inherit useradd"
DESCRIPTION = "This recipe serves as an example for using features from useradd.bbclass"
SECTION = "examples"
PR = "r1"
LICENSE = "MIT"
S = "${WORKDIR}"
inherit useradd
# You must set USERADD_PACKAGES when you inherit useradd. This
# lists which output packages will include the user/group
# creation code.
USERADD_PACKAGES = "${PN}"
USERADD_PARAM_${PN} = "-d /home/foo -r -s /bin/bash -p 'bar' foo"
do_install () {
install -d -m 755 ${D}/usr/share/foo
install -d -m 755 ${D}/home/foo
chown -R foo ${D}/usr/share/foo
chown -R foo ${D}/home/foo
}
FILES_${PN} = "/usr/share/foo /home/foo"
# Prevents do_package failures with:
# debugsources.list: No such file or directory:
INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
I then have a second recipe, which should add the directory "code" to the user's home directory, and put a file in it:
LICENSE = "CLOSED"
DEPENDS = "adduser"
FILES_${PN} += "/home/foo/code /home/foo/code/base_reading.py"
SRC_URI = "file://base_reading.py \
"
S = "${WORKDIR}"
do_install() {
install -d ${D}/home/foo/code
install -m 0755 ${S}/base_reading.py ${D}/home/foo/code/base_reading.py
chown -R foo ${D}/home/foo/code
}
This is the whole error: https://paste.ubuntu.com/p/6bfH4vf8qw but the TL;DR is:
Error: Transaction check error:
file /home/foo conflicts between attempted installs of basecode-1.0-r0.cortexa7hf_neon_vfpv4 and adduser-1.0-r1.cortexa7hf_neon_vfpv4
At first, I tried to fix this by adding the DEPENDS = "adduser", thinking that that would ensure that /home/foo exists before it tries to create /home/foo/code, but it didn't make any difference.

Jenkins workflow stashing flattened folders

Is it possible to unstash a stashed group of artifacts as a flatten directory like you can do with jenkins archiving?
What I would like it to have 3 folders stashed and only one unstashed with all the contents of the 3, but I can't do it currently.
Here is my try:
echo("Workflow Starting...");
node {
def imageNames = ["connector","registryloader","salepersistence","settlement","standalone","trackingloader"]
stage 'Building
checkout([$class: 'SubversionSCM', additionalCredentials: [], excludedCommitMessages: '', excludedRegions: '', excludedRevprop: '', excludedUsers: '', filterChangelog: false, ignoreDirPropChanges: false, includedRegions: '', locations: [[credentialsId: '36c9ca9f-de25-4022-b9eb-70ada8e793b8', depthOption: 'infinity', ignoreExternalsOption: true, local: '.', remote: 'http://10.64.111.28/svn/SampleProject/skl-br']], workspaceUpdater: [$class: 'UpdateUpdater']])
withEnv(["PATH+MAVEN=${tool 'M3'}/bin"]) {
bat "mvn clean install assembly:assembly versions:resolve-ranges -Dmaven.test.skip=false -DskipTests"
}
echo("Archiving")
archive '**/target/*.tar.gz, conf/desenv/**/*'
for(int i = 0; i < imageNames.size(); i++){
String imageName = imageNames[i]
echo("Stashing ${imageName}")
stash excludes: '', includes: '**/sklbr-1.0.0-standalone.tar.gz, **/'+imageName+'/*, **/commonConfigs/*, **/scripts/*', name: ''+imageName+''
}
stage 'Creating Container'
docker.withServer('tcp://localhost:2375')
{
for(int i = 0; i < imageNames.size(); i++){
String imageName = imageNames[i]
ws('sub-workspace ' + imageName) {
echo("Creating ${imageName} container")
//unarchive mapping: ['**/sklbr-1.0.0-standalone.tar.gz' : '.', '**/${imageName}/*' : '.', '**/commonConfigs/*' : '.', '**/scripts/*' : '.']
unstash imageName
echo("Unstashing ${imageName}")
def newApp = docker.build "devops-docker-registry:5000/"+imageName+":${env.BUILD_NUMBER}-${env.SVN_REVISION}"
echo("Building container with ${imageName}")
newApp.push()
echo("Pushing ${imageName} container")
}
}
}
}
Well I've found a way using shell script, but that is not what I was looking for...
Here it is in case you need it
*Nix
sh 'find /${pwd()} -iname "*" -print0 | xargs -0 echo mv -t a'
Windows
bat 'for /r %f in (*) do #move "%f" .'
JENKINS-29780 may be helpful, but remember you can wrap stash and/or unstash in dir.