├── .gitignore ├── .travis.yml ├── Jenkinsfile ├── README.md ├── build.gradle ├── exampleJobs └── parallel │ └── Jenkinsfile ├── gradlew ├── gradlew.bat ├── pipelineTests └── groovy │ ├── testSupport │ ├── PipelineSpockTestBase.groovy │ ├── PipelineTestHelper.groovy │ └── WhenExitException.groovy │ └── tests │ ├── callstacks │ ├── JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_false_gradle_build test.txt │ ├── JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_null_gradle_null.txt │ ├── JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_true_gradle_test.txt │ └── ParallelJobTestSpec_Parallel_Jenkinsfile_should_complete_with_success.txt │ └── library │ ├── analyzeWithSonarTestSpec.groovy │ ├── getJiraIssueTestSpec.groovy │ ├── gradleBuildTestSpec.groovy │ ├── mavenBuildTestSpec.groovy │ ├── postmessageTestSpec.groovy │ └── runAppLocallyTestSpec.groovy ├── src └── org │ └── ldop │ ├── DockerHubHelper.groovy │ ├── DockerHubHelper.txt │ ├── NexusMavenArtifactHelper.groovy │ └── NexusMavenArtifactHelper.txt └── vars ├── AddProductToManifest.groovy ├── AddProductToManifest.txt ├── DeployToBluemix.groovy ├── DeployToBluemix.txt ├── analyzeWithSonar.groovy ├── analyzeWithSonar.txt ├── bumpVersion.groovy ├── bumpVersion.txt ├── deployContainerToEnv.groovy ├── deployContainerToEnv.txt ├── deployHelmChartOpenshift.groovy ├── deployToEnvironment.groovy ├── deployToEnvironment.txt ├── doesVersionExist.groovy ├── doesVersionExist.txt ├── failIfVersionExists.groovy ├── failIfVersionExists.txt ├── formatSlackOutput.groovy ├── formatSlackOutput.txt ├── getArtifact.groovy ├── getArtifact.txt ├── getJiraIssue.groovy ├── getJiraIssue.txt ├── getLatestVersion.groovy ├── getLatestVersion.txt ├── getNexusMavenArtifact.groovy ├── getNexusMavenArtifact.txt ├── getVersionFromContainer.groovy ├── getVersionFromContainer.txt ├── gradleBuild.groovy ├── gradleBuild.txt ├── gradleBuildAndDeploy.groovy ├── gradleBuildAndDeploy.txt ├── mavenBuild.groovy ├── mavenBuild.txt ├── mavenBuildAndDeploy.groovy ├── mavenBuildAndDeploy.txt ├── mavenJxBuild.groovy ├── postMessage.groovy ├── postMessage.txt ├── promoteJx.groovy ├── publishHelmChartArtifactory.groovy ├── pushContainerToArtifactory.groovy ├── pushContainerToArtifactory.txt ├── runAppLocally.groovy ├── runAppLocally.txt ├── sendBuildEvent.groovy ├── sendHealthyEvent.groovy ├── sendUnhealthyEvent.groovy ├── skaffoldBuild.groovy ├── testSuite.groovy └── testSuite.txt /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | **/*.iml 3 | **/.idea 4 | **/.gradle -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | install: gradle wrapper --gradle-version 4.2 2 | language: groovy 3 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent any 3 | stages { 4 | stage('Run Shared Library Tests') { 5 | agent { 6 | docker { 7 | image 'gradle:4.6' 8 | } 9 | } 10 | steps { 11 | sh 'gradle clean test' 12 | } 13 | } 14 | } 15 | post { 16 | failure { 17 | hipchatSend color: 'RED', notify: true, v2enabled: true, message: "Pipeline failed at stage: ${STAGE}. Click to view changelist." 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pipeline Library 2 | Shared library with unit tests to be used with Jenkins pipelines. 3 | [![Build Status](https://travis-ci.org/liatrio/pipeline-library.svg?branch=master)](https://travis-ci.org/liatrio/pipeline-library) 4 | 5 | 6 | 7 | #### Run Pipeline Library Tests Locally For Development Purposes 8 | ``` 9 | git clone https://github.com/liatrio/pipeline-library.git 10 | gradle clean test 11 | ``` 12 | ### Testing 13 | Uses com.lesfurets.jenkins.unit.RegressionTest to test the shared libraries with spock. 14 | 15 | 16 | 17 | #### Shared Library Methods 18 | * [Analyze With Sonar](vars/analyzeWithSonar.groovy) 19 | * [Deploy container to Environment](vars/deployContainerToEnv.groovy) 20 | * [Get Jira Issue](vars/getJiraIssue.groovy) 21 | * [Gradle Build](vars/gradleBuild.groovy) 22 | * [Gradle Build And Deploy](vars/gradleBuildAndDeploy.groovy) 23 | * [Maven Build](vars/mavenBuild.groovy) 24 | * [Maven Build and Deploy](vars/mavenBuildAndDeploy.groovy) 25 | * [Push Container to Artifactory](vars/pushContainerToArtifactory.groovy) 26 | * [Run App Locally](vars/runAppLocally.groovy) 27 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'groovy' 2 | repositories { 3 | mavenCentral() 4 | } 5 | 6 | dependencies { 7 | compile 'org.codehaus.groovy:groovy-all:2.4.11' 8 | 9 | /** 10 | * JenkinsPipelineUnit for testing pipelines from: 11 | * https://github.com/lesfurets/JenkinsPipelineUnit 12 | */ 13 | testCompile 'com.lesfurets:jenkins-pipeline-unit:1.1' 14 | 15 | /** 16 | * For Spock unit tests 17 | */ 18 | testCompile 'org.spockframework:spock-core:1.1-groovy-2.4' 19 | testCompile 'cglib:cglib-nodep:3.2.2' 20 | testCompile 'org.objenesis:objenesis:1.2' 21 | testCompile 'org.assertj:assertj-core:3.7.0' 22 | 23 | } 24 | test { 25 | systemProperty "pipeline.stack.write", System.properties["pipeline.stack.write"] 26 | } 27 | 28 | sourceSets { 29 | 30 | test { 31 | groovy { 32 | srcDirs= ['pipelineTests/groovy'] 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /exampleJobs/parallel/Jenkinsfile: -------------------------------------------------------------------------------- 1 | /** 2 | * A pipeline to demo running parallel branches using both a dynamic and static coding method. 3 | * 4 | * In the Blue Ocean GUI, a dynamic construction might be better so as not to show parallel 5 | * branches that are skipped in the graphic representation of a run. 6 | */ 7 | 8 | /** 9 | * A map of parallel runs built dynamically in the job. It is a map of closures 10 | */ 11 | def parallelCodeMap = [:] 12 | 13 | /** 14 | * Declarative pipeline 15 | */ 16 | pipeline { 17 | 18 | agent any 19 | 20 | stages { 21 | 22 | stage('Setup') { 23 | 24 | steps { 25 | 26 | // Set up the dynamic parallel code map 27 | script { 28 | 29 | parallelCodeMap['foo'] = { 30 | echo "Running foo branch.." 31 | } 32 | 33 | parallelCodeMap['bar'] = { 34 | echo "Running bar branch..." 35 | } 36 | } 37 | } 38 | } 39 | 40 | stage('Dynamic') { 41 | steps { 42 | script { 43 | parallel( parallelCodeMap ) 44 | } 45 | } 46 | } 47 | 48 | // Pre pipeline v1.2 do it this way, awkward syntax 49 | stage('Static Old Way') { 50 | steps { 51 | parallel ( 52 | 'branch_1' : { 53 | echo "Running static branch 1" 54 | }, 55 | 'branch_2' : { 56 | echo "Running static branch 2" 57 | }, 58 | ) 59 | } 60 | } 61 | 62 | // From pipeline v1.2 do it this way : requires Pipeline Model Definition Plugin v1.2+ 63 | stage('Static New Way') { 64 | 65 | // Support for full parallel stages. Nice. 66 | parallel { 67 | 68 | stage('Stage 1') { 69 | steps { 70 | echo "Running pipeline v1.2 static stage 1" 71 | } 72 | } 73 | 74 | stage('Stage 2') { 75 | steps { 76 | echo "Running pipeline v1.2 static stage 2" 77 | } 78 | } 79 | 80 | stage('Stage Skipped') { 81 | 82 | when { expression { false } } 83 | 84 | steps { 85 | echo "pipeline v1.2 static stage will be skipped" 86 | } 87 | } 88 | } 89 | } 90 | } 91 | } -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /pipelineTests/groovy/testSupport/PipelineSpockTestBase.groovy: -------------------------------------------------------------------------------- 1 | package testSupport 2 | 3 | import com.lesfurets.jenkins.unit.RegressionTest 4 | import spock.lang.Specification 5 | 6 | class PipelineSpockTestBase extends Specification implements RegressionTest { 7 | 8 | @Delegate PipelineTestHelper pipelineTestHelper 9 | def setup() { 10 | callStackPath = 'pipelineTests/groovy/tests/callstacks/' 11 | pipelineTestHelper = new PipelineTestHelper() 12 | pipelineTestHelper.setUp() 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /pipelineTests/groovy/testSupport/PipelineTestHelper.groovy: -------------------------------------------------------------------------------- 1 | package testSupport 2 | 3 | import com.lesfurets.jenkins.unit.BasePipelineTest 4 | import static com.lesfurets.jenkins.unit.MethodSignature.method 5 | 6 | 7 | class PipelineTestHelper extends BasePipelineTest { 8 | 9 | /** 10 | * Override the setup for our purposes 11 | */ 12 | @Override 13 | void setUp() { 14 | 15 | // Scripts (Jenkinsfiles etc) loaded from root of project directory and have no extension by default 16 | helper.scriptRoots = [''] 17 | helper.scriptExtension = '' 18 | 19 | // Add support to the helper to unregister a method 20 | helper.metaClass.unRegisterAllowedMethod = { String name, List args -> 21 | allowedMethodCallbacks.remove(method(name, args.toArray(new Class[args.size()]))) 22 | } 23 | 24 | // Setup the parent stuff 25 | super.setUp() 26 | 27 | // Declaring all my stuff 28 | registerDeclarativeMethods() 29 | registerScriptedMethods() 30 | setJobVariables() 31 | } 32 | 33 | /** 34 | * Declarative pipeline methods not in the base 35 | * 36 | * See here: 37 | * https://www.cloudbees.com/sites/default/files/declarative-pipeline-refcard.pdf 38 | */ 39 | void registerDeclarativeMethods() { 40 | 41 | // For execution of the pipeline 42 | helper.registerAllowedMethod('execute', [], {}) 43 | helper.registerAllowedMethod('pipeline', [Closure.class], null) 44 | helper.registerAllowedMethod('options', [Closure.class], null) 45 | 46 | // Handle endvironment section adding the env vars 47 | helper.registerAllowedMethod('environment', [Closure.class], { Closure c -> 48 | 49 | def envBefore = [env: binding.getVariable('env')] 50 | println "Env section - original env vars: ${envBefore.toString()}" 51 | c.resolveStrategy = Closure.DELEGATE_FIRST 52 | c.delegate = envBefore 53 | c() 54 | 55 | def envNew = envBefore.env 56 | envBefore.each { k, v -> 57 | if (k != 'env') { 58 | envNew["$k"] = v 59 | } 60 | 61 | } 62 | println "Env section - env vars set to: ${envNew.toString()}" 63 | binding.setVariable('env', envNew) 64 | }) 65 | 66 | // Handle parameters section adding the default params 67 | helper.registerAllowedMethod('parameters', [Closure.class], { Closure parametersBody -> 68 | 69 | // Register the contained elements 70 | helper.registerAllowedMethod('string', [Map.class], { Map stringParam -> 71 | 72 | // Add the param default for a string 73 | addParam(stringParam.name, stringParam.defaultValue) 74 | 75 | }) 76 | helper.registerAllowedMethod('booleanParam', [Map.class], { Map boolParam -> 77 | // Add the param default for a string 78 | addParam(boolParam.name, boolParam.defaultValue.toString().toBoolean()) 79 | }) 80 | 81 | // Run the body closure 82 | def paramsResult = parametersBody() 83 | 84 | // Unregister the contained elements 85 | helper.unRegisterAllowedMethod('string', [Map.class]) 86 | helper.unRegisterAllowedMethod('booleanParam', [Map.class]) 87 | 88 | // Result to higher level. Is this needed? 89 | return paramsResult 90 | }) 91 | 92 | // If any of these need special handling, it needs to be implemented here or in the tests with a closure instead of null 93 | helper.registerAllowedMethod('triggers', [Closure.class], null) 94 | helper.registerAllowedMethod('pollSCM', [String.class], null) 95 | helper.registerAllowedMethod('cron', [String.class], null) 96 | 97 | helper.registerAllowedMethod('agent', [Closure.class], null) 98 | helper.registerAllowedMethod('label', [String.class], null) 99 | helper.registerAllowedMethod('docker', [String.class], null) 100 | helper.registerAllowedMethod('image', [String.class], null) 101 | helper.registerAllowedMethod('args', [String.class], null) 102 | helper.registerAllowedMethod('dockerfile', [Closure.class], null) 103 | helper.registerAllowedMethod('dockerfile', [Boolean.class], null) 104 | 105 | helper.registerAllowedMethod('timestamps', [], null) 106 | helper.registerAllowedMethod('tools', [Closure.class], null) 107 | helper.registerAllowedMethod('stages', [Closure.class], null) 108 | helper.registerAllowedMethod('validateDeclarativePipeline', [String.class], null) 109 | 110 | helper.registerAllowedMethod('parallel', [Closure.class], null) 111 | helper.registerAllowedMethod('retry', [Integer.class, Closure.class], null) 112 | 113 | /** 114 | * Handling of a stage skipping execution in tests due to failure, abort, when 115 | */ 116 | helper.registerAllowedMethod('stage', [String.class, Closure.class], { String stgName, Closure body -> 117 | 118 | // Returned from the stage 119 | def stageResult 120 | 121 | // Handling of the when. Only supporting expression right now 122 | helper.registerAllowedMethod('when', [Closure.class], { Closure whenBody -> 123 | 124 | // Handle a when expression 125 | helper.registerAllowedMethod('expression', [Closure.class], { Closure expressionBody -> 126 | 127 | // Run the expression and return any result 128 | def expressionResult = expressionBody() 129 | if(expressionResult == false) { 130 | throw new WhenExitException("Stage '${stgName}' skipped due to when expression returned false") 131 | } 132 | return expressionResult 133 | }) 134 | 135 | // TODO - handle other when clauses in the when 136 | // branch : 'when { branch 'master' }' 137 | // environment : 'when { environment name: 'DEPLOY_TO', value: 'production' }' 138 | 139 | // Run the when body and return any result 140 | return whenBody() 141 | }) 142 | 143 | // Stage is not executed if build fails or aborts 144 | def status = binding.getVariable('currentBuild').result 145 | switch (status) { 146 | case 'FAILURE': 147 | case 'ABORTED': 148 | println "Stage '${stgName}' skipped - job status: '${status}'" 149 | break 150 | default: 151 | 152 | // Run the stage body. A when statement may exit with an exception 153 | try { 154 | stageResult = body() 155 | } 156 | catch (WhenExitException we) { 157 | // The when exited with an exception due to returning false. Swallow it. 158 | println we.getMessage() 159 | } 160 | catch (Exception e) { 161 | // Some sort of error in the pipeline 162 | throw e 163 | } 164 | 165 | } 166 | 167 | // Unregister 168 | helper.unRegisterAllowedMethod('when', [Closure.class.class]) 169 | helper.unRegisterAllowedMethod('expression', [Closure.class]) 170 | 171 | return stageResult 172 | }) 173 | 174 | helper.registerAllowedMethod('steps', [Closure.class], null) 175 | helper.registerAllowedMethod('script', [Closure.class], null) 176 | 177 | helper.registerAllowedMethod('when', [Closure.class], null) 178 | helper.registerAllowedMethod('expression', [Closure.class], null) 179 | helper.registerAllowedMethod('post', [Closure.class], null) 180 | 181 | /** 182 | * Handling the post sections 183 | */ 184 | def postResultEmulator = { String section, Closure c -> 185 | 186 | def currentBuild = binding.getVariable('currentBuild') 187 | 188 | switch (section) { 189 | case 'always': 190 | case 'changed': // How to handle changed? It may happen so just run it.. 191 | return c.call() 192 | break 193 | case 'success': 194 | if(currentBuild.result == 'SUCCESS') { return c.call() } 195 | else { println "post ${section} skipped as not SUCCESS"; return null} 196 | break 197 | case 'unstable': 198 | if(currentBuild.result == 'UNSTABLE') { return c.call() } 199 | else { println "post ${section} skipped as SUCCESS"; return null} 200 | break 201 | case 'failure': 202 | if(currentBuild.result == 'FAILURE') { return c.call() } 203 | else { println "post ${section} skipped as not FAILURE"; return null} 204 | break 205 | case 'aborted': 206 | if(currentBuild.result == 'ABORTED') { return c.call() } 207 | else { println "post ${section} skipped as not ABORTED"; return null} 208 | break 209 | default: 210 | assert false, "post section ${section} is not recognised. Check pipeline syntax." 211 | break 212 | } 213 | } 214 | helper.registerAllowedMethod('always', [Closure.class], postResultEmulator.curry('always')) 215 | helper.registerAllowedMethod('changed', [Closure.class], postResultEmulator.curry('changed')) 216 | helper.registerAllowedMethod('success', [Closure.class], postResultEmulator.curry('success')) 217 | helper.registerAllowedMethod('unstable', [Closure.class], postResultEmulator.curry('unstable')) 218 | helper.registerAllowedMethod('failure', [Closure.class], postResultEmulator.curry('failure')) 219 | } 220 | 221 | /** 222 | * Scripted pipeline methods not in the base 223 | */ 224 | void registerScriptedMethods() { 225 | 226 | /** 227 | * In minutes: 228 | * timeout(20) {} 229 | */ 230 | helper.registerAllowedMethod('timeout', [Integer.class, Closure.class], null) 231 | 232 | helper.registerAllowedMethod('waitUntil', [Closure.class], null) 233 | helper.registerAllowedMethod('writeFile', [Map.class], null) 234 | helper.registerAllowedMethod('build', [Map.class], null) 235 | helper.registerAllowedMethod('tool', [Map.class], { t -> "${t.name}_HOME" }) 236 | 237 | helper.registerAllowedMethod('withCredentials', [Map.class, Closure.class], { List list, Closure c -> 238 | 239 | list.each { 240 | //def env = helper.get 241 | def item = it.split('=') 242 | assert item.size() == 2, "withEnv list does not look right: ${list.toString()}" 243 | addEnvVar(item[0], item[1]) 244 | c.delegate = binding 245 | c.call() 246 | } 247 | }) 248 | helper.registerAllowedMethod('hipchatSend', [java.util.LinkedHashMap.class], null) 249 | helper.registerAllowedMethod('configFile', [java.util.LinkedHashMap], null) 250 | helper.registerAllowedMethod('configFileProvider', [java.util.ArrayList, Closure.class], null) 251 | helper.registerAllowedMethod('usernamePassword', [Map.class], { creds -> return creds }) 252 | 253 | helper.registerAllowedMethod('deleteDir', [], null) 254 | helper.registerAllowedMethod('pwd', [], { 'workspaceDirMocked' }) 255 | 256 | helper.registerAllowedMethod('stash', [Map.class], null) 257 | helper.registerAllowedMethod('unstash', [Map.class], null) 258 | 259 | helper.registerAllowedMethod('checkout', [Closure.class], null) 260 | 261 | helper.registerAllowedMethod('withEnv', [List.class, Closure.class], { List list, Closure c -> 262 | 263 | list.each { 264 | //def env = helper.get 265 | def item = it.split('=') 266 | assert item.size() == 2, "withEnv list does not look right: ${list.toString()}" 267 | addEnvVar(item[0], item[1]) 268 | c.delegate = binding 269 | c.call() 270 | } 271 | }) 272 | 273 | 274 | } 275 | 276 | /** 277 | * Variables that Jenkins expects 278 | */ 279 | void setJobVariables() { 280 | 281 | /** 282 | * Job params - may need to override in specific tests 283 | */ 284 | binding.setVariable('params', [:]) 285 | 286 | /** 287 | * The currentBuild in the job 288 | */ 289 | binding.setVariable('currentBuild', new Expando(result: 'SUCCESS', displayName: 'Build #1234')) 290 | 291 | /** 292 | * agent any 293 | * agent none 294 | */ 295 | binding.setVariable('any', {}) 296 | binding.setVariable('none', {}) 297 | 298 | /** 299 | * checkout scm 300 | */ 301 | binding.setVariable('scm', {}) 302 | 303 | /** 304 | * PATH 305 | */ 306 | binding.setVariable('PATH', '/some/path') 307 | binding.setVariable('RUN_DISPLAY_URL', "the jenkinsUrl") 308 | binding.setVariable('RUN_CHANGES_DISPLAY_URL', "the jenkinsUrl") 309 | /** 310 | * Initialize a basic Env passed in from Jenkins - may need to override in specific tests 311 | */ 312 | addEnvVar('BUILD_NUMBER', '1234') 313 | addEnvVar('PATH', '/some/path') 314 | } 315 | 316 | /** 317 | * Prettier print of call stack to whatever taste 318 | */ 319 | @Override 320 | void printCallStack() { 321 | println '>>>>>> pipeline call stack -------------------------------------------------' 322 | super.printCallStack() 323 | println '' 324 | } 325 | 326 | /** 327 | * Helper for adding a params value in tests 328 | */ 329 | void addParam(String name, Object val, Boolean overWrite = false) { 330 | Map params = binding.getVariable('params') as Map 331 | if (params == null) { 332 | params = [:] 333 | binding.setVariable('params', params) 334 | } 335 | if ( (val != null) && (params[name] == null || overWrite)) { 336 | params[name] = val 337 | } 338 | } 339 | 340 | /** 341 | * Helper for adding a environment value in tests 342 | */ 343 | void addEnvVar(String name, String val) { 344 | if (!binding.hasVariable('env')) { 345 | binding.setVariable('env', new Expando(getProperty: { p -> this[p] }, setProperty: { p, v -> this[p] = v })) 346 | } 347 | def env = binding.getVariable('env') as Expando 348 | env[name] = val 349 | } 350 | } 351 | -------------------------------------------------------------------------------- /pipelineTests/groovy/testSupport/WhenExitException.groovy: -------------------------------------------------------------------------------- 1 | package testSupport 2 | 3 | /** 4 | * An exception class to exit a stage due to the when statement 5 | */ 6 | class WhenExitException extends Exception { 7 | 8 | public WhenExitException(String message) 9 | { 10 | super(message); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_false_gradle_build test.txt: -------------------------------------------------------------------------------- 1 | Jenkinsfile.run() 2 | Jenkinsfile.pipeline(groovy.lang.Closure) 3 | Jenkinsfile.agent(groovy.lang.Closure) 4 | Jenkinsfile.parameters(groovy.lang.Closure) 5 | Jenkinsfile.booleanParam({name=VALIDATE, defaultValue=true, description=Whether to run validation stage}) 6 | Jenkinsfile.string({name=GRADLE_TASKS_OPTIONS, defaultValue=clean build test -i, description=Tasks and options for the gradle command}) 7 | Jenkinsfile.options(groovy.lang.Closure) 8 | Jenkinsfile.logRotator({numToKeepStr=10}) 9 | Jenkinsfile.buildDiscarder(null) 10 | Jenkinsfile.timestamps() 11 | Jenkinsfile.triggers(groovy.lang.Closure) 12 | Jenkinsfile.pollSCM(*/5 * * * *) 13 | Jenkinsfile.stages(groovy.lang.Closure) 14 | Jenkinsfile.stage(Checkout, groovy.lang.Closure) 15 | Jenkinsfile.steps(groovy.lang.Closure) 16 | Jenkinsfile.deleteDir() 17 | Jenkinsfile.checkout(groovy.lang.Closure) 18 | Jenkinsfile.stage(validate, groovy.lang.Closure) 19 | Jenkinsfile.when(groovy.lang.Closure) 20 | Jenkinsfile.expression(groovy.lang.Closure) 21 | Jenkinsfile.stage(build, groovy.lang.Closure) 22 | Jenkinsfile.steps(groovy.lang.Closure) 23 | Jenkinsfile.tool({name=GRADLE_3, type=hudson.plugins.gradle.GradleInstallation}) 24 | Jenkinsfile.withEnv([GRADLE_HOME=GRADLE_3_HOME], groovy.lang.Closure) 25 | Jenkinsfile.withEnv([PATH=/some/path:GRADLE_3_HOME/bin], groovy.lang.Closure) 26 | Jenkinsfile.echo(GRADLE_HOME=GRADLE_3_HOME) 27 | Jenkinsfile.echo(PATH=/some/path:GRADLE_3_HOME/bin) 28 | Jenkinsfile.sh(gradle build test) 29 | Jenkinsfile.post(groovy.lang.Closure) 30 | Jenkinsfile.always(groovy.lang.Closure) 31 | Jenkinsfile.echo(pipeline unit tests completed - recording JUnit results) 32 | Jenkinsfile.junit(build/test-results/**/*.xml) 33 | Jenkinsfile.success(groovy.lang.Closure) 34 | Jenkinsfile.echo(pipeline unit tests PASSED) 35 | Jenkinsfile.failure(groovy.lang.Closure) 36 | Jenkinsfile.changed(groovy.lang.Closure) 37 | Jenkinsfile.echo(pipeline unit tests results have CHANGED) 38 | Jenkinsfile.unstable(groovy.lang.Closure) 39 | -------------------------------------------------------------------------------- /pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_null_gradle_null.txt: -------------------------------------------------------------------------------- 1 | Jenkinsfile.run() 2 | Jenkinsfile.pipeline(groovy.lang.Closure) 3 | Jenkinsfile.agent(groovy.lang.Closure) 4 | Jenkinsfile.parameters(groovy.lang.Closure) 5 | Jenkinsfile.booleanParam({name=VALIDATE, defaultValue=true, description=Whether to run validation stage}) 6 | Jenkinsfile.string({name=GRADLE_TASKS_OPTIONS, defaultValue=clean build test -i, description=Tasks and options for the gradle command}) 7 | Jenkinsfile.options(groovy.lang.Closure) 8 | Jenkinsfile.logRotator({numToKeepStr=10}) 9 | Jenkinsfile.buildDiscarder(null) 10 | Jenkinsfile.timestamps() 11 | Jenkinsfile.triggers(groovy.lang.Closure) 12 | Jenkinsfile.pollSCM(*/5 * * * *) 13 | Jenkinsfile.stages(groovy.lang.Closure) 14 | Jenkinsfile.stage(Checkout, groovy.lang.Closure) 15 | Jenkinsfile.steps(groovy.lang.Closure) 16 | Jenkinsfile.deleteDir() 17 | Jenkinsfile.checkout(groovy.lang.Closure) 18 | Jenkinsfile.stage(validate, groovy.lang.Closure) 19 | Jenkinsfile.when(groovy.lang.Closure) 20 | Jenkinsfile.expression(groovy.lang.Closure) 21 | Jenkinsfile.steps(groovy.lang.Closure) 22 | Jenkinsfile.script(groovy.lang.Closure) 23 | Jenkinsfile.validateDeclarativePipeline(exampleJobs/parallel/Jenkinsfile) 24 | Jenkinsfile.validateDeclarativePipeline(Jenkinsfile) 25 | Jenkinsfile.stage(build, groovy.lang.Closure) 26 | Jenkinsfile.steps(groovy.lang.Closure) 27 | Jenkinsfile.tool({name=GRADLE_3, type=hudson.plugins.gradle.GradleInstallation}) 28 | Jenkinsfile.withEnv([GRADLE_HOME=GRADLE_3_HOME], groovy.lang.Closure) 29 | Jenkinsfile.withEnv([PATH=/some/path:GRADLE_3_HOME/bin], groovy.lang.Closure) 30 | Jenkinsfile.echo(GRADLE_HOME=GRADLE_3_HOME) 31 | Jenkinsfile.echo(PATH=/some/path:GRADLE_3_HOME/bin) 32 | Jenkinsfile.sh(gradle clean build test -i) 33 | Jenkinsfile.post(groovy.lang.Closure) 34 | Jenkinsfile.always(groovy.lang.Closure) 35 | Jenkinsfile.echo(pipeline unit tests completed - recording JUnit results) 36 | Jenkinsfile.junit(build/test-results/**/*.xml) 37 | Jenkinsfile.success(groovy.lang.Closure) 38 | Jenkinsfile.echo(pipeline unit tests PASSED) 39 | Jenkinsfile.failure(groovy.lang.Closure) 40 | Jenkinsfile.changed(groovy.lang.Closure) 41 | Jenkinsfile.echo(pipeline unit tests results have CHANGED) 42 | Jenkinsfile.unstable(groovy.lang.Closure) 43 | -------------------------------------------------------------------------------- /pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_true_gradle_test.txt: -------------------------------------------------------------------------------- 1 | Jenkinsfile.run() 2 | Jenkinsfile.pipeline(groovy.lang.Closure) 3 | Jenkinsfile.agent(groovy.lang.Closure) 4 | Jenkinsfile.parameters(groovy.lang.Closure) 5 | Jenkinsfile.booleanParam({name=VALIDATE, defaultValue=true, description=Whether to run validation stage}) 6 | Jenkinsfile.string({name=GRADLE_TASKS_OPTIONS, defaultValue=clean build test -i, description=Tasks and options for the gradle command}) 7 | Jenkinsfile.options(groovy.lang.Closure) 8 | Jenkinsfile.logRotator({numToKeepStr=10}) 9 | Jenkinsfile.buildDiscarder(null) 10 | Jenkinsfile.timestamps() 11 | Jenkinsfile.triggers(groovy.lang.Closure) 12 | Jenkinsfile.pollSCM(*/5 * * * *) 13 | Jenkinsfile.stages(groovy.lang.Closure) 14 | Jenkinsfile.stage(Checkout, groovy.lang.Closure) 15 | Jenkinsfile.steps(groovy.lang.Closure) 16 | Jenkinsfile.deleteDir() 17 | Jenkinsfile.checkout(groovy.lang.Closure) 18 | Jenkinsfile.stage(validate, groovy.lang.Closure) 19 | Jenkinsfile.when(groovy.lang.Closure) 20 | Jenkinsfile.expression(groovy.lang.Closure) 21 | Jenkinsfile.steps(groovy.lang.Closure) 22 | Jenkinsfile.script(groovy.lang.Closure) 23 | Jenkinsfile.validateDeclarativePipeline(exampleJobs/parallel/Jenkinsfile) 24 | Jenkinsfile.validateDeclarativePipeline(Jenkinsfile) 25 | Jenkinsfile.stage(build, groovy.lang.Closure) 26 | Jenkinsfile.steps(groovy.lang.Closure) 27 | Jenkinsfile.tool({name=GRADLE_3, type=hudson.plugins.gradle.GradleInstallation}) 28 | Jenkinsfile.withEnv([GRADLE_HOME=GRADLE_3_HOME], groovy.lang.Closure) 29 | Jenkinsfile.withEnv([PATH=/some/path:GRADLE_3_HOME/bin], groovy.lang.Closure) 30 | Jenkinsfile.echo(GRADLE_HOME=GRADLE_3_HOME) 31 | Jenkinsfile.echo(PATH=/some/path:GRADLE_3_HOME/bin) 32 | Jenkinsfile.sh(gradle test) 33 | Jenkinsfile.post(groovy.lang.Closure) 34 | Jenkinsfile.always(groovy.lang.Closure) 35 | Jenkinsfile.echo(pipeline unit tests completed - recording JUnit results) 36 | Jenkinsfile.junit(build/test-results/**/*.xml) 37 | Jenkinsfile.success(groovy.lang.Closure) 38 | Jenkinsfile.echo(pipeline unit tests PASSED) 39 | Jenkinsfile.failure(groovy.lang.Closure) 40 | Jenkinsfile.changed(groovy.lang.Closure) 41 | Jenkinsfile.echo(pipeline unit tests results have CHANGED) 42 | Jenkinsfile.unstable(groovy.lang.Closure) 43 | -------------------------------------------------------------------------------- /pipelineTests/groovy/tests/callstacks/ParallelJobTestSpec_Parallel_Jenkinsfile_should_complete_with_success.txt: -------------------------------------------------------------------------------- 1 | Jenkinsfile.run() 2 | Jenkinsfile.pipeline(groovy.lang.Closure) 3 | Jenkinsfile.agent(groovy.lang.Closure) 4 | Jenkinsfile.stages(groovy.lang.Closure) 5 | Jenkinsfile.stage(Setup, groovy.lang.Closure) 6 | Jenkinsfile.steps(groovy.lang.Closure) 7 | Jenkinsfile.script(groovy.lang.Closure) 8 | Jenkinsfile.stage(Dynamic, groovy.lang.Closure) 9 | Jenkinsfile.steps(groovy.lang.Closure) 10 | Jenkinsfile.script(groovy.lang.Closure) 11 | Jenkinsfile.parallel({foo=groovy.lang.Closure, bar=groovy.lang.Closure}) 12 | Jenkinsfile.echo(Running foo branch..) 13 | Jenkinsfile.echo(Running bar branch...) 14 | Jenkinsfile.stage(Static Old Way, groovy.lang.Closure) 15 | Jenkinsfile.steps(groovy.lang.Closure) 16 | Jenkinsfile.parallel({branch_1=groovy.lang.Closure, branch_2=groovy.lang.Closure}) 17 | Jenkinsfile.echo(Running static branch 1) 18 | Jenkinsfile.echo(Running static branch 2) 19 | Jenkinsfile.stage(Static New Way, groovy.lang.Closure) 20 | Jenkinsfile.parallel(groovy.lang.Closure) 21 | Jenkinsfile.stage(Stage 1, groovy.lang.Closure) 22 | Jenkinsfile.steps(groovy.lang.Closure) 23 | Jenkinsfile.echo(Running pipeline v1.2 static stage 1) 24 | Jenkinsfile.stage(Stage 2, groovy.lang.Closure) 25 | Jenkinsfile.steps(groovy.lang.Closure) 26 | Jenkinsfile.echo(Running pipeline v1.2 static stage 2) 27 | Jenkinsfile.stage(Stage Skipped, groovy.lang.Closure) 28 | Jenkinsfile.when(groovy.lang.Closure) 29 | Jenkinsfile.expression(groovy.lang.Closure) 30 | -------------------------------------------------------------------------------- /pipelineTests/groovy/tests/library/analyzeWithSonarTestSpec.groovy: -------------------------------------------------------------------------------- 1 | package tests.library 2 | 3 | import testSupport.PipelineSpockTestBase 4 | 5 | /** 6 | * How to unit test some vars DSL like shared code 7 | */ 8 | class analyzeWithSonarTestSpec extends PipelineSpockTestBase { 9 | 10 | 11 | def "test analyze with sonarqube"() { 12 | given: 13 | helper.registerAllowedMethod('readMavenPom', [Map.class], { 14 | return [groupId: "com.org", artifactId: "some-artifact-id"] 15 | }) 16 | helper.registerAllowedMethod('withCredentials', [List.class, Closure.class], { List list, Closure c -> 17 | binding.setVariable(list[0], 'some-token') 18 | c.delegate = binding 19 | c.call() 20 | }) 21 | addEnvVar("SONAR_URL", "https://some-sonar-url.io") 22 | when: 23 | def script = loadScript('vars/analyzeWithSonar.groovy') 24 | script.call() 25 | 26 | then: 27 | assert helper.callStack.findAll { call -> 28 | call.methodName == "sh" 29 | }.any { 30 | it.toString().contains("mvn sonar:sonar -Dsonar.login=some-token") 31 | } 32 | assert helper.callStack.findAll { call -> 33 | call.methodName == "hipchatSend" 34 | }.any { 35 | it.toString().contains("{color=GRAY, notify=true, v2enabled=true, message=Success: Sonarqube Scan complete https://some-sonar-url.io}") 36 | } 37 | 38 | printCallStack() 39 | assertJobStatusSuccess() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pipelineTests/groovy/tests/library/getJiraIssueTestSpec.groovy: -------------------------------------------------------------------------------- 1 | package tests.library 2 | 3 | import testSupport.PipelineSpockTestBase 4 | 5 | /** 6 | * How to unit test some vars DSL like shared code 7 | */ 8 | class getJiraIssueTestSpec extends PipelineSpockTestBase { 9 | 10 | 11 | def "get jira issue from a commit with a jira issue in it"() { 12 | given: 13 | helper.registerAllowedMethod('sh',[Map.class], { 14 | return 'LIA-23 look for hipchat message with correct variables' 15 | }) 16 | 17 | when: 18 | def script = loadScript('vars/getJiraIssue.groovy') 19 | def jiraIssue = script.call() 20 | 21 | then: 22 | printCallStack() 23 | assert jiraIssue == 'LIA-23' 24 | assertJobStatusSuccess() 25 | } 26 | def "get jira issue from the branch since commit has no jira issue"() { 27 | given: 28 | helper.registerAllowedMethod('sh',[Map.class], { 29 | return 'some commit message' 30 | }) 31 | addEnvVar("GIT_BRANCH","LIA-22-summary-feature") 32 | 33 | when: 34 | def script = loadScript('vars/getJiraIssue.groovy') 35 | def jiraIssue = script.call() 36 | 37 | then: 38 | printCallStack() 39 | assert jiraIssue == 'LIA-22' 40 | assertJobStatusSuccess() 41 | } 42 | def "attempt to get jira issue but returns empty"() { 43 | given: 44 | helper.registerAllowedMethod('sh',[Map.class], { 45 | return 'some commit message' 46 | }) 47 | addEnvVar("GIT_BRANCH","summary-feature") 48 | 49 | when: 50 | def script = loadScript('vars/getJiraIssue.groovy') 51 | def jiraIssue = script.call() 52 | 53 | then: 54 | printCallStack() 55 | assert jiraIssue == '' 56 | assertJobStatusSuccess() 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /pipelineTests/groovy/tests/library/gradleBuildTestSpec.groovy: -------------------------------------------------------------------------------- 1 | package tests.library 2 | 3 | import testSupport.PipelineSpockTestBase 4 | 5 | /** 6 | * How to unit test some vars DSL like shared code 7 | */ 8 | class gradleBuildTestSpec extends PipelineSpockTestBase { 9 | 10 | 11 | def "run gradle build"() { 12 | given: 13 | helper.registerAllowedMethod('withCredentials', [List.class, Closure.class], { List list, Closure c -> 14 | Map credMap = list[0] 15 | def credentialHolders = [] 16 | credMap.each { 17 | k, v -> 18 | credentialHolders.add(v) 19 | } 20 | binding.setVariable(credentialHolders[1], "jenkinsCredUsername") 21 | binding.setVariable(credentialHolders[2], "jenkinsCredPassword") 22 | c.delegate = binding 23 | c.call() 24 | }) 25 | addEnvVar("GIT_URL", "https://git-server.com/project/repo.git") 26 | when: 27 | def script = loadScript('vars/gradleBuild.groovy') 28 | script.call() 29 | 30 | then: 31 | assert helper.callStack.findAll { call -> 32 | call.methodName == "sh" 33 | }.any { 34 | it.toString().contains("gradle build") 35 | } 36 | printCallStack() 37 | assertJobStatusSuccess() 38 | } 39 | def "run default gradle BuildAndDeploy"() { 40 | given: 41 | helper.registerAllowedMethod('withCredentials', [List.class, Closure.class], { List list, Closure c -> 42 | Map credMap = list[0] 43 | def credentialHolders = [] 44 | credMap.each { 45 | k, v -> 46 | credentialHolders.add(v) 47 | } 48 | binding.setVariable(credentialHolders[1], "jenkinsCredUsername") 49 | binding.setVariable(credentialHolders[2], "jenkinsCredPassword") 50 | c.delegate = binding 51 | c.call() 52 | }) 53 | addEnvVar("GIT_URL", "https://git-server.com/project/repo.git") 54 | 55 | when: 56 | def script = loadScript('vars/gradleBuildAndDeploy.groovy') 57 | script.call() 58 | 59 | then: 60 | assert helper.callStack.findAll { call -> 61 | call.methodName == "sh" 62 | }.any { 63 | it.toString().contains("gradle artifactoryPublish") 64 | } 65 | printCallStack() 66 | assertJobStatusSuccess() 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /pipelineTests/groovy/tests/library/mavenBuildTestSpec.groovy: -------------------------------------------------------------------------------- 1 | package tests.library 2 | 3 | import testSupport.PipelineSpockTestBase 4 | 5 | /** 6 | * How to unit test some vars DSL like shared code 7 | */ 8 | class mavenBuildTestSpec extends PipelineSpockTestBase { 9 | 10 | def "run maven build"() { 11 | given: 12 | helper.registerAllowedMethod('configFileProvider', [java.util.ArrayList, Closure.class], { List list, Closure c -> 13 | binding.setVariable("MAVEN_SETTINGS", "path/to/settings.xml") 14 | c.delegate = binding 15 | c.call() 16 | }) 17 | addEnvVar("GIT_URL", "https://git-server.com/project/repo.git") 18 | addEnvVar("GIT_BRANCH", "LIA-23-some-feature") 19 | addEnvVar("SONAR_URL", "https://some-sonar-url.io") 20 | 21 | when: 22 | def script = loadScript('vars/mavenBuild.groovy') 23 | script.call() 24 | 25 | then: 26 | printCallStack() 27 | assert helper.callStack.get(0).toString().trim() == "mavenBuild.call()" 28 | assert helper.callStack.get(1).toString().trim() == "mavenBuild.hipchatSend({color=GRAY, notify=true, v2enabled=true, message=Building LIA-23-some-feature from: https://git-server.com/project/repo.git})" 29 | assert helper.callStack.get(2).toString().trim() == "mavenBuild.configFile({fileId=artifactory, variable=MAVEN_SETTINGS})" 30 | assert helper.callStack.get(3).toString().trim() == "mavenBuild.configFileProvider([null], groovy.lang.Closure)" 31 | assert helper.callStack.get(4).toString().trim() == "mavenBuild.sh(mvn -s path/to/settings.xml -Dsonar.host.url=https://some-sonar-url.io clean install -B)" 32 | assert helper.callStack.get(5).toString().trim() == "mavenBuild.hipchatSend({color=GRAY, notify=true, v2enabled=true, message=Success: Built war with changelist the jenkinsUrl})" 33 | assertJobStatusSuccess() 34 | } 35 | def "run default maven BuildAndDeploy"() { 36 | given: 37 | helper.registerAllowedMethod('withCredentials', [List.class, Closure.class], { List list, Closure c -> 38 | Map credMap = list[0] 39 | def credentialHolders = [] 40 | credMap.each { 41 | k, v -> 42 | credentialHolders.add(v) 43 | } 44 | binding.setVariable(credentialHolders[1], "jenkinsCredUsername") 45 | binding.setVariable(credentialHolders[2], "jenkinsCredPassword") 46 | c.delegate = binding 47 | c.call() 48 | }) 49 | addEnvVar("GIT_URL", "https://git-server.com/project/repo.git") 50 | addEnvVar("GIT_BRANCH", "LIA-23-some-feature") 51 | addEnvVar("GIT_COMMIT", "92b4d3435f39c6be") 52 | 53 | when: 54 | def script = loadScript('vars/mavenBuildAndDeploy.groovy') 55 | script.call() 56 | 57 | then: 58 | printCallStack() 59 | assert helper.callStack.get(0).toString().trim() == "mavenBuildAndDeploy.call()" 60 | assert helper.callStack.get(1).toString().trim() == "mavenBuildAndDeploy.hipchatSend({color=GRAY, notify=true, v2enabled=true, message=Building LIA-23-some-feature from: https://git-server.com/project/repo.git})" 61 | assert helper.callStack.get(2).toString().trim() == "mavenBuildAndDeploy.usernamePassword({credentialsId=Artifactory, usernameVariable=USERNAME, passwordVariable=PASSWORD})" 62 | assert helper.callStack.get(3).toString().trim() == "mavenBuildAndDeploy.withCredentials([{credentialsId=Artifactory, usernameVariable=USERNAME, passwordVariable=PASSWORD}], groovy.lang.Closure)" 63 | assert helper.callStack.get(4).toString().trim() == "mavenBuildAndDeploy.sh(mvn clean deploy -B -DartifactoryUsername=jenkinsCredUsername -DartifactoryPassword=jenkinsCredPassword)" 64 | assert helper.callStack.get(5).toString().trim() == "mavenBuildAndDeploy.hipchatSend({color=GRAY, notify=true, v2enabled=true, message=Success: Built war with changelist the jenkinsUrl})" 65 | assertJobStatusSuccess() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /pipelineTests/groovy/tests/library/postmessageTestSpec.groovy: -------------------------------------------------------------------------------- 1 | package tests.library 2 | 3 | import testSupport.PipelineSpockTestBase 4 | 5 | /** 6 | * How to unit test some vars DSL like shared code 7 | */ 8 | class postMessageTestSpec extends PipelineSpockTestBase { 9 | def "slack message send" () { 10 | given: 11 | addEnvVar("chatClient", "slack") 12 | helper.registerAllowedMethod("slackSend",[Map.class], null) 13 | helper.registerAllowedMethod("mattermostSend",[Map.class], null) 14 | helper.registerAllowedMethod("hipchatSend",[Map.class], null) 15 | def params = ["color": "GREEN", "message": "Build was successful", "team": "liatrio-team"] 16 | 17 | when: 18 | def script = loadScript('vars/postMessage.groovy') 19 | script.call(params) 20 | 21 | then: 22 | printCallStack() 23 | assert helper.callStack.get(0).toString().trim() == "postMessage.call({color=GREEN, message=Build was successful, team=liatrio-team})" 24 | assert helper.callStack.get(1).toString().trim() == "postMessage.slackSend({channel=false, color=GREEN, message=Build was successful, teamDomain=liatrio-team, token=slack-token})" 25 | assertJobStatusSuccess() 26 | 27 | } 28 | def "hipchat message send" () { 29 | given: 30 | addEnvVar("chatClient", "hipchat") 31 | helper.registerAllowedMethod("hipchatSend",[Map.class], null) 32 | def params = ["color": "GREEN", "message": "Build was successful", "team": "liatrio-team"] 33 | when: 34 | def script = loadScript('vars/postMessage.groovy') 35 | script.call(params) 36 | then: 37 | printCallStack() 38 | assert helper.callStack.get(0).toString().trim() == "postMessage.call({color=GREEN, message=Build was successful, team=liatrio-team})" 39 | assert helper.callStack.get(1).toString().trim() == "postMessage.hipchatSend({color=GREEN, notify=true, v2enabled=true, message=Build was successful, token=hipchat-token})" 40 | assertJobStatusSuccess() 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /pipelineTests/groovy/tests/library/runAppLocallyTestSpec.groovy: -------------------------------------------------------------------------------- 1 | package tests.library 2 | 3 | import testSupport.PipelineSpockTestBase 4 | 5 | /** 6 | * How to unit test some vars DSL like shared code 7 | */ 8 | class runAppLocallyTestSpec extends PipelineSpockTestBase { 9 | 10 | 11 | def "test analyze with sonarqube"() { 12 | given: 13 | addEnvVar("DOCKER_REPO", "docker-repo-path.io") 14 | def appParams = [:] 15 | appParams.appName = "some-app-name" 16 | appParams.imageName = "some-image-name" 17 | appParams.imageVersion = "latest" 18 | 19 | when: 20 | def script = loadScript('vars/runAppLocally.groovy') 21 | script.call(appParams) 22 | 23 | then: 24 | printCallStack() 25 | assert helper.callStack.get(0).toString().trim() == "runAppLocally.call({appName=some-app-name, imageName=some-image-name, imageVersion=latest})" 26 | assert helper.callStack.get(1).toString().trim() == "runAppLocally.sh(docker network create demo || true)" 27 | assert helper.callStack.get(2).toString().trim() == "runAppLocally.sh(docker rm -f some-app-name || true)" 28 | assert helper.callStack.get(3).toString().trim() == "runAppLocally.retry(3, groovy.lang.Closure)" 29 | assert helper.callStack.get(4).toString().trim() == "runAppLocally.sh(docker run -d --net demo --rm --name some-app-name docker-repo-path.io/some-image-name:latest)" 30 | assertJobStatusSuccess() 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/org/ldop/DockerHubHelper.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | package org.ldop 4 | 5 | @Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.7') 6 | 7 | import groovyx.net.http.RESTClient 8 | 9 | class DockerHubHelper { 10 | 11 | public DockerHubHelper() { /* empty */ } 12 | 13 | def dockerHttpRequestGet(url, page) { 14 | def dockerHubApi = new RESTClient("https://hub.docker.com/v2/") 15 | 16 | def response = dockerHubApi.get(path: url, query: ["page": page]) 17 | 18 | return response.data 19 | } 20 | 21 | def getDockerHubTags(repository, image) { 22 | return dockerHttpRequestGet("repositories/${repository}/${image}/tags/").results 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/org/ldop/DockerHubHelper.txt: -------------------------------------------------------------------------------- 1 |

Gets data from DockerHub

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /src/org/ldop/NexusMavenArtifactHelper.groovy: -------------------------------------------------------------------------------- 1 | @Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7' ) 2 | 3 | import org.apache.commons.io.IOUtils 4 | import org.apache.commons.io.FileUtils 5 | import groovyx.net.http.HTTPBuilder 6 | import static groovyx.net.http.Method.GET 7 | import static groovyx.net.http.ContentType.BINARY 8 | 9 | 10 | class NexusMavenArtifactHelper { 11 | 12 | public NexusMavenArtifactHelper() { /* empty */ } 13 | 14 | static def getArtifact(groupId, artifactId, version, targetPath, String nexus="http://nexus:8081") { 15 | 16 | if (version.contains('SNAPSHOT')) { 17 | url = "${nexus}/nexus/service/local/artifact/maven/content?r=snapshots&g=${groupId}&a=${artifactId}&v=${version}&p=war" 18 | } else { 19 | url = "${nexus}/nexus/service/local/artifact/maven/content?r=releases&g=${groupId}&a=${artifactId}&v=${version}&p=war" 20 | } 21 | 22 | env = System.getenv() 23 | artifactEndpoint = new HTTPBuilder(url) 24 | artifactEndpoint.auth.basic(env['INITIAL_ADMIN_USER'], env['INITIAL_ADMIN_PASSWORD']) 25 | artifactEndpoint.headers.'Accept' = '*/*' 26 | 27 | artifactEndpoint.request(GET, BINARY) { req -> 28 | 29 | response.success = { resp, reader -> 30 | target = new File(targetPath) 31 | targetDir = new File(target.getParent()) 32 | targetDir.mkdirs() // Create dirs if they don't exist 33 | FileUtils.copyInputStreamToFile(reader, target); 34 | println 'success' 35 | } 36 | 37 | response.failure = { resp -> 38 | println('Error performing request:') 39 | println(" ${req.getRequestLine()}") 40 | println('Responded with:') 41 | println(" ${resp.getStatusLine()}") 42 | } 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/org/ldop/NexusMavenArtifactHelper.txt: -------------------------------------------------------------------------------- 1 |

Downloads an artifact from nexus and writes it to targetPath.

2 |

Creates target directories if they don't exist. Errors if the target file already exists

3 |

Parameters:

4 | -------------------------------------------------------------------------------- /vars/AddProductToManifest.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | def call(product, version) { 4 | 5 | if (!product || !version) 6 | return 7 | sh 'git reset --hard' 8 | sh "git checkout master && git pull" 9 | def parsedText = readJSON file: "manifest.json" 10 | parsedText.put(product, version) 11 | writeJSON file: 'manifest.json', json: parsedText 12 | 13 | withCredentials([usernamePassword(credentialsId: 'github', passwordVariable: 'PASSWORD', usernameVariable: 14 | 'USERNAME')]) { 15 | sh "git add manifest.json" 16 | sh 'git commit -m "Jenkins updating manifest" ' 17 | sh "git push https://${USERNAME}:${PASSWORD}@github.com/liatrio/sample-manifest-pipeline.git" 18 | } 19 | } -------------------------------------------------------------------------------- /vars/AddProductToManifest.txt: -------------------------------------------------------------------------------- 1 |

Adds the product version to the JSON manifest

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /vars/DeployToBluemix.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | def call(String productName, String artifactPath, String nexus="http://nexus:8081") { 4 | def parsedText = readJSON file: "manifest.json" 5 | def urlForArtifact = "${nexus}/nexus/content/repositories/${artifactPath}" 6 | sh "curl -o ${productName}.war ${urlForArtifact}" 7 | withCredentials([usernamePassword(credentialsId: 'bluemix', passwordVariable: 'PASSWORD', usernameVariable: 'USERNAME')]) { 8 | sh 'cf api https://api.ng.bluemix.net' 9 | sh "cf login -u ${env.USERNAME} -p ${env.PASSWORD}" 10 | sh 'cf push' 11 | } 12 | } -------------------------------------------------------------------------------- /vars/DeployToBluemix.txt: -------------------------------------------------------------------------------- 1 |

Deploys to a bluemix environment

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /vars/analyzeWithSonar.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | def call() { 4 | withCredentials([string(credentialsId: 'sonarqube', variable: 'sonarqubeToken')]) { 5 | sh "mvn sonar:sonar -Dsonar.login=${sonarqubeToken}" 6 | } 7 | pom = readMavenPom file: 'pom.xml' 8 | hipchatSend color: 'GRAY', notify: true, v2enabled: true, message: "Success: Sonarqube Scan complete ${env.SONAR_URL}" 9 | } 10 | -------------------------------------------------------------------------------- /vars/analyzeWithSonar.txt: -------------------------------------------------------------------------------- 1 |

Analyzes the project with Sonar

2 | No Parameters -------------------------------------------------------------------------------- /vars/bumpVersion.groovy: -------------------------------------------------------------------------------- 1 | #!/bin/env groovy 2 | 3 | def call (String input_version, String type = "patch") { 4 | 5 | def version = input_version.tokenize(".") 6 | 7 | def snapshot = version[2].contains("-SNAPSHOT") 8 | 9 | def major 10 | def minor 11 | def patch 12 | 13 | //major update 14 | if (type == "major") { 15 | major = version[0].toInteger() + 1 16 | minor = "0" 17 | patch = "0" 18 | } 19 | //minor update 20 | else if (type == "minor") { 21 | major = version[0] 22 | minor = version[1].toInteger() + 1 23 | patch = "0" 24 | } 25 | //patch snapshot update 26 | else if (type == "patch" && snapshot) { 27 | major = version[0] 28 | minor = version[1] 29 | patch = version[2].split('-')[0].toInteger() + 1 30 | } 31 | //patch release update 32 | else if (type == "patch") { 33 | major = version[0] 34 | minor = version[1] 35 | patch = version[2].toInteger() + 1 36 | } 37 | 38 | def newver = major + "." + minor + "." + patch 39 | 40 | if (snapshot) 41 | newver += "-SNAPSHOT" 42 | return newver 43 | } 44 | -------------------------------------------------------------------------------- /vars/bumpVersion.txt: -------------------------------------------------------------------------------- 1 |

Increases the project version by one

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /vars/deployContainerToEnv.groovy: -------------------------------------------------------------------------------- 1 | #!/bin/env groovy 2 | 3 | def call(Map params, String credentialsIdIn = '71d94074-215d-4798-8430-40b98e223d8c') { 4 | withCredentials([sshUserPrivateKey(credentialsId: credentialsIdIn, keyFileVariable: 'keyFileVariable', passphraseVariable: '', usernameVariable: 'usernameVariable')]) { 5 | withCredentials([usernamePassword(credentialsId: 'Artifactory', passwordVariable: 'artifactoryPassword', usernameVariable: 'artifactoryUsername')]) { 6 | STAGE = env.STAGE_NAME 7 | sh "ssh -o StrictHostKeyChecking=no -i $keyFileVariable $usernameVariable@${params.env} docker login -u ${env.artifactoryUsername} -p ${env.artifactoryPassword} ${env.DOCKER_REPO}" 8 | } 9 | String stopAppCommand = "docker rm -f ${params.appName} || sleep 5" 10 | sh "ssh -o StrictHostKeyChecking=no -i $keyFileVariable $usernameVariable@${params.env} docker pull ${env.DOCKER_REPO}/${params.imageName}:${params.imageVersion}" 11 | sh "ssh -o StrictHostKeyChecking=no -i $keyFileVariable $usernameVariable@${params.env} ${stopAppCommand}" 12 | sh "ssh -o StrictHostKeyChecking=no -i $keyFileVariable $usernameVariable@${params.env} 'docker ps -a || sleep 5'" 13 | sh "ssh -o StrictHostKeyChecking=no -i $keyFileVariable $usernameVariable@${params.env} 'docker run --rm -d --name ${params.appName} -p 80:8080 ${env.DOCKER_REPO}/${params.imageName}:${params.imageVersion}'" 14 | hipchatSend color: 'GRAY', notify: true, v2enabled: true, message: "Success: Deployed to Development Environment; waiting on Smoke Test" 15 | } 16 | try { 17 | jiraComment body: "Deployed ${params.imageName}:${TAG} to http://${params.env}", issueKey: "${params.jiraIssue}" 18 | } 19 | catch (e) { 20 | echo "No Jira Ticket" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /vars/deployContainerToEnv.txt: -------------------------------------------------------------------------------- 1 |

Deploys a given container to a given environment

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /vars/deployHelmChartOpenshift.groovy: -------------------------------------------------------------------------------- 1 | #!/bin/env groovy 2 | /** 3 | * Deploys a helm chart to an OpenShift cluster 4 | 5 | * REQUIRED ENVIRONMENT VARIABLES 6 | * OPENSHIFT_CLUSTER: OpenShift cluster host name 7 | * OPENSHIFT_PROJECT: OpenShift project name 8 | * APP_NAME: Application name 9 | * BRANCH_NAME: Build branch name 10 | * VERSION: Application version 11 | * TILLER_NAMESPACE: Kubernetes namespace to deploy app into 12 | * DOCKER_REGISTRY: Docker registry host name 13 | * 14 | * PARAMETERS 15 | * openshiftToken: DEFAULT = "openshift-token": OpenShift token name 16 | * helmRepository: DEFAULT = "https://artifactory.liatr.io/artifactory/helm": Helm repository URL 17 | * helmRepositoryCredentials: DEFAULT = "helm-repository-credentials": Name of Helm credentials 18 | * chartName: DEFAULT = APP_NAME 19 | */ 20 | def call(params) { 21 | if (!params) params = [:] 22 | def chartName = params.get("chartName", APP_NAME) 23 | def branchName = env.BRANCH_NAME ?: "master" 24 | withCredentials([string(credentialsId: params.get("openshiftToken", "openshift-token"), variable: 'OC_TOKEN')]) { 25 | // Setup OpenShift Kubernetes context and setup Helm 26 | sh "oc login https://${OPENSHIFT_CLUSTER} --token=${OC_TOKEN}" 27 | sh "helm init --client-only" 28 | withCredentials([usernamePassword(credentialsId: params.get("helmRepositoryCredentials", "helm-repository-credentials"), variable: 'CREDS', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { 29 | sh "helm repo add liatrio-repository ${params.get("helmRepository", "https://artifactory.liatr.io/artifactory/helm")} --username $USERNAME --password $PASSWORD" 30 | } 31 | 32 | // Generate Helm deploy name. Verify and comply with Helms deployment name 33 | // standard release name sample-app-api-ENG-493-joe is not a valid DNS 34 | // label: a DNS-1123 label must consist of lower case alphanumeric characters 35 | // or '-', and must start and end with an alphanumeric character (e.g. 36 | // 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?') 37 | def deploy_name = "${APP_NAME}-${branchName}".take(32).toLowerCase() 38 | echo "Deploy name: ${deploy_name}" 39 | 40 | // Check if chart is already installed 41 | def helm_status_data = sh returnStdout: true, script: 'helm ls --output=json' 42 | echo "helm status: ${helm_status_data}" 43 | def helm_status = readJSON text: "${helm_status_data ?: '[]'}" 44 | def action = helm_status.Releases?.findAll {it.Status == 'DEPLOYED'}.collect { it.Name }.contains(deploy_name)? "upgrade" : "install" 45 | 46 | // Install or update Helm chart 47 | echo "Performing helm action: ${action}" 48 | if ( action == "upgrade" ) { 49 | sh "helm upgrade ${deploy_name} liatrio-repository/${chartName} --version ${VERSION} --namespace ${TILLER_NAMESPACE} --set openshift=true --set image.repository=${DOCKER_REGISTRY}/liatrio/${APP_NAME} --set image.tag=${VERSION}" 50 | } else { 51 | try { 52 | sh "helm install liatrio-repository/${chartName} --name ${deploy_name} --version ${VERSION} --namespace ${TILLER_NAMESPACE} --set openshift=true --set image.repository=${DOCKER_REGISTRY}/liatrio/${APP_NAME} --set image.tag=${VERSION}" 53 | } catch (Exception ex) { 54 | // delete helm deployment on failure otherwise it will block future builds 55 | sh "helm delete --purge ${deploy_name}" 56 | throw ex 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /vars/deployToEnvironment.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | def call(String user, String instance, String pkCredentialsId, String image, String tag, String appName, String frontendRule, String loadBalanceGroup=null) { 4 | if (!loadBalanceGroup) { 5 | // Use unique name for loadBalanceGroup 6 | loadBalanceGroup = appName 7 | } 8 | String dockerRm = "docker rm -f ${appName} || true" 9 | String dockerPull = "docker pull ${image}:${tag}" 10 | String dockerRun = "docker run --label 'traefik.enable=true' --label 'traefik.backend=${loadBalanceGroup}' --label 'traefik.frontend.rule=Host:${frontendRule}' --network=bridge -d --name ${appName} ${image}:${tag}" 11 | 12 | withCredentials([file(credentialsId: pkCredentialsId, variable: 'privateKeyPath')]) { 13 | sh "ssh -i ${privateKeyPath} -tt -o StrictHostKeyChecking=no -l ${user} ${instance} '${dockerRm}; ${dockerPull}; ${dockerRun}'" 14 | sh "exit" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /vars/deployToEnvironment.txt: -------------------------------------------------------------------------------- 1 |

Deploys an application container to an environment.

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /vars/doesVersionExist.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | import org.ldop.DockerHubHelper 4 | 5 | def call(repository, image, tagName) { 6 | DockerHubHelper helper = new DockerHubHelper() 7 | 8 | def pageNumber = "1" 9 | def nextUrl = "repositories/${repository}/${image}/tags/" 10 | 11 | while (nextUrl) { 12 | def jsonResponse = helper.dockerHttpRequestGet(nextUrl, pageNumber) 13 | def dockerHubTags = jsonResponse.results.name 14 | 15 | if (jsonResponse.next) { 16 | def splitValue = "repositories" + jsonResponse.next.split("repositories")[1] 17 | 18 | nextUrl = splitValue.split('\\?')[0] 19 | pageNumber = splitValue.split('=')[1] 20 | } else { 21 | nextUrl = null 22 | } 23 | 24 | if (dockerHubTags.any { it == tagName }) 25 | return true 26 | } 27 | 28 | return false 29 | } 30 | -------------------------------------------------------------------------------- /vars/doesVersionExist.txt: -------------------------------------------------------------------------------- 1 |

Checks if a given version of an artifact exists

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /vars/failIfVersionExists.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | import org.ldop.DockerHubHelper 4 | 5 | def call(repository, image, tagName) { 6 | if(doesVersionExist(repository, image, tagName)) { 7 | echo "Version already exists on dockerhub" 8 | error("LDOP ${image} tag ${tagName} already exists on dockerhub! Failing pipeline...") 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /vars/failIfVersionExists.txt: -------------------------------------------------------------------------------- 1 |

Helper to fail the pipeline if image already exists

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /vars/formatSlackOutput.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | def call(jobTitle, jobUrl, jobChanges, exitStatus) { 4 | def changes = "" 5 | def output = "*Job*\n• ${jobTitle}\n• ${jobUrl}\n*Status*\n• ${exitStatus}\n*Changes*\n" 6 | 7 | for (entry in jobChanges) { 8 | for (item in entry) { 9 | changes = changes + "• ${item.msg} [${item.author}]\n" 10 | } 11 | } 12 | 13 | changes = (changes == "") ? "• no changes" : changes 14 | 15 | return output + changes 16 | } 17 | -------------------------------------------------------------------------------- /vars/formatSlackOutput.txt: -------------------------------------------------------------------------------- 1 |

Formatter for details for outputting to Slack

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /vars/getArtifact.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | def call(String groupId, String artifactId, String version, String artifactName, String nexus="http://nexus:8081"){ 4 | 5 | if (version.contains("SNAPSHOT")){ 6 | url = "nexus/service/local/artifact/maven/content?r=snapshots&g=${groupId}&a=${artifactId}&v=${version}&p=war" 7 | 8 | } 9 | else { 10 | url = "nexus/service/local/artifact/maven/content?r=releases&g=${groupId}&a=${artifactId}&v=${version}&p=war" 11 | } 12 | sh "wget --user=${INITIAL_ADMIN_USER} --password=${INITIAL_ADMIN_PASSWORD} -O ${artifactName}.war \"${nexus}/${url}\"" 13 | sh 'mkdir target' 14 | sh "mv ${artifactName}.war target/${artifactName}.war" 15 | } 16 | -------------------------------------------------------------------------------- /vars/getArtifact.txt: -------------------------------------------------------------------------------- 1 |

Gets an artifact based on parameters

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /vars/getJiraIssue.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | def call() { 4 | def jiraIssue = '' 5 | def gitLog = sh( 6 | script: 'git log -1', 7 | returnStdout: true 8 | ).trim() 9 | def result = (gitLog =~ /\s*([A-Z]+-[0-9]+)/) 10 | try { 11 | echo result[0][0] 12 | jiraIssue = (result[0][0]).trim() 13 | currentBuild.description = "${jiraIssue} ${env.JIRA_URL}/browse/${jiraIssue}" 14 | } catch (Exception ex) { 15 | try { 16 | echo "No ticket name specified in commit, looking at the branch" 17 | echo "Branch name is ${env.GIT_BRANCH}" 18 | jiraIssue = ( "${env.GIT_BRANCH}" =~ /\s*([A-Z]+-[0-9]+)/)[0][0].trim() 19 | currentBuild.description = "${jiraIssue} ${env.JIRA_URL}/browse/${jiraIssue}" 20 | } 21 | catch (Exception e) { 22 | echo "No jira issue in branch" 23 | currentBuild.description = "N/A." 24 | } 25 | } 26 | finally { 27 | return jiraIssue 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /vars/getJiraIssue.txt: -------------------------------------------------------------------------------- 1 |

Gets a Jira issue

2 | No Parameters -------------------------------------------------------------------------------- /vars/getLatestVersion.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | import org.ldop.DockerHubHelper 4 | 5 | def call(repository, image) { 6 | DockerHubHelper helper = new DockerHubHelper() 7 | 8 | return helper.getDockerHubTags(repository, image)[0].name 9 | } 10 | -------------------------------------------------------------------------------- /vars/getLatestVersion.txt: -------------------------------------------------------------------------------- 1 |

Gets the latest version of an image from a repository

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /vars/getNexusMavenArtifact.groovy: -------------------------------------------------------------------------------- 1 | import org.ldop.NexusMavenArtifactHelper.groovy 2 | 3 | def call(groupId, artifactId, version, targetPath) { 4 | NexusMavenArtifactHelper.getArtifact(groupId, artifactId, version, targetPath) 5 | } 6 | -------------------------------------------------------------------------------- /vars/getNexusMavenArtifact.txt: -------------------------------------------------------------------------------- 1 |

Downloads an artifact from nexus and writes it to targetPath

2 |

Creates target directories if they don't exist. Errors if the target file already exists

3 |

Parameters:

4 | -------------------------------------------------------------------------------- /vars/getVersionFromContainer.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | def call(imageName) { 4 | sh "docker inspect ${imageName} > containerMetaData.json" 5 | def metaData = readJSON file: "containerMetaData.json" 6 | return metaData[0].ContainerConfig.Labels.version.split(" ")[1] 7 | } 8 | -------------------------------------------------------------------------------- /vars/getVersionFromContainer.txt: -------------------------------------------------------------------------------- 1 |

Gets the version from a specific docker image

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /vars/gradleBuild.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | def call() { 4 | hipchatSend color: 'GRAY', notify: true, v2enabled: true, message: "Building ${env.GIT_BRANCH} from: ${env.GIT_URL}" 5 | withCredentials([usernamePassword(credentialsId: 'Artifactory', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { 6 | sh 'gradle build' 7 | } 8 | hipchatSend color: 'GRAY', notify: true, v2enabled: true, message: "Success: Built war with changelist ${RUN_CHANGES_DISPLAY_URL}" 9 | 10 | } 11 | -------------------------------------------------------------------------------- /vars/gradleBuild.txt: -------------------------------------------------------------------------------- 1 |

Runs a gradle build for the project

2 | No Parameters -------------------------------------------------------------------------------- /vars/gradleBuildAndDeploy.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy\ 2 | 3 | def call() { 4 | hipchatSend color: 'GRAY', notify: true, v2enabled: true, message: "Building ${env.GIT_BRANCH} from: ${env.GIT_URL}" 5 | withCredentials([usernamePassword(credentialsId: 'Artifactory', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { 6 | sh 'gradle artifactoryPublish ' 7 | } 8 | hipchatSend color: 'GRAY', notify: true, v2enabled: true, message: "Success: Built war with changelist ${RUN_CHANGES_DISPLAY_URL}" 9 | } 10 | -------------------------------------------------------------------------------- /vars/gradleBuildAndDeploy.txt: -------------------------------------------------------------------------------- 1 |

Runs a gradle build for the project and publishes the artifact to Artifactory

2 | No Parameters -------------------------------------------------------------------------------- /vars/mavenBuild.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | def call() { 4 | hipchatSend color: 'GRAY', notify: true, v2enabled: true, message: "Building ${env.GIT_BRANCH} from: ${env.GIT_URL}" 5 | configFileProvider([configFile(fileId: 'artifactory', variable: 'MAVEN_SETTINGS')]) { 6 | sh "mvn -s $MAVEN_SETTINGS -Dsonar.host.url=${env.SONAR_URL} clean install -B" 7 | } 8 | hipchatSend color: 'GRAY', notify: true, v2enabled: true, message: "Success: Built war with changelist ${RUN_CHANGES_DISPLAY_URL}" 9 | } 10 | -------------------------------------------------------------------------------- /vars/mavenBuild.txt: -------------------------------------------------------------------------------- 1 |

Runs a maven build for the project

2 | No Parameters -------------------------------------------------------------------------------- /vars/mavenBuildAndDeploy.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | def call() { 4 | def gitUrl = env.GIT_URL ? env.GIT_URL: env.GIT_URL_1 5 | hipchatSend color: 'GRAY', notify: true, v2enabled: true, message: "Building ${env.GIT_BRANCH} from: ${gitUrl}" 6 | withCredentials([usernamePassword(credentialsId: 'Artifactory', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { 7 | sh "mvn clean deploy -B -DartifactoryUsername=$USERNAME -DartifactoryPassword=$PASSWORD" 8 | } 9 | hipchatSend color: 'GRAY', notify: true, v2enabled: true, message: "Success: Built war with changelist ${RUN_CHANGES_DISPLAY_URL}" 10 | } 11 | -------------------------------------------------------------------------------- /vars/mavenBuildAndDeploy.txt: -------------------------------------------------------------------------------- 1 |

Runs a maven build for the project and publishes the artifact to Artifactory

2 | No Parameters -------------------------------------------------------------------------------- /vars/mavenJxBuild.groovy: -------------------------------------------------------------------------------- 1 | #!/bin/env groovy 2 | 3 | def call(params) { 4 | if (!params) params = [:] 5 | def appVersion = params.get("version", "") 6 | sendBuildEvent(eventType: 'build') 7 | container('maven') { 8 | def pom = readMavenPom file: 'pom.xml' 9 | if (appVersion) { 10 | sh "mvn versions:set -DnewVersion=${appVersion}" 11 | } else { 12 | appVersion = pom.version.split("-")[0] + "-${BUILD_NUMBER}" 13 | } 14 | env.VERSION = appVersion 15 | env.APP_NAME = pom.artifactId 16 | env.GROUP_ID = pom.groupId 17 | 18 | sh "mvn clean install" 19 | sh "skaffold version" 20 | 21 | if (env.BRANCH_NAME == 'master') { 22 | sh "git checkout master" 23 | sh "git config --global credential.helper store" 24 | sh "jx step git credentials" 25 | sh "jx step tag --version ${appVersion}" 26 | } 27 | 28 | sh "skaffold build -f skaffold.yaml" 29 | sh "jx step post build --image $DOCKER_REGISTRY/$ORG/$APP_NAME:$VERSION" 30 | if (env.BRANCH_NAME.contains("PR")) { 31 | dir('charts/preview') { 32 | sh "make preview" 33 | sh "jx preview --app $APP_NAME --dir ../.." 34 | env.APP_URL = sh returnStdout: true, script: 'jx get previews -c' 35 | } 36 | echo "url to sample app is: ${env.APP_URL}" 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /vars/postMessage.groovy: -------------------------------------------------------------------------------- 1 | #!/bin/env groovy 2 | 3 | def call(Map params) { 4 | def color = params.color 5 | def message = params.message 6 | def room = params.channel || params.room 7 | def team = params.team 8 | switch(env.chatClient) { 9 | case "slack": 10 | slackSend channel: room, color: color, message: params.message, teamDomain: team, token: 'slack-token' 11 | break 12 | case "hipchat": 13 | def notify = true 14 | if( color != "RED" && color != "GREEN") 15 | notify = false 16 | hipchatSend color: color, notify: notify, v2enabled: true, message: message, token: 'hipchat-token' 17 | break 18 | case "mattermost": 19 | mattermostSend color: 'color', message: 'Message from Jenkins Pipeline', text: message, token: 'mattermost-token' 20 | break 21 | // case "stride": 22 | // echo "stride command" 23 | default: 24 | echo "no chat client enabled" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /vars/postMessage.txt: -------------------------------------------------------------------------------- 1 |

Posts a message to a chat room

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /vars/promoteJx.groovy: -------------------------------------------------------------------------------- 1 | def call() { 2 | container('maven') { 3 | dir('charts/sample-app-api') { 4 | sh "jx step changelog --version $VERSION" 5 | 6 | // release the helm chart 7 | sh "jx step helm release" 8 | 9 | // promote through all 'Auto' promotion Environments 10 | sh "jx promote -b --all-auto --timeout 1h --version $VERSION" 11 | def pipelineActivityUrl = "${env.ORG}-${env.APP_NAME}-${env.BRANCH_NAME}-${env.BUILD_ID}" 12 | env.APP_URL= sh returnStdout: true, script: "kubectl get pipelineactivity ${pipelineActivityUrl} -o=\"jsonpath={.spec.steps[?(.kind=='Promote')].promote.applicationURL}\"" 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /vars/publishHelmChartArtifactory.groovy: -------------------------------------------------------------------------------- 1 | #!/bin/env groovy 2 | /** 3 | * Publish a Helm chart to an Artifactory repository 4 | * 5 | * PARAMETERS 6 | * helmRepository: DEFAULT = "https://artifactory.liatr.io/artifactory/helm" 7 | * chartPath: DEFAULT = "charts/" 8 | * chartName: DEFAULT = APP_NAME 9 | * repos: List of repos to add to helm for chart dependencies 10 | * version: Used for chart version - DEFAULT = VERSION. 11 | **/ 12 | def call(params) { 13 | if (!params) params = [:] 14 | def chartPath = params.get("chartPath", "charts/") 15 | def chartName = params.get("chartName", null) 16 | if (!chartName) chartName = APP_NAME 17 | def helmRepository = params.get("helmRepository", "https://artifactory.liatr.io/artifactory/helm") 18 | def version = params.get("version", null) 19 | if (!version) version = VERSION 20 | sh "helm init --client-only" 21 | def repos = params.get("repos") 22 | repos?.each { 23 | sh "helm repo add ${it.name} ${it.url}" 24 | } 25 | sh "helm package --dependency-update --version ${version} --app-version ${version} ${chartPath}/${chartName}" 26 | withCredentials([usernamePassword(credentialsId: 'jenkins-credential-artifactory', passwordVariable: 'artifactoryPassword', usernameVariable: 'artifactoryUsername')]) { 27 | sh "curl -X PUT -u ${env.artifactoryUsername}:${env.artifactoryPassword} -T ${chartName}-${version}.tgz '${helmRepository}/${chartName}-${version}.tgz'" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /vars/pushContainerToArtifactory.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | def call(tag) { 4 | STAGE = env.STAGE_NAME 5 | withCredentials([usernamePassword(credentialsId: 'Artifactory', passwordVariable: 'artifactoryPassword', usernameVariable: 'artifactoryUsername')]) { 6 | sh "docker login -u ${env.artifactoryUsername} -p ${env.artifactoryPassword} ${env.DOCKER_REPO}" 7 | sh "docker push ${env.DOCKER_REPO}/${env.IMAGE}:${tag}" 8 | } 9 | hipchatSend color: 'GRAY', notify: true, v2enabled: true, message: "Success: Pushed to ${env.ARTIFACTORY_URL}" 10 | } 11 | -------------------------------------------------------------------------------- /vars/pushContainerToArtifactory.txt: -------------------------------------------------------------------------------- 1 |

Pushes a docker image to artifactory

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /vars/runAppLocally.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | def call(Map params) { 4 | STAGE = env.STAGE_NAME 5 | sh "docker network create demo || true" 6 | sh "docker rm -f ${params.appName} || true" 7 | retry (3) { 8 | sh "docker run -d --net demo --rm --name ${params.appName} ${env.DOCKER_REPO}/${params.imageName}:${params.imageVersion}" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /vars/runAppLocally.txt: -------------------------------------------------------------------------------- 1 |

Runs a docker image locally

2 |

Parameters:

3 | -------------------------------------------------------------------------------- /vars/sendBuildEvent.groovy: -------------------------------------------------------------------------------- 1 | import groovy.json.JsonOutput 2 | 3 | def call(requestParams) { 4 | /* 5 | def requestBody = [ 6 | "teamName": ${teamName}, 7 | "appName": ${env.APP_NAME}, 8 | "eventName": "state-change", 9 | "branch": "master", 10 | "state": "healthy", 11 | "priorDuration": 16343 12 | ] 13 | */ 14 | requestParams.teamName = env.TEAM_NAME ? env.TEAM_NAME : env.ORG 15 | requestParams.appName = env.APP_NAME 16 | requestParams.branch = env.BRANCH_NAME 17 | requestParams.groupID = env.GROUP_ID 18 | requestParams.versionNumber = env.VERSION 19 | requestParams.gitCommit = env.GIT_COMMIT 20 | 21 | def requestBody = JsonOutput.toJson(requestParams) 22 | def url = env.elasticUrl ? env.elasticUrl : "localhost:9000" 23 | 24 | def response = httpRequest acceptType: 'APPLICATION_JSON', contentType: 'APPLICATION_JSON', httpMode: 'POST', requestBody: requestBody, url: url 25 | println('Status: ' + response.status) 26 | println('Response: ' + response.content) 27 | } 28 | -------------------------------------------------------------------------------- /vars/sendHealthyEvent.groovy: -------------------------------------------------------------------------------- 1 | def call(String unit = "MILLISECONDS") { 2 | 3 | 4 | def divisor = ["HOURS": 360000, "MINUTES": 60000, "SECONDS": 1000 , "MILLISECONDS": 1] 5 | long completedTimeStamp = currentBuild.getTimeInMillis() 6 | long prevTimeStamp = getTimeOfFailedBuild(currentBuild) 7 | recoveryTime = completedTimeStamp - prevTimeStamp 8 | sendBuildEvent(eventType:'state-change', state: 'healthy', priorDuration: recoveryTime ) 9 | return (completedTimeStamp - prevTimeStamp) / divisor[unit] 10 | } 11 | 12 | 13 | 14 | @NonCPS 15 | long getTimeOfFailedBuild(currentBuild) { 16 | def build = currentBuild //current build is fixed 17 | 18 | while(build.getNumber() > 1 && build.getPreviousBuild().getResult() != 'SUCCESS') { 19 | build = build.getPreviousBuild() 20 | } 21 | println "build that failed first ${build.getNumber()}" 22 | return build.getTimeInMillis() 23 | } -------------------------------------------------------------------------------- /vars/sendUnhealthyEvent.groovy: -------------------------------------------------------------------------------- 1 | def call(String unit = "MILLISECONDS") { 2 | 3 | def divisor = ["HOURS": 360000, "MINUTES": 60000, "SECONDS": 1000 , "MILLISECONDS": 1] 4 | long completedTimeStamp = currentBuild.getTimeInMillis() 5 | long prevTimeStamp = getTimeOfFailedBuild(currentBuild) 6 | recoveryTime = completedTimeStamp - prevTimeStamp 7 | echo "last failed build was: ${recoveryTime} ago " 8 | sendBuildEvent(eventType:'state-change', state: 'unhealthy', priorDuration: recoveryTime ) 9 | return recoveryTime / divisor[unit] 10 | } 11 | 12 | @NonCPS 13 | long getTimeOfFailedBuild(currentBuild) { 14 | def build = currentBuild.getPreviousBuild() //start looking at previous build 15 | while(build.getNumber() > 1 && build.getResult() != 'FAILURE') { 16 | build = build.getPreviousBuild() 17 | } 18 | println "Last failed build was ${build.getNumber()}" 19 | return build.getTimeInMillis() 20 | } -------------------------------------------------------------------------------- /vars/skaffoldBuild.groovy: -------------------------------------------------------------------------------- 1 | #!/bin/env groovy 2 | 3 | def call(params) { 4 | if (!params) params = [:] 5 | docker.withRegistry("https://${DOCKER_REGISTRY}", params.get("artifactoryCredentials", "jenkins-credential-artifactory")) { 6 | sh "skaffold build -p ${SKAFFOLD_PROFILE} -f skaffold.yaml" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /vars/testSuite.groovy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | //vars/TestSuite.groovy 3 | import hudson.model.* 4 | import java.io.File 5 | 6 | def call(String ldopImageName, String branch, String directory, String orgName="liatrio") { 7 | if (!ldopImageName || !branch) 8 | return 9 | 10 | def file = new File("${directory}/docker-compose.yml") 11 | file.write(file.text.replaceAll( 12 | "image: ${orgName}/${ldopImageName}:"+/\d{1,2}(?:\.\d{1,2}\.\d{1,2})?/, 13 | "image: ${orgName}/${ldopImageName}:${branch}")); 14 | } 15 | -------------------------------------------------------------------------------- /vars/testSuite.txt: -------------------------------------------------------------------------------- 1 |

Replaces tag name in docker compose file with branch name

2 |

Parameters:

3 | --------------------------------------------------------------------------------