We did exactly this in a solution with over 165 projects grouped into 30 individual services and web applications. However instead of building a specific project with msbuild
we created individual solutions based on the respective service and web application domain. The result were solutions like JenkinsBuild_Project1.sln
and JenkinsBuild_Project2.sln
.
https://stackoverflow.com/a/19534376/3850405
The code below can be modified to use msbuild
instead with minor changes.
Jenkinsfile:
#!groovy
import groovy.json.*
pipeline {
agent {
node {
label 'msbuild'
}
}
environment {
OCTOPUS_PUBLISH_KEY = credentials('OctoPackPublishApiKey')
//Global variable where we save what to build
BUILD_LIST =''
}
stages {
stage('What to build?') {
steps {
script {
GIT_DIFF = bat (
script: 'git diff --name-status HEAD..HEAD~1',
returnStdout: true
).trim()
echo "From batscript: ${GIT_DIFF}"
//Environment variable values must either be single quoted, double quoted, or function calls and therefore a json string is used to save the array
//https://stackoverflow.com/a/53745878/3850405
BUILD_LIST = new JsonBuilder(whatToBuild("${GIT_DIFF}")).toPrettyString()
echo BUILD_LIST
}
}
}
stage('Prepare') {
steps {
script {
def buildList = new JsonSlurper().parseText(BUILD_LIST)
for (i = 0; i < buildList.size(); i++){
bat "C:\\Program\\NuGet\\nuget_4.4.1.exe restore Source\\${buildList[i]}\\${buildList[i]}.sln"
}
}
}
}
stage('Build') {
steps {
script {
def buildList = new JsonSlurper().parseText(BUILD_LIST)
for (i = 0; i < buildList.size(); i++){
bat "\"${tool 'Build Tools 2019'}\" /t:Clean;Build /p:Configuration=JenkinsBuild JenkinsBuild\\JenkinsBuild_${buildList[i]}.sln"
}
}
}
}
stage('Publish') {
when {
anyOf {
branch 'master';
}
}
steps {
script {
def buildList = new JsonSlurper().parseText(BUILD_LIST)
for (i = 0; i < buildList.size(); i++){
bat """\"${tool 'Build Tools 2019'}\" ^
/t:Build ^
/p:Configuration=JenkinsBuild ^
/p:RunOctoPack=true ^
/p:OctoPackEnforceAddingFiles=true ^
/p:AllowedReferenceRelatedFileExtensions=none ^
/p:OctoPackNuGetProperties=env=${env.BRANCH_NAME};change=${env.CHANGE_ID} ^
/p:OctoPackPackageVersion=2.1.${BUILD_NUMBER}-${env.BRANCH_NAME}1 ^
/p:OctoPackPublishPackageToHttp=https://OurOctopusServer:1337/nuget/packages ^
/p:OctoPackPublishApiKey=${env.OCTOPUS_PUBLISH_KEY} ^
JenkinsBuild\\JenkinsBuild_${buildList[i]}.sln"""
}
}
}
}
}
post {
always {
//Clean and notify
}
}
}
Groovy script that takes a file list from git command git diff --name-status HEAD..HEAD~1
and filters out unique project values like Project1
and Project2
from paths like below.
/Source/Project1/Project1.Data/Properties/AssemblyInfo.cs
/Source/Project2/Project2.Clients.WinService/Services/Project2.Designer.cs
whatToBuild.groovy:
#!/usr/bin/env groovy
def call(String fileList) {
println "Printing filelist in whatToBuild()"
println fileList
def lines = fileList.tokenize('\n')
println lines
def list = []
lines.eachWithIndex{ value, key ->
println "Printing value"
println value
if (value.contains("Source")) {
def result = value =~ /Source\/([A-Z]*)\//
println "Printing result"
println result[0][1]
list.add(result[0][1])
}
}
def listUnique = list as Set
println listUnique
return listUnique
}