Skip to content

Instantly share code, notes, and snippets.

@ennisa-ire
Last active December 20, 2018 13:11
Show Gist options
  • Save ennisa-ire/993ef28062279a39df74204175a09185 to your computer and use it in GitHub Desktop.
Save ennisa-ire/993ef28062279a39df74204175a09185 to your computer and use it in GitHub Desktop.
01 - IoT Tech DevOps Corner

DevOps!!!

Principles

Principles

Tracking

you can track your local head to a remote, and vica versa using tracking. This will inform u if you local branch is ahead of the remote, and vica versa

https://www.git-tower.com/learn/git/faq/track-remote-upstream-branch

Git Forking

Configuration

Web Hooks

API

Migration

Some things to consider

Thanks for reaching out to the GitHub Professional Services team and inquiring about a TFS to GitHub migration. A migration preserving version history is certainly an option, and to best scope and provide you with how Professional Services would advise on this migration, can you provide responses the following questions? • How many repositories or projects would be involved in the migration? • Are libraries, binaries, or other large artifacts stored in the current TFS version controlled content? • Which deployment of GitHub is the destination (GitHub Enterprise, GitHub Business Cloud, GitHub.com)? • What, if any, integrations or third-party solutions are in use (e.g. Jenkins or similar CI/CD solution, JIRA, etc.)?

  • Setup a archetype project

ubuntu@service-accounts:~/workspace/tmp$ mvn archetype:generate
-DarchetypeArtifactId=jersey-quickstart-grizzly2
-DarchetypeGroupId=org.glassfish.jersey.archetypes
-DgroupId=com.example
-Dpackage=com.example
-DartifactId=simple-service
-DinteractiveMode=false

-DarchetypeVersion=2.26-b09

[INFO] Generating project in Batch mode [INFO] Archetype repository not defined. Using the one from [org.glassfish.jersey.archetypes:jersey-quickstart-grizzly2:2.26-b09] found in catalog remote [INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating project from Old (1.x) Archetype: jersey-quickstart-grizzly2:2.26-b09 [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: basedir, Value: /home/ubuntu/workspace/tmp [INFO] Parameter: package, Value: com.example [INFO] Parameter: groupId, Value: com.example [INFO] Parameter: artifactId, Value: simple-service [INFO] Parameter: packageName, Value: com.example [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] project created from Old (1.x) Archetype in dir: /home/ubuntu/workspace/tmp/simple-service [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 6.707 s [INFO] Finished at: 2017-08-26T14:33:19+00:00 [INFO] Final Memory: 17M/251M

Note:

  • project setup simple-service
  • Feel free to adjust the groupId, package and/or artifactId of your new project.

Adding external jar to project

From the NetBeans forum:

Open the Projects tab.
Right-click on Dependencies.
Select Add dependency.
Set groupId to: group.id (can be anything)
Set artifactId to: artifact.id (can be anything)
Set version to: 1.0 (can be anything)
Click Add to continue.
Dependency is added to pom.xml and appears under the Libraries node of Maven project. Continue:

Expand Dependencies.
Right-click on library (e.g., group.id).
Select Manually install artifact.
Set Artifact to install with the Java Archive (.jar) file path.
Click Install locally.
Library is installed locally with dependency attributes (coordinates) entered in steps 4 - 6.

Search

apt-cache search maven

The maven package always comes with latest Apache Maven.

ubuntu@service-accounts:~/workspace/tmp$ apt-cache search maven
libxml-maven-plugin-java - Maven XML Plugin
libxmlbeans-maven-plugin-java - Maven XMLBeans Plugin
libxmlbeans-maven-plugin-java-doc - Documentation for Maven XMLBeans Plugin
maven - Java software project management and comprehension tool
maven-ant-helper - helper scripts for building Maven components with ant
maven-debian-helper - Helper tools for building Debian packages with Maven
maven-repo-helper - Helper tools for including Maven metadata in Debian packages
testng - testing framework for Java
ubuntu@service-accounts:

Install

ubuntu@service-accounts:~/workspace/tmp$ sudo apt-get install maven
Setting up maven (3.3.9-3) ...
update-alternatives: using /usr/share/maven/bin/mvn to provide /usr/bin/mvn (mvn) in auto mode

Verify

ubuntu@service-accounts:~/workspace/tmp$ mvn -version
Apache Maven 3.3.9
Maven home: /usr/share/maven
Java version: 1.8.0_131, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-8-openjdk-i386/jre
Default locale: en_IE, platform encoding: UTF-8
OS name: "linux", version: "4.4.0-89-generic", arch: "i386", family: "unix"
ubuntu@service-accounts:~/workspace/tmp$ 

Home

ubuntu@service-accounts:~/workspace/tmp$ ll /usr/share/maven
total 24
drwxr-xr-x   6 root root 4096 Aug 26 14:26 ./
drwxr-xr-x 125 root root 4096 Aug 26 14:26 ../
drwxr-xr-x   2 root root 4096 Aug 26 14:26 bin/
drwxr-xr-x   2 root root 4096 Aug 26 14:26 boot/
lrwxrwxrwx   1 root root   10 Dec 10  2015 conf -> /etc/maven/
drwxr-xr-x   2 root root 4096 Aug 26 14:26 lib/
drwxr-xr-x   2 root root 4096 Aug 26 14:26 man/
ubuntu@service-accounts:~/workspace/tmp$ ll /usr/share/maven

Configuration

ubuntu@service-accounts:~/workspace/tmp$ ll /etc/maven/
total 32
drwxr-xr-x  3 root root  4096 Aug 26 14:26 ./
drwxr-xr-x 95 root root  4096 Aug 26 14:26 ../
drwxr-xr-x  2 root root  4096 Aug 26 14:26 logging/
-rw-r--r--  1 root root   222 Nov 19  2015 m2.conf
-rw-r--r--  1 root root 10216 Nov 19  2015 settings.xml
-rw-r--r--  1 root root  3649 Nov 19  2015 toolchains.xml
ubuntu@service-accounts:~/workspace/tmp$ 

Maven project structure:

Project build and management configuration is described in the pom.xml located in the project root directory. Project sources are located under src/main/java. Project test sources are located under src/test/java.

Is about the journey, not the destination
"Design"
Random/Posion distribution please.
Concerns - Migrated Load is Low.
Performance Features
Workload - groups of people dont act synchrously...
Think Time - contanst.
Active users
Page Hits
Thread Pool
TPS
ThroughPut
* Also know as hits, or RPS, or ThroughPut.
* TP is measure of how many units of work are been processed.
* Is a measure of activity
* visualizse as a convery belt, with the load been _processed_ by the server. Take my "authenticaton" and process it, service it..
* its measure in RPS.
Concurrent users
* vistors
* The number of users engaged with the app or site at a given time.
* visualize the users as cars, and the road system as your application, if too many cars , you will get a jam, then a deversion, or worse, a pile up!! or standstill
Journey
* Scripts to minic what we expect users to do, such as navigating through a retail site, searching for an item, choosing one and buying it, registering for an account, editing profile preferences, and so on.
Contrived
Login - Payment - logout.
Real
* Login - Browse, make a payment.
Test Strategy
UX load test - examines journey, working on a page level, pages , and static files are downloaded, but not processed.
KPI = Users/Min V Response Times/Sec
1. Use natural journeys.
-> Then run those scripts at stepped intervals of load, 10 users, then 100, then 1000 users, examine throughput for each run, you can extrapalate next runs, but it wont be linear.
-> implement think time using poison distribution.
Use legal entities with cards and accounts, and mix of product kinds.
login only once?
2. For a complex scenario, like logging in or filling out a form, you will need to implement a dynamic variable.
For example: in Drupal, you might want to catch the form build ID and pass it on with the login post request, because these are created in real time.
3. E2E tests to be run during performance tests(response times to analysised, should include rendering time)
4. Users Verus Reponse Time.
=> for errors , such as 500/501, socket closed, socket timeout
5. Examine jmeter load engine, to get better understanding of response times.
API load test - working on JSON level
KPI = Request / Second
1. Run e2e test during load test, if mobile app.
2. Concerned with throughput ie. Requests/Sec, not response time!!!
3. Dont retrieve all
4. Response times should be a lot shorter.
5. Use a higher number of threads on API then UI test, and as such example stress on CPU is critical, and not memory which is used uring UI
6. Add assertions on data level, value, and path, as data might not be ok. (UX 200:OK is on request level)
7. Use of constant throughput timer more valuable here.
8. Here we are interested in pacing / stepping load, to find bottle necks.
Test Calculations
* X number of users = Y number of hits/sec
Tech Stack.
Site Type : Dynamic
Performance is a prcess!!! Needs a process workflow.
Assumtions
* Architecutre has not changed, if so what is the delta.
* User load projects are incluvise of all supported devices!!!
* User load, was calculated by a tracking tool called
Google Analytics or MixPanel or KISSmetrics, or machine logs.
Post Mortem.
/**
 * Checkout code using Git plugin
 * Input parameters
 *   1.gitRepo
 *   2.branchName
 *   
 **/

def checkout(gitRepo, branchName){
	try{
		git credentialsId: 'ssh_devopspipeline_credentials', url: gitRepo, branch: branchName;
		println "Checked out repo - ${gitRepo}, branch - ${branchName}";
	}catch(Exception e){
		println "Failed to checkout repo - ${gitRepo}";
		throw e;
	}
}


/**
 * Checkout code using GIT plugin with polling enabled
 * Input parameters
 *   1.gitCredId
 *   2.gitRepo
 *   3.branchName
 **/
/*def CheckoutWithPollingEnabled(gitCredId,gitRepo, branchName){
	git poll: true, credentialsId: gitCredId, url: gitRepo, branch: branchName
	println "Checked out repo - ${gitRepo}, branch - ${branchName}";
}*/


def checkoutProperties(){
	
}

/**
 * Checkout code using clone. This method is to avoid poll
 * Input parameters
 *	 1.Jenkins node OS
 *   2.gitRepo
 *   3.branchName
 *   
 **/

def clonerepo(nodeOs, gitRepo, branchName){
	try{
		withCredentials([string(credentialsId: 'comm_git_clone_token', variable: 'comm_git_clone_token')]){
			if(nodeOs == 'WIN') {
				bat "git clone -b ${branchName} https://${comm_git_clone_token}@${gitRepo}";
				println "Cloned the repo";
			}else{
				sh "scl enable rh-git29 -- git clone -b ${branchName} https://${comm_git_clone_token}@${gitRepo}";
			}
		}
		println "Cloned repo - ${gitRepo}, branch - ${branchName}";
	}catch(Exception e){
		println "Failed to clone repo - ${gitRepo}";
		throw e;
	}
}

def getCommitSha(nodeOs) {
	if(nodeOs == 'WIN') {
		bat "git rev-parse HEAD > .git/current-commit";
	}else{
		sh "git rev-parse HEAD > .git/current-commit";
	}
  
  	return readFile(".git/current-commit").trim()
}

def getRepoURL(nodeOs) {
	if(nodeOs == 'WIN') {
		bat "git config --get remote.origin.url > .git/remote-url";
	}else{
		sh "git config --get remote.origin.url > .git/remote-url";
	}
  	return readFile(".git/remote-url").trim()
}

def getTagName(buildVersion) {
  "v${buildVersion}"
}

def tagBuild(nodeOs, buildVersion) {
  def repoUrl = getRepoURL(nodeOs);
  def commitSha = getCommitSha(nodeOs);
  def tagName = getTagName buildVersion;
  
	if(nodeOs == 'WIN') {
		sshagent(credentials: ['ssh_devopspipeline_credentials']) {
			bat "git tag -a -m \"Tagging change set $commitSha with version $buildVersion\" $tagName $commitSha";
			bat "git push origin $tagName";
		}
	}else{
		sshagent(credentials: ['ssh_devopspipeline_credentials']) {
			sh "git tag -a -m \"Tagging change set $commitSha with version $buildVersion\" $tagName $commitSha";
			sh "git push origin $tagName";
		}
	}
}


/*
 - artifactoryTarget -  target path to where it needs to be uplaoded
 - artifactoryPattern - pattern of the packages to upload
 - buildinfo object
 - artifactory server object

*/
def doUploadToArtifactory(artifactoryTarget,artifactoryPattern,buildInfo,server){
	
	println "artifactoryTarget = " + artifactoryTarget
	println "artifactoryPattern = " + artifactoryPattern
	println "buildInfo = " + buildInfo
	
	def uploadSpec = """ {
		"files" : [{
				"pattern" : ${artifactoryPattern},
				"target" :  ${artifactoryTarget}
			}]
	}""";
	server.upload(uploadSpec, buildInfo)
}
/*
 - buildno to promote
 - status
 - buildname of the package
 - server - artifactory server object
 - artifactory source repo
 - artifactory target repo
 - comments
*/
def promoteBuild(server, buildname, buildno, comment, status, sourceRepo, targetRepo){
    println sourceRepo
    println targetRepo
    println buildname
    println buildno
    println comment
    println status

   	def buildInfo   = Artifactory.newBuildInfo();
   	buildInfo.name  = buildname;
   	buildInfo.number= buildno;

	def promotionConfig = [
		//Mandatory parameters
		'buildName'          : buildInfo.name,
		'buildNumber'        : buildInfo.number,
		'targetRepo'         : targetRepo,

		//Optional parameters
		'comment'            : comment,
		'sourceRepo'         : sourceRepo,
		'status'             : status,
		'includeDependencies': false,
		'failFast'           : true,
		'copy'               : false
	]

	// Promote build
	server.promote promotionConfig
}

/*
- artifactoryTarget -  target path to where it needs to be uplaoded
 - artifactoryPattern - pattern of the packages to upload
 - server - artifactory server object
*/
def downloadPackages(server,pattern,target){

	println server
	println pattern
	println target
	
	def downloadSpec = """ {
		"files" : [
		{
				"target" : ${target},
				"pattern" :${pattern},
				"flat"  : true
			} 
		]
		}"""

	server.download(downloadSpec)
}




/*
*	Defines the pipeline stages and prepares the stage array which is used for email notification
*	Input Parameters
*	stages - Array 
*/

import java.text.SimpleDateFormat;
def prepareStages(String... stages){
	try{
		def dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
		def start = new Date();
		env.build_start = dateFormat.format(start);
		def stageArray = [:]
		for(def stage: stages){
			stageArray.put(stage, "Not started");
		}
		return stageArray;
	
}catch(Exception e){
	println "Caught: ${e}";
	println 'Error preparing stages';
	throw e;
}
}



/*
*	get the console log of a jenkins job which is used for email notification
*	absoluteUrl - jenkinsbuildobject.absoluteUrl or http://plgsascs4750004.r1-core.r1.aig.net:8080/job/commercial-it-multi-national/job/qa-master-pipeline/19/
*	logfilename - somefilename.txt
*/

def getJenkinsJobConsole(absoluteUrl,logfilename) {
	println absoluteUrl;
	println logfilename;
	if (absoluteUrl.size() > 0){
		absoluteUrl 	= absoluteUrl + 'consoleText';
		try{
		def httpresp 	= httpRequest authentication: 'devopspipeline', url:absoluteUrl
		println('Status: '+httpresp.status);
		println('Response: '+httpresp.content);
		//Write the jenkins console log to seperate file and attach in the email
		if(logfilename !=""){
			writeFile file:logfilename,text: httpresp.content+"\n";
		}
		}
		catch(Exception e){
		println e;
		throw e;
		}
	}
}

/*
* Creates release notes in format {{componentName}}-{{buildVersion}}-{{fileName}}
* Input parameters
* nodeOs
* componentName
* buildVersion
* fileName
* startDate - Sprint/Release start date
*/
def generateReleaseNotes(nodeOs, componentName, buildVersion, fileName, startDate){
	try{
		if(nodeOs == 'WIN')
			bat "git log --pretty=format:\"%%cd \t\t %%cn    \t\t\t %%s\" --since=${startDate} > temp.txt";
		else
			sh "git log --pretty=format:\"%cd \t\t %cn    \t\t\t %s\" --since=${startDate} > temp.txt";
		def relNotesContent = readFile 'temp.txt';
		def header = "-------------------------------------------------------------------------------------------------------               -------------------------------------------";
		header = header + "\n\t Date \t\t\t\t Committed By \t\t\t\t\t\t Task Description \n";
		header = header + "--------------------------------------------------------------------------------------------------   ------------------------------------------------\n";
		def targetReleaseNotesArtifactName = componentName + "-" +  buildVersion + "-" + "${fileName}";
		writeFile file:"${targetReleaseNotesArtifactName}",text:header + relNotesContent
		return targetReleaseNotesArtifactName;
	}catch(Exception e){
		println "Caught: ${e}";
		println 'Error creating ReleaseNotes.';
		throw e;
	}
}

/**
* Downloads the Sprint release notes for the component and appends to Release_Notes.txt file to create consolidated release notes
*
*/
def  consolidateReleaseNotes(server, component, deployment_unit_name, artifactVersion, baseFolder, artifactAppFolder){
    println 'Inside consolidateReleaseNotes method'
    def repo = '';
    if(component.equals('Service')){
       repo = env.SERVICES_ARTIFACT_DOWNLOAD_REPO ;
    }else if(component.equals('UI')){
       repo = env.UX_UI_ARTIFACT_DOWNLOAD_REPO ;
    }else if(component.equals('DB')){
       repo = env.DB_ARTIFACT_DOWNLOAD_REPO ;
    }
   def consolidatedReleaseNotes = readFile 'Release_Notes.txt'
   def componentRelNotesContent = '';
    try{
        def artifactName =   artifactAppFolder + '-' + artifactVersion +  '-sprint-release-notes.txt'
        def artifactoryPattern = '"' + repo + '/' + baseFolder +'/' + artifactAppFolder  + '/' + artifactVersion + '/' + artifactName + '"';
        componentRelNotesContent = getReleaseNotes(server,artifactoryPattern)
    }catch(Exception ex1){
        println 'ignore failure'
        try{
            def artifactName = 'Sprint_Release_Notes.txt'
            def artifactoryPattern = '"' + repo + '/' + baseFolder +'/' + artifactAppFolder  + '/' + artifactVersion + '/' + artifactName + '"';
            componentRelNotesContent = getReleaseNotes(server,artifactoryPattern)
        }catch(Exception ex2){
                println 'ignore failure'
        }
    }
    println componentRelNotesContent;
   writeFile file:'Release_Notes.txt',text:consolidatedReleaseNotes + '\n\n\n' + deployment_unit_name + '  Version - ' + artifactVersion+ '\n\n\n' +  componentRelNotesContent;
}

/**
* Downloads the release notes from artifactory for a component with given patten
*/
def getReleaseNotes(server, artifactoryPattern){
    println artifactoryPattern;
    downloadSpec = """{
           "files": [
            {
                   "pattern": ${artifactoryPattern},
                   "target": "Release_Notes_tmp.txt",
       	          "flat": "true"
              }
           ]
          }"""
     server.download spec: downloadSpec
   def componentRelNotesContent = readFile 'Release_Notes_tmp.txt'
   return componentRelNotesContent;
}

/**
*	Use this method for sending Commercial themed email notification - changes every quarter
*	status - Success | Failure
*	subjectName - Email subject - String
*	buildVersion - build version - String
*	attachmentPattern - Regex for files to be sent as attachments - Ex:: 'sprint-release-notes.txt', 'sprint-*.txt', 'artifact/*.txt'
*	attachBuildLog - true | false - Boolean
*	emailTo - List of recipients who should recieve mail - Comma seperated email ids as a string
*	urlArray - List of links to be available in email - Map
*	stageArray - List of stages with status - Map
**/
def sendEmailNotification(status, subjectJobName, buildVersion, attachmentPattern, attachBuildLog, emailTo, urlArray, stageArray){
	emailext attachLog: attachBuildLog, attachmentsPattern:attachmentPattern, body: generateEmailContent(status, stageArray, urlArray, buildVersion), subject: subjectJobName +' : '+status, to: emailTo;
}

/*
*	generates email content - Frozen theme
*	Input parameters
*	status
*	stageArray
*	urlArray
*	buildVersion
*/
def generateEmailContent(status, stageArray, urlArray,buildVersion){
	def changeUsers = changelist();
	def icons = ["14","2","3","4","5","13","7","12","9","10","11"];
	def dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
	def startDate = dateFormat.parse(env.build_start);
	def endDate = new Date();
	def tookTime = groovy.time.TimeCategory.minus(endDate,startDate).toString();
	def randomY = randomNum(2);
	def randomN = randomNum(2);
	def htmlContent = "";
	htmlContent += "<!doctype html><html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\"><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">";
	htmlContent += "<style>body{font-family:Arial;font-size:16px;}.hdcontent,.status a{font-size:16px;text-decoration: underline;}.status a,a img,img{text-decoration:none}.shell-body li,a{word-wrap:break-word}#bodyCell,#bodyTable,body{height:100%!important;margin:0;padding:0;width:100%!important}table{border-collapse:collapse}.hdcontent{width:60%;padding:10px}.status{height:100px;padding:10px 10px 0;border-radius:10px}.status a{color:#FFF}td{color:#FFF;}h3,h4{color:#E35F0B!important;letter-spacing:normal}.tabstyle{width:100px;height:20px;padding:10px;border-bottom:5px solid transparent;cursor:pointer}.tabstyle:hover{border-bottom:5px solid #fff}#templateBody,#templateFooter,#templateHeader{border-bottom:0}.circle-text{color:#707070;padding-left:25px}#outlook a,p{padding:0}#bodyCell,#templateBody,#templateHeader{background-color:#FFF;border-top:0}a img,img{border:0;outline:0}h1,h2,h3,h4,h5,h6{margin:0;padding:0}p{margin:1em 0}.ExternalClass,.ReadMsgBody{width:100%}.ExternalClass,.ExternalClass div,.ExternalClass font,.ExternalClass p,.ExternalClass span,.ExternalClass td{line-height:100%}h1,h2{line-height:125%;text-align:center;font-weight:700;font-style:normal}table,td{mso-table-lspace:0;mso-table-rspace:0}img{-ms-interpolation-mode:bicubic}a,blockquote,body,li,p,table,td{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a.devopsButton{display:block}.devopsImage{vertical-align:bottom}.devopsTextContent{word-break:break-word}.devopsTextContent img{height:auto!important}.devopsDividerBlock{table-layout:fixed!important}h1{color:#0bd0e2!important;font-size:30px;letter-spacing:-1px}h2{color:#202020!important;font-size:20px;letter-spacing:normal}h3,h4{line-height:125%;text-align:left;}h3{font-size:18px;font-style:normal;font-weight:700}h4{font-size:16px;font-style:normal;font-weight:400}#templatePreheader{background-color:#4caad8;border-top:0;border-bottom:0}.preheaderContainer .devopsTextContent,.preheaderContainer .devopsTextContent p{color:#202020;font-size:14px;line-height:125%;text-align:left}.preheaderContainer .devopsTextContent a{color:#202020;font-weight:400;text-decoration:underline}.headerContainer .devopsTextContent,.headerContainer .devopsTextContent p{color:#202020;font-size:15px;line-height:150%;text-align:center}.headerContainer .devopsTextContent a{color:#E35F0B;font-weight:400;text-decoration:underline},.bodyContainer .devopsTextContent,.bodyContainer .devopsTextContent p{color:#202020;font-size:15px;line-height:150%;text-align:left}.bodyContainer .devopsTextContent a{color:#E35F0B;font-weight:400;text-decoration:underline}#templateFooter{border-top:0}.footerContainer .devopsTextContent,.footerContainer .devopsTextContent p{color:#202020;font-size:16px;line-height:125%;text-align:center}.footerContainer .devopsTextContent a{color:#202020;font-weight:400;text-decoration:underline}@media only screen and (max-width:480px){a,blockquote,body,li,p,table,td{-webkit-text-size-adjust:none!important}body{width:100%!important;min-width:100%!important}#bodyCell{padding-top:10px!important}.templateContainer{max-width:600px!important;width:100%!important}.devopsImage{height:auto!important;width:100%!important}.devopsBoxedTextContentContainer,.devopsCaptionBottomContent,.devopsCaptionLeftImageContentContainer,.devopsCaptionLeftTextContentContainer,.devopsCaptionRightImageContentContainer,.devopsCaptionRightTextContentContainer,.devopsCaptionTopContent,.devopsCartContainer,.devopsImageCardLeftTextContentContainer,.devopsImageCardRightTextContentContainer,.devopsImageGroupContentContainer,.devopsRecContentContainer,.devopsTextContentContainer{max-width:100%!important;width:100%!important}.devopsBoxedTextContentContainer{min-width:100%!important}.devopsImageGroupContent{padding:9px!important}.devopsCaptionLeftContentOuter .devopsTextContent,.devopsCaptionRightContentOuter .devopsTextContent{padding-top:9px!important}.devopsCaptionBlockInner .devopsCaptionTopContent:last-child .devopsTextContent,.devopsImageCardTopImageContent{padding-top:18px!important}.devopsImageCardBottomImageContent{padding-bottom:9px!important}.devopsImageGroupBlockInner{padding-top:0!important;padding-bottom:0!important}.devopsImageGroupBlockOuter{padding-top:9px!important;padding-bottom:9px!important}.devopsBoxedTextContentColumn,.devopsTextContent{padding-right:18px!important;padding-left:18px!important}.devopsImageCardLeftImageContent,.devopsImageCardRightImageContent{padding-right:18px!important;padding-bottom:0!important;padding-left:18px!important}.mcpreview-image-uploader{display:none!important;width:100%!important}h1{font-size:24px!important;line-height:125%!important}h2{font-size:20px!important;line-height:125%!important}.devopsBoxedTextContentContainer .devopsTextContent,.devopsBoxedTextContentContainer .devopsTextContent p,h3{font-size:18px!important;line-height:125%!important}h4{font-size:16px!important;line-height:125%!important}#templatePreheader{display:block!important}.preheaderContainer .devopsTextContent,.preheaderContainer .devopsTextContent p{font-size:14px!important;line-height:115%!important}.bodyContainer .devopsTextContent,.bodyContainer .devopsTextContent p,.headerContainer .devopsTextContent,.headerContainer .devopsTextContent p{font-size:18px!important;line-height:125%!important}.footerContainer .devopsTextContent,.footerContainer .devopsTextContent p{font-size:14px!important;line-height:115%!important}}.shell-wrap{width:90%;margin:0 auto;box-shadow:0 0 30px rgba(0,0,0,.4);-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;float:left}.shell-body{margin:0;padding:5px;list-style:none;background:#141414;color:#45D40C;font:.8em 'Andale Mono',Consolas,'Courier New';line-height:1.6em;-webkit-border-bottom-right-radius:3px;-webkit-border-bottom-left-radius:3px;-moz-border-radius-bottomright:3px;-moz-border-radius-bottomleft:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.shell-body li{position:relative;padding:0 0 0 15px}</style>";
	htmlContent += "</head><body leftmargin=\"0\" marginwidth=\"0\" topmargin=\"0\" marginheight=\"0\" offset=\"0\"><center><table align=\"center\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" height=\"100%\" width=\"100%\" id=\"bodyTable\"><tr><td align=\"center\" valign=\"top\" id=\"bodyCell\">";
	htmlContent += "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\"><tr><td align=\"center\" valign=\"top\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" id=\"templateHeader\"><tr> <td align=\"center\" valign=\"top\"> <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"80%\" class=\"templateContainer\"><tr><td valign=\"top\" class=\"headerContainer\" style=\"padding-top:10px; padding-bottom:10px;\"><table class=\"devopsImageBlock\" style=\"min-width:100%;\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" border=\"0\"><tbody class=\"devopsImageBlockOuter\"><tr><td class=\"devopsImageContent\" style=\"padding-right: 9px; padding-left: 9px; padding-top: 0; padding-bottom: 0; text-align:center;\" valign=\"top\">";
	htmlContent += "<!-- Image check -->";
	if (status.toUpperCase() == 'FAILURE') {
		htmlContent += "<img alt=\"\" src=\"https://s3.amazonaws.com/devops-lite/Frozen/Sad-${randomN}.png\" style=\"padding-bottom: 0; display: inline !important; vertical-align: bottom;\" class=\"devopsImage\" width=\"300\" align=\"middle\">";
	}else{
		htmlContent += "<img alt=\"\" src=\"https://s3.amazonaws.com/devops-lite/Frozen/Happy-${randomY}.png\" style=\"padding-bottom: 0; display: inline !important; vertical-align: bottom;\" class=\"devopsImage\" width=\"300\" align=\"middle\">";
	}
	htmlContent += "</td></tr></tbody></table></td></tr></table></td></tr></table></td></tr><tr><td align=\"center\" valign=\"top\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" id=\"templateHeader\"><tr> <td align=\"center\" valign=\"top\"> <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"90%\" class=\"templateContainer\"><tr><td valign=\"top\" class=\"headerContainer\" style=\"padding-top:10px; padding-bottom:10px;\">";
	htmlContent += "<!-- Table color -->";
	if (status.toUpperCase() == 'FAILURE') {
		htmlContent += "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" align=\"center\" class=\"status\" style=\"background-color:#F00\" id=\"status\">";
	}else{
		htmlContent += "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" align=\"center\" class=\"status\" style=\"background-color:#0C6\" id=\"status\">";
	}
	htmlContent += "<tr><td class=\"hdcontent\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" align=\"left\"><tr>";
	htmlContent += "<td colspan=\"3\">${env.JOB_NAME}</td></tr><tr><td>Build version</td><td>:</td><td>${buildVersion}</td></tr><tr><td>Changes by</td><td>:</td>";
	htmlContent += "<td>${changeUsers}</td></tr></table></td><td class=\"hdright\"><table border=\"0\" cellpadding=\"5px\" cellspacing=\"0\" align=\"right\"><tr><td><img src=\"https://s3.amazonaws.com/devops-lite/clock_1.png\" width=\"20px\" height=\"20px\" /></td>";
	htmlContent += "<td>${tookTime}</td></tr><tr><td><img src=\"https://s3.amazonaws.com/devops-lite/Clock_2.png\" width=\"20px\" height=\"20px\" /></td>";
	htmlContent += "<td>${env.build_start}</td></tr></table></td></tr><tr><td colspan=\"3\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" align=\"left\"><tr>";
	for (it2 in mapToList(urlArray)) {
		key = it2[0]
		value = it2[1]
		htmlContent += "<td class=\"tabstyle\"><a href=\""+value+"\">"+key+"</a></td>";
	}
	htmlContent += "</tr></table></td></tr></table></td></tr></table></td></tr></table></td></tr>";
	def pipelinehtml = "<tr><td align=\"center\" valign=\"top\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" id=\"templateHeader\"><tr> <td align=\"center\" valign=\"top\"> <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"80%\" class=\"templateContainer\"><tr><td valign=\"top\" class=\"headerContainer\" style=\"padding-top:10px; padding-bottom:10px;\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"80%\" align=\"center\">";
	def counter = 0;
	for (it2 in mapToList(stageArray)) {
		key = it2[0];
		value = it2[1];
		def color = "grey";
		if(value.toUpperCase() == "SUCCESS")
			color = "green";
		else if(value.toUpperCase() == "FAILURE")
			color = 'red';
		if(counter==0 || counter==6 || counter==12){ pipelinehtml += "<tr>"; }
		pipelinehtml += "<td align=\"center\"><div class=\"circle\"><img src=\"https://s3.amazonaws.com/devops-lite/Frozen/${icons[counter % icons.size()]}/${color}.png\"/></div><div class=\"circle-text\">${key}</div></td>";
		if (counter != stageArray.size() - 1)
			pipelinehtml += "<td width=\"75px\" align=\"center\"><img src=\"https://s3.amazonaws.com/devops-lite/cline.png\"/></td>";
		counter++;
		if((counter==6) || (counter==12) ||(counter==18) || (counter == stageArray.size())){ pipelinehtml += "</tr>"; }
	}
	pipelinehtml += "</tr></table></td></tr></table></td></tr></table></td></tr>";
	htmlContent += pipelinehtml;
	htmlContent += "</tbody> </table> </td></tr>";
	htmlContent += "<tr><td> <table class=\"templateContainer\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"> <tbody> <tr> <td align=\"center\" valign=\"bottom\" class=\"circle-text\">For more details about GWIT, <a href=\"https://share.connect.aig/teams/GWIT/Charlotte/SitePages/Home.aspx\">Click here</a></td></tr></tbody> </table></td></tr>";
	htmlContent += "<tr> <td align=\"center\" valign=\"top\" style=\"padding-top: 10px;\"> <table width=\"100%\" id=\"templateFooter\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"> <tbody> <tr> <td align=\"center\" valign=\"top\"> <table width=\"1200\" class=\"templateContainer\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"> <tbody> <tr> <td align=\"center\" valign=\"top\"><img width=\"1200\" height=\"40\" class=\"devopsImage\" style=\"display: block;\" src=\"https://s3.amazonaws.com/devops-lite/Frozen/footer-top.png\"></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr> <tr> <td align=\"center\" valign=\"top\" style=\"padding-bottom: 10px;\"> <table width=\"100%\" id=\"templateFooter\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"> <tbody> <tr> <td align=\"center\" valign=\"top\"> <table width=\"1200\" class=\"templateContainer\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"> <tbody> <tr> <td align=\"center\" valign=\"top\"><img width=\"1200\" height=\"40\" class=\"devopsImage\" style=\"display: block;\" src=\"https://s3.amazonaws.com/devops-lite/Frozen/footer-bottom.png\"></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr>";
	htmlContent += "</table></td></tr></table></center></body></html>";
	return htmlContent;
}


/**
 *	Use this method for sending Commercial themed email notification along with console log view in mail body - changes every quarter
 *	status - Success | Failure
 *	subjectName - Email subject - String
 *	buildVersion - build version - String
 *	attachmentPattern - Regex for files to be sent as attachments - Ex:: 'sprint-release-notes.txt', 'sprint-*.txt', 'artifact/*.txt'
 *	attachBuildLog - true | false - Boolean
 *	emailTo - List of recipients who should recieve mail - Comma seperated email ids as a string
 *	urlArray - List of links to be available in email - Map
 *	stageArray - List of stages with status - Map
 **/
 def sendEmailNotification(status, subjectJobName, buildVersion, attachmentPattern, attachBuildLog, emailTo, urlArray, stageArray,consolelog){
	 emailext attachLog: attachBuildLog, attachmentsPattern:attachmentPattern, body: generateEmailContent(status, stageArray, urlArray, buildVersion,consolelog), subject: subjectJobName +' : '+status, to: emailTo;
 }
 
 /*
 *	generates email content - Frozen theme
 *	Input parameters
 *	status
 *	stageArray
 *	urlArray
 *	buildVersion
 *	consolelog
 */
 def generateEmailContent(status, stageArray, urlArray,buildVersion,consolelog){
	 def changeUsers = changelist();
	 def icons = ["14","2","3","4","5","13","7","12","9","10","11"];
	 def dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
	 def startDate = dateFormat.parse(env.build_start);
	 def endDate = new Date();
	 def tookTime = groovy.time.TimeCategory.minus(endDate,startDate).toString();
	 def randomY = randomNum(2);
	 def randomN = randomNum(2);
	 def htmlContent = "";
	 htmlContent += "<!doctype html><html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\"><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">";
	 htmlContent += "<style>body{font-family:Arial;font-size:16px;}.hdcontent,.status a{font-size:16px;text-decoration: underline;}.status a,a img,img{text-decoration:none}.shell-body li,a{word-wrap:break-word}#bodyCell,#bodyTable,body{height:100%!important;margin:0;padding:0;width:100%!important}table{border-collapse:collapse}.hdcontent{width:60%;padding:10px}.status{height:100px;padding:10px 10px 0;border-radius:10px}.status a{color:#FFF}td{color:#FFF;}h3,h4{color:#E35F0B!important;letter-spacing:normal}.tabstyle{width:100px;height:20px;padding:10px;border-bottom:5px solid transparent;cursor:pointer}.tabstyle:hover{border-bottom:5px solid #fff}#templateBody,#templateFooter,#templateHeader{border-bottom:0}.circle-text{color:#707070;padding-left:25px}#outlook a,p{padding:0}#bodyCell,#templateBody,#templateHeader{background-color:#FFF;border-top:0}a img,img{border:0;outline:0}h1,h2,h3,h4,h5,h6{margin:0;padding:0}p{margin:1em 0}.ExternalClass,.ReadMsgBody{width:100%}.ExternalClass,.ExternalClass div,.ExternalClass font,.ExternalClass p,.ExternalClass span,.ExternalClass td{line-height:100%}h1,h2{line-height:125%;text-align:center;font-weight:700;font-style:normal}table,td{mso-table-lspace:0;mso-table-rspace:0}img{-ms-interpolation-mode:bicubic}a,blockquote,body,li,p,table,td{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a.devopsButton{display:block}.devopsImage{vertical-align:bottom}.devopsTextContent{word-break:break-word}.devopsTextContent img{height:auto!important}.devopsDividerBlock{table-layout:fixed!important}h1{color:#0bd0e2!important;font-size:30px;letter-spacing:-1px}h2{color:#202020!important;font-size:20px;letter-spacing:normal}h3,h4{line-height:125%;text-align:left;}h3{font-size:18px;font-style:normal;font-weight:700}h4{font-size:16px;font-style:normal;font-weight:400}#templatePreheader{background-color:#4caad8;border-top:0;border-bottom:0}.preheaderContainer .devopsTextContent,.preheaderContainer .devopsTextContent p{color:#202020;font-size:14px;line-height:125%;text-align:left}.preheaderContainer .devopsTextContent a{color:#202020;font-weight:400;text-decoration:underline}.headerContainer .devopsTextContent,.headerContainer .devopsTextContent p{color:#202020;font-size:15px;line-height:150%;text-align:center}.headerContainer .devopsTextContent a{color:#E35F0B;font-weight:400;text-decoration:underline},.bodyContainer .devopsTextContent,.bodyContainer .devopsTextContent p{color:#202020;font-size:15px;line-height:150%;text-align:left}.bodyContainer .devopsTextContent a{color:#E35F0B;font-weight:400;text-decoration:underline}#templateFooter{border-top:0}.footerContainer .devopsTextContent,.footerContainer .devopsTextContent p{color:#202020;font-size:16px;line-height:125%;text-align:center}.footerContainer .devopsTextContent a{color:#202020;font-weight:400;text-decoration:underline}@media only screen and (max-width:480px){a,blockquote,body,li,p,table,td{-webkit-text-size-adjust:none!important}body{width:100%!important;min-width:100%!important}#bodyCell{padding-top:10px!important}.templateContainer{max-width:600px!important;width:100%!important}.devopsImage{height:auto!important;width:100%!important}.devopsBoxedTextContentContainer,.devopsCaptionBottomContent,.devopsCaptionLeftImageContentContainer,.devopsCaptionLeftTextContentContainer,.devopsCaptionRightImageContentContainer,.devopsCaptionRightTextContentContainer,.devopsCaptionTopContent,.devopsCartContainer,.devopsImageCardLeftTextContentContainer,.devopsImageCardRightTextContentContainer,.devopsImageGroupContentContainer,.devopsRecContentContainer,.devopsTextContentContainer{max-width:100%!important;width:100%!important}.devopsBoxedTextContentContainer{min-width:100%!important}.devopsImageGroupContent{padding:9px!important}.devopsCaptionLeftContentOuter .devopsTextContent,.devopsCaptionRightContentOuter .devopsTextContent{padding-top:9px!important}.devopsCaptionBlockInner .devopsCaptionTopContent:last-child .devopsTextContent,.devopsImageCardTopImageContent{padding-top:18px!important}.devopsImageCardBottomImageContent{padding-bottom:9px!important}.devopsImageGroupBlockInner{padding-top:0!important;padding-bottom:0!important}.devopsImageGroupBlockOuter{padding-top:9px!important;padding-bottom:9px!important}.devopsBoxedTextContentColumn,.devopsTextContent{padding-right:18px!important;padding-left:18px!important}.devopsImageCardLeftImageContent,.devopsImageCardRightImageContent{padding-right:18px!important;padding-bottom:0!important;padding-left:18px!important}.mcpreview-image-uploader{display:none!important;width:100%!important}h1{font-size:24px!important;line-height:125%!important}h2{font-size:20px!important;line-height:125%!important}.devopsBoxedTextContentContainer .devopsTextContent,.devopsBoxedTextContentContainer .devopsTextContent p,h3{font-size:18px!important;line-height:125%!important}h4{font-size:16px!important;line-height:125%!important}#templatePreheader{display:block!important}.preheaderContainer .devopsTextContent,.preheaderContainer .devopsTextContent p{font-size:14px!important;line-height:115%!important}.bodyContainer .devopsTextContent,.bodyContainer .devopsTextContent p,.headerContainer .devopsTextContent,.headerContainer .devopsTextContent p{font-size:18px!important;line-height:125%!important}.footerContainer .devopsTextContent,.footerContainer .devopsTextContent p{font-size:14px!important;line-height:115%!important}}.shell-wrap{width:90%;margin:0 auto;box-shadow:0 0 30px rgba(0,0,0,.4);-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;float:left}.shell-body{margin:0;padding:5px;list-style:none;background:#141414;color:#45D40C;font:.8em 'Andale Mono',Consolas,'Courier New';line-height:1.6em;-webkit-border-bottom-right-radius:3px;-webkit-border-bottom-left-radius:3px;-moz-border-radius-bottomright:3px;-moz-border-radius-bottomleft:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.shell-body li{position:relative;padding:0 0 0 15px}</style>";
	 htmlContent += "</head><body leftmargin=\"0\" marginwidth=\"0\" topmargin=\"0\" marginheight=\"0\" offset=\"0\"><center><table align=\"center\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" height=\"100%\" width=\"100%\" id=\"bodyTable\"><tr><td align=\"center\" valign=\"top\" id=\"bodyCell\">";
	 htmlContent += "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\"><tr><td align=\"center\" valign=\"top\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" id=\"templateHeader\"><tr> <td align=\"center\" valign=\"top\"> <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"80%\" class=\"templateContainer\"><tr><td valign=\"top\" class=\"headerContainer\" style=\"padding-top:10px; padding-bottom:10px;\"><table class=\"devopsImageBlock\" style=\"min-width:100%;\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" border=\"0\"><tbody class=\"devopsImageBlockOuter\"><tr><td class=\"devopsImageContent\" style=\"padding-right: 9px; padding-left: 9px; padding-top: 0; padding-bottom: 0; text-align:center;\" valign=\"top\">";
	 htmlContent += "<!-- Image check -->";
	 if (status.toUpperCase() == 'FAILURE') {
		 htmlContent += "<img alt=\"\" src=\"https://s3.amazonaws.com/devops-lite/Frozen/Sad-${randomN}.png\" style=\"padding-bottom: 0; display: inline !important; vertical-align: bottom;\" class=\"devopsImage\" width=\"300\" align=\"middle\">";
	 }else{
		 htmlContent += "<img alt=\"\" src=\"https://s3.amazonaws.com/devops-lite/Frozen/Happy-${randomY}.png\" style=\"padding-bottom: 0; display: inline !important; vertical-align: bottom;\" class=\"devopsImage\" width=\"300\" align=\"middle\">";
	 }
	 htmlContent += "</td></tr></tbody></table></td></tr></table></td></tr></table></td></tr><tr><td align=\"center\" valign=\"top\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" id=\"templateHeader\"><tr> <td align=\"center\" valign=\"top\"> <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"90%\" class=\"templateContainer\"><tr><td valign=\"top\" class=\"headerContainer\" style=\"padding-top:10px; padding-bottom:10px;\">";
	 htmlContent += "<!-- Table color -->";
	 if (status.toUpperCase() == 'FAILURE') {
		 htmlContent += "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" align=\"center\" class=\"status\" style=\"background-color:#F00\" id=\"status\">";
	 }else{
		 htmlContent += "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" align=\"center\" class=\"status\" style=\"background-color:#0C6\" id=\"status\">";
	 }
	 htmlContent += "<tr><td class=\"hdcontent\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" align=\"left\"><tr>";
	 htmlContent += "<td colspan=\"3\">${env.JOB_NAME}</td></tr><tr><td>Build version</td><td>:</td><td>${buildVersion}</td></tr><tr><td>Changes by</td><td>:</td>";
	 htmlContent += "<td>${changeUsers}</td></tr></table></td><td class=\"hdright\"><table border=\"0\" cellpadding=\"5px\" cellspacing=\"0\" align=\"right\"><tr><td><img src=\"https://s3.amazonaws.com/devops-lite/clock_1.png\" width=\"20px\" height=\"20px\" /></td>";
	 htmlContent += "<td>${tookTime}</td></tr><tr><td><img src=\"https://s3.amazonaws.com/devops-lite/Clock_2.png\" width=\"20px\" height=\"20px\" /></td>";
	 htmlContent += "<td>${env.build_start}</td></tr></table></td></tr><tr><td colspan=\"3\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" align=\"left\"><tr>";
	 for (it2 in mapToList(urlArray)) {
		 key = it2[0]
		 value = it2[1]
		 htmlContent += "<td class=\"tabstyle\"><a href=\""+value+"\">"+key+"</a></td>";
	 }
	 htmlContent += "</tr></table></td></tr></table></td></tr></table></td></tr></table></td></tr>";
	 def pipelinehtml = "<tr><td align=\"center\" valign=\"top\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" id=\"templateHeader\"><tr> <td align=\"center\" valign=\"top\"> <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"80%\" class=\"templateContainer\"><tr><td valign=\"top\" class=\"headerContainer\" style=\"padding-top:10px; padding-bottom:10px;\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"80%\" align=\"center\">";
	 def counter = 0;
	 for (it2 in mapToList(stageArray)) {
		 key = it2[0];
		 value = it2[1];
		 def color = "grey";
		 if(value.toUpperCase() == "SUCCESS")
			 color = "green";
		 else if(value.toUpperCase() == "FAILURE")
			 color = 'red';
		 if(counter==0 || counter==6 || counter==12){ pipelinehtml += "<tr>"; }
		 pipelinehtml += "<td align=\"center\"><div class=\"circle\"><img src=\"https://s3.amazonaws.com/devops-lite/Frozen/${icons[counter % icons.size()]}/${color}.png\"/></div><div class=\"circle-text\">${key}</div></td>";
		 if (counter != stageArray.size() - 1)
			 pipelinehtml += "<td width=\"75px\" align=\"center\"><img src=\"https://s3.amazonaws.com/devops-lite/cline.png\"/></td>";
		 counter++;
		 if((counter==6) || (counter==12) ||(counter==18) || (counter == stageArray.size())){ pipelinehtml += "</tr>"; }
	 }
	 pipelinehtml += "</tr></table></td></tr></table></td></tr></table></td></tr>";
	 htmlContent += pipelinehtml;
	 htmlContent += "</tbody> </table> </td></tr>";
	 htmlContent += "<tr><td> <table class=\"templateContainer\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"> <tbody> <tr> <td align=\"center\" valign=\"bottom\" class=\"circle-text\">"+consolelog+"</td></tr></tbody> </table></td></tr>";
	 htmlContent += "<tr><td> <table class=\"templateContainer\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"> <tbody> <tr> <td align=\"center\" valign=\"bottom\" class=\"circle-text\">For more details about GWIT, <a href=\"https://share.connect.aig/teams/GWIT/Charlotte/SitePages/Home.aspx\">Click here</a></td></tr></tbody> </table></td></tr>";
	 htmlContent += "<tr> <td align=\"center\" valign=\"top\" style=\"padding-top: 10px;\"> <table width=\"100%\" id=\"templateFooter\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"> <tbody> <tr> <td align=\"center\" valign=\"top\"> <table width=\"1200\" class=\"templateContainer\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"> <tbody> <tr> <td align=\"center\" valign=\"top\"><img width=\"1200\" height=\"40\" class=\"devopsImage\" style=\"display: block;\" src=\"https://s3.amazonaws.com/devops-lite/Frozen/footer-top.png\"></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr> <tr> <td align=\"center\" valign=\"top\" style=\"padding-bottom: 10px;\"> <table width=\"100%\" id=\"templateFooter\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"> <tbody> <tr> <td align=\"center\" valign=\"top\"> <table width=\"1200\" class=\"templateContainer\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"> <tbody> <tr> <td align=\"center\" valign=\"top\"><img width=\"1200\" height=\"40\" class=\"devopsImage\" style=\"display: block;\" src=\"https://s3.amazonaws.com/devops-lite/Frozen/footer-bottom.png\"></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr>";
	 htmlContent += "</table></td></tr></table></center></body></html>";
	 return htmlContent;
}

@NonCPS
def mapToList(depmap) {
	def dlist = []
	for (entry in depmap) {
		dlist.add([entry.key, entry.value])
	}
	dlist
}

import java.util.Random
@NonCPS
def randomNum(max){
	Random rand = new Random();
	return rand.nextInt(max);
}

@NonCPS
def changelist() {
	def changes = [] as Set
	currentBuild.changeSets.each { set ->
		set.each { entry ->
			changes.add("${entry.author.fullName}")
		}
	}
	return changes.join(", ")
}


def publishArtifactsToBuildScreen(manager,urlArray){
	for (it2 in mapToList(urlArray)) {
		key = it2[0]
		value = it2[1]
		manager.createSummary("green.gif").appendText("<h1>${key} : <a href=\"${value}\">${value}</a></h1>", false, false, false, "blue")	
	}
}

/**
* Method used to update the Build promotion history for QA, Model and Prod deployment repos
* And change deployment.properties file status
*/
def updateBuildPromotionHistory(nodeOs, currentPromotionDetails, projectPrefix){
          def promotionHistoryFile = 'Promotion_History/' + env.APP_ENVIRONMENT_TYPE.toLowerCase() + '-deployment.txt'
          def Deployment_HistoryOrig = readFile(promotionHistoryFile)

          def date = new Date();
          def header = "--Deployment Date : " + date +"---  Build#--" + env.BUILD_NUMBER + "\n"
          header = header + "\n\t Component \t\t\t\t\t\t Version  \n"
          header = header + "--------------------------------------------------------------------------------------------------   ------------------------------------------------\n"
          def consolidatedNotes = header + currentPromotionDetails + "\n" + Deployment_HistoryOrig ;
          writeFile file:promotionHistoryFile,text:consolidatedNotes
          def deploymentPropertiesFile = projectPrefix+ '-' + env.APP_ENVIRONMENT_TYPE.toLowerCase()  + '-deployment.properties'
          def f = readFile deploymentPropertiesFile
          writeFile file:deploymentPropertiesFile,text:f.replace('STATUS=SUBMITTED','STATUS=COMPLETED');
          try{
		if(nodeOs == 'WIN') {
			sshagent(credentials: ['ssh_devopspipeline_credentials']) {
			      bat "git pull origin master";
			      bat "git commit -am 'Update the property files'";
			      bat "git push -u origin master";
			}
		}else{
			sshagent(credentials: ['ssh_devopspipeline_credentials']) {
			      sh "git pull origin master";
			      sh "git commit -am 'Update the property files'";
			      sh "git push -u origin master";
			}
		}
           }catch(Exception ex){
              println "Error occured while updating to Github"
              throw ex;
            }
}

/*----------------------------------------------------------------------------------------------------
	Function Name	: updateBuildPromotionHistoryAndStatus
	Description		: Updates promotion history CSV file with current promotion history details, 
						when header columns, filename and latest history are passed in this method
					Updates status in deployment properties to completed
	Author Name		: Ramya Vijayakumar(rvijayak)
	Parameters		: 
			nodeOs           - operating system of jenkins node
			promotionDetailsHeader - comma separated header column names(can be customized for your project). End with a \n
					sample - def promotionDetailsHeader='ComponentName,BuildNo,PromotedBuildNo,UserName,UserId,EmailID,Status,DeploymentDate\n';
			currentPromotionDetails   - multiline comma separated lines detailing current promotion details. End each line with a \n
					sample - currentPromotionDetails=[currentPromotionDetails,componentName,',',env.BUILD_NUMBER,',',versionToBeDeployed,',',env.BUILD_USER,',',env.BUILD_USER_ID,',',env.BUILD_USER_EMAIL,',',status,',',dateAndTime,'\n'].join('')	
			promotionHistoryFile     - file to write promotion history into. This is updated to github
			deploymentPropertiesFile - Deployment properties file name
	Return Parameter: NA
	Version History		Date Modified		Owner			Comments
	Intial Version		5/1/2018		Ramya			Initial version
	Update status		5/22/2018		Ramya			Update Status in addition to promotion details
	------------------------------------------------------------------------------------------------------*/
def updateBuildPromotionHistoryAndStatus(nodeOs,promotionDetailsHeader,currentPromotionDetails, promotionHistoryFile,deploymentPropertiesFile){
	try{
		if(deploymentPropertiesFile != null){ 
			def deploymentPropertiesStr = readFile deploymentPropertiesFile
			writeFile file:deploymentPropertiesFile,text:deploymentPropertiesStr.replace('STATUS=SUBMITTED','STATUS=COMPLETED');
		}

		def prevPromotionHistory = readFile(promotionHistoryFile);
		//Add header if it a first time promotion and promotion file is blank
		if(prevPromotionHistory == null || prevPromotionHistory.trim().equals("")){
			prevPromotionHistory = promotionDetailsHeader;
		}
		def consolidatedNotes 	= [prevPromotionHistory,currentPromotionDetails].join('');
		writeFile file:promotionHistoryFile,text:consolidatedNotes;
    	
    	println "******* Current Promotion Details *********"
    	println currentPromotionDetails
    	
		if(nodeOs == 'WIN') {
			sshagent(credentials: ['ssh_devopspipeline_credentials']) {
				bat "git pull origin master";
				bat "git commit -am 'Update promotion history and status details'";
				bat "git push -u origin master";
			}
		}else{
			sshagent(credentials: ['ssh_devopspipeline_credentials']) {
				sh "git pull origin master";
				sh "git commit -am 'Update promotion history and status details'";
				sh "git push -u origin master";
			}
		}
    }catch(Exception ex){
        println "Error occured while updating to Github in updateBuildPromotionHistoryAndStatus "+ex     
    }
}
/*
	runs sonar code analysis
*/
def doCodeAnalysis(node_os, sonarRunner, sonarQubeURL, sonarProjectKey, sonarProjectName, buildVersion, sonarSource, branchName, sonarLogin, skipSonarBuildBreaker, jdkVersion){
    try{
    	if(node_os == 'WIN')
	    	bat "${sonarRunner} -Dsonar.inclusions=**/*.java -Dsonar.host.url=$sonarQubeURL -Dsonar.projectKey=$sonarProjectKey -Dsonar.projectName=$sonarProjectName -Dsonar.projectVersion=$buildVersion -Dsonar.sources=$sonarSource -Dsonar.branch=$branchName  -Dsonar.login=${sonarLogin} -Dsonar.buildbreaker.skip=${skipSonarBuildBreaker}"; 
	    else{
	    	withEnv([
	          "JAVA_HOME=${jdkVersion}"
	        ]) {
	    		sh "${sonarRunner} -Dsonar.inclusions=**/*.java -Dsonar.host.url=$sonarQubeURL -Dsonar.projectKey=$sonarProjectKey -Dsonar.projectName=$sonarProjectName -Dsonar.projectVersion=$buildVersion -Dsonar.sources=$sonarSource -Dsonar.branch=$branchName  -Dsonar.login=${sonarLogin} -Dsonar.buildbreaker.skip=${skipSonarBuildBreaker}";
	    	}
	    }
	    }catch(Exception e){
	    	println "Caught: ${e}";
	    	throw e;
	    }
}

 
//BUILD_USER- firstname , lastname  BUILD_USER_ID = R1-Core ID 

def getBuildUserDetails(){
	if(node_os=="LINUX")
	  wrap([$class: 'BuildUser']) { 
      env.BUILD_USER= "${BUILD_USER}" 
	  env.BUILD_USER=env.BUILD_USER.replace(','," ");
      env.BUILD_USER_ID= "${BUILD_USER_ID}" 
      env.BUILD_USER_EMAIL= "${BUILD_USER_EMAIL}"
	}
	if(node_os=="WIN")
	 wrap([$class: 'BuildUser']) { 
      env.BUILD_USER	= BUILD_USER 
      env.BUILD_USER_ID	= BUILD_USER_ID 
      env.BUILD_USER_EMAIL = BUILD_USER_EMAIL
	}
}

def getBuildUserDetails(node_os){
	if(node_os=="LINUX")
	  wrap([$class: 'BuildUser']) { 
      env.BUILD_USER= "${BUILD_USER}" 
	  env.BUILD_USER=env.BUILD_USER.replace(','," ");
      env.BUILD_USER_ID= "${BUILD_USER_ID}" 
      env.BUILD_USER_EMAIL= "${BUILD_USER_EMAIL}"
	}
	if(node_os=="WIN")
	 wrap([$class: 'BuildUser']) { 
      env.BUILD_USER	= BUILD_USER 
      env.BUILD_USER_ID	= BUILD_USER_ID 
      env.BUILD_USER_EMAIL = BUILD_USER_EMAIL
	}
}


/*----------------------------------------------------------------------------------------------------
	Function Name	: readFile
	Description		: Read different file type
	Author Name		: Saravanan Govindarajalu (sagovind)
	Parameters		: 
			fileType 	--> File type. eg. JSON, Properties
			fileName	-->	Absolute file path		
	Return Parameter: File object
	Version History		Date Modified	Owner			Comments
	Intial Version		3/31/2018		Saravanan		Read file only if exists
	------------------------------------------------------------------------------------------------------*/

	def readFile(fileType,fileName){
		def fileObject;
		if (fileExists(fileName)){
			if(fileType == 'Properties'){
				fileObject 	= 	readProperties file: fileName;
			}
			if(fileType == 'JSON'){
				fileObject 	= 	readJSON file: fileName;
			}
			return fileObject;
		}else{
			throw new Exception("File Not Found ["+fileName+"]")
		}
	}
	
	
	/*----------------------------------------------------------------------------------------------------
	Function Name	: sonarCodeAnalysis
	Description		: Code analysis using sonar.properties file
	Author Name		: Saravanan Govindarajalu (sagovind)
	Parameters		: 
			nodeOs 			--> Jenkins node operating system version (e.g., WIN)
			sonarRunner		-->	Sonar install path
			sonarPropFile	--> Define all sonar flags in a property file
			jdkVersion		-->	JDK install path
	Return Parameter: None
	Version History		Date Modified	Owner			Comments
	Intial Version		3/31/2018		Saravanan		Added new function to use sonar.properties file
														instead of individual flags
	------------------------------------------------------------------------------------------------------*/
	def sonarCodeAnalysis(nodeOs,sonarRunner,sonarPropFile,jdkVersion){
		//validate the sonar property file exists or not
		if (fileExists(sonarPropFile)){
			if(nodeOs == 'WIN'){
				bat "${sonarRunner} -Dproject.settings=${sonarPropFile}"; 
			}else{
				withEnv(["JAVA_HOME=${jdkVersion}"]) {
					sh "${sonarRunner} -Dproject.settings=${sonarPropFile}";
				}
			}
		}else{
			// throw exception if the file not found
			throw new Exception("File Not Found "+sonarPropFile);
		}
	}

	/*----------------------------------------------------------------------------------------------------
	Function Name	: createDir
	Description		: Create directory based on the operating system	
	Author Name		: Saravanan Govindarajalu (sagovind)
	Parameters		: 
			nodeOs 	--> Jenkins node operating system version (e.g., WIN)
			dirName	--> Directoy name to te created
	Return Parameter: Returns the directory name
	Version History		Date Modified	Owner			Comments
	Intial Version		3/31/2018		Saravanan		Added new function to create a dir if not exists
	------------------------------------------------------------------------------------------------------*/
	def createDir(nodeOs,dirName){
		if(nodeOs == 'WIN'){ 
			bat "IF NOT EXIST ${dirName} mkdir ${dirName}" 
		}else{ 
			sh "[[ ! -d ${dirName} ]] && mkdir -p ${dirName}"
		}
		return dirName;
	}

	/*----------------------------------------------------------------------------------------------------
	Function Name	: replaceStr
	Description		: Replace a string in a file
	Author Name		: Saravanan Govindarajalu (sagovind)
	Parameters		: 
			fileName 	--> Absolute file path
			searchStr	--> String to search and replace
			replaceStr	--> String to repace.
	Return Parameter: Returns the directory name
	Version History		Date Modified	Owner			Comments
	Intial Version		3/31/2018		Saravanan		Replace the string if file exists
	------------------------------------------------------------------------------------------------------*/
	def replaceStr(fileName,searchStr,replaceStr){
		if (fileExists(fileName)){
			def objfile 	= readFile fileName
			writeFile file:fileName,text:objfile.replace(searchStr,replaceStr);
		}else{
			throw new Exception("File Not Found ["+fileName+"]")
		}
	}
	
	/*-----------------------------------------------------------------------------------------------------
	Function Name :getKeyValueFromVault
	Description	  :get value from vault for key passed in the argument
	Parameters 	  : 
			vault_app_path  : path in which app details are in vault eg :-'general-insurance/personal Insurance/warranty
			vault_cred	 	: ROLE ID created and configured in jenkins eg :- 'gi-vault-app-role'
			vault_key		: give the key value you wanted to access eg:- 'accesskey'
	Return 		  :
			returnKeyValue  : keyValue from  Vault 
			
	Version History		Date Modified	Owner			Comments
	Intial Version		06/01/2018		viknesh			to get the values from vault
	------------------------------------------------------------------------------------------------------*/

	def getKeyValueFromVault(vault_cred,vault_app_path,vault_key){
		def returnKeyValue = "";
		try{
		def secrets = [[$class: 'VaultSecret', path: vault_app_path, secretValues: [[$class: 'VaultSecretValue', envVar: 'vaultValue', vaultKey: vault_key]]]]
		def configuration = [$class: 'VaultConfiguration', vaultCredentialId: vault_cred];
		wrap([$class: 'VaultBuildWrapper', configuration: configuration, vaultSecrets: secrets]) {
                         returnKeyValue=env.vaultValue;
        }
		}
		catch(Exception e){
			println e;
			throw new Exception("Exception in getting the return value from vault METHOD : getKeyValueFromVault")
		}
		return returnKeyValue;
	}


return this;
```
/*
* @file: Jenkinsfile
* @brief: Jenkins pipeline for ael-policy-autobooker-dashboard-5416
* @author:
* @created:07-09-2018
* @modified:
*/
//[LIBRARIES]
//@Library(['tpam-shared-library']) _
import groovy.io.FileType.*;
// Runtime
rtUnitTest=false;
_nodeOs = "";
_linux = "LINUX";
_windows = "WIN";
/*[GIT]*/
_gitCredentialId = "ssh_devopspipeline_credentials";
_gitPipelineRepository = "[email protected]:commercial-it-config/devops-ael-policy-autobooker-dashboard-dev-ci-cd-5416.git";
_gitPipelineRepositoryBranch = "master";
_gitProjectRepository = "";
_gitProjectRepositoryBranch = "";
/*[STAGES]*/
_stageArray = [:];
/*[STATES]*/
_success = "SUCCESS";
_failure = "FAILURE";
_notStarted = "NOT STARTED";
_unstable = "UNSTABLE";
/*[MISC]*/
_dirPipelineRepo = "pipeline-dir";
_dirProjectRepo = "project-dir";
_pipelinePropertyFile = "pipeline.properties";
_pipelineProps = "";
_buildVersion = "";
_commonUtils = ""
//UNICODE
_unicodeAnchor = "\u2693";
_unicodePoints = "\u27A1";
_unicodeInfo = "\u273F";
_unicodeSuccess = "\u2714";
_unicodeError = "\u2716";
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*NODE*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
node('00d || 008')
{
try
{
deleteDir();
init();
execute();
}
catch(Exception e) {
println e.getMessage();
println e;
throw e;
}
finally {
deleteDir();
//step([$class: 'AuditPipelinePublisher', enabled: true]); todo: enable audit pipeline
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*INITIALIZE*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
def init()
{
try
{
_nodeOs = isUnix() ? _linux : _windows;
//initialize utilities: get common pipeline utilities
clonerepo(_nodeOs, "github.aig.net/commercial-it-devops/pipeline-utilities.git", "master");
_commonUtils = load "./pipeline-utilities/common.groovy";
executeCommand("mkdir ${_dirPipelineRepo}");
executeCommand("mkdir ${_dirProjectRepo}");
initStages();
_commonUtils.prepareStages(_stageCheckoutPipeline,_stageCheckoutProject,_stageBuildAutomation,
_stageUnitTest,_stageCodeAnalysis,_stageBuildManagement,_stageDeployment);
initMessages();
}
catch(Exception e) {
println "${_unicodeError} Error occurred during initialization";
throw e;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*EXECUTE*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
def execute()
{
def stageDifferentiator = "\n================================================================================\n"
println("${stageDifferentiator}${_unicodeAnchor} Running on ${_nodeOs} node.");
try
{
/**CHECKOUT-PIPELINE**/
stage(_stageCheckoutPipeline)
{
setCurrentStage(_stageCheckoutPipeline);
runCheckoutPipeline();
_stageArray.put(_stageCheckoutPipeline,_success);
}
println "${stageDifferentiator}"
/**CHECKOUT-PROJECT**/
stage(_stageCheckoutProject)
{
setCurrentStage(_stageCheckoutProject);
runCheckoutProject();
_stageArray.put(_stageCheckoutProject,_success);
}
println "${stageDifferentiator}"
/**Lint-TEST**/
stage(_stageLintAnalysis)
{
setCurrentStage(_stageLintAnalysis);
runLintTest();
_stageArray.put(_stageLintAnalysis,_success);
}
println "${stageDifferentiator}"
/**UNIT-TEST**/
if (rtUnitTest == true) {
stage(_stageUnitTest)
{
setCurrentStage(_stageUnitTest);
runUnitTest();
_stageArray.put(_stageUnitTest,_success);
}
println "${stageDifferentiator}"
}
/**BUILD-AUTOMATION**/
stage(_stageBuildAutomation)
{
setCurrentStage(_stageBuildAutomation);
runBuildAutomation();
_stageArray.put(_stageBuildAutomation,_success);
}
println "${stageDifferentiator}"
/**CODE-ANALYSIS**/
// stage(_stageCodeAnalysis)
// {
// setCurrentStage(_stageCodeAnalysis);
// runCodeAnalysis();
// _stageArray.put(_stageCodeAnalysis,_success);
// }
// println "${stageDifferentiator}"
/**BUILD-MANAGEMENT**/
stage(_stageBuildManagement)
{
setCurrentStage(_stageBuildManagement);
runBuildManagement();
_stageArray.put(_stageBuildManagement,_success);
}
println "${stageDifferentiator}"
/**DEPLOYMENT**/
stage(_stageDeployment)
{
setCurrentStage(_stageDeployment);
runDeployment();
_stageArray.put(_stageDeployment,_success);
}
println "${stageDifferentiator}"
/**DEPLOYMENT**/
stage ("E2E") {
checkout scm
sh("ls -lrt")
dir("utils") {
// https://submissionmgtdev.apps.xeuw1-pcf.aig.net/
def sut="submissionmgtdev"
sh ("chmod a+x buildRemoteJob.ksh")
sh ("./buildRemoteJob.ksh $sut")
}
// error "INF: E2E ...."
}
//error "End of Line"
sendEmailNotification(_success);
}
catch(Exception e)
{
//send error notification
sendEmailNotification(_failure);
throw e;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*CHECKOUT-PIPELINE*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
def runCheckoutPipeline()
{
try
{
println _messageCheckoutPipelineStart;
dir(_dirPipelineRepo)
{
git credentialsId:_gitCredentialId, url:_gitPipelineRepository, branch:_gitPipelineRepositoryBranch
//..read pipeline.properties file
_pipelineProps = readProperties file: "${_pipelinePropertyFile}";
initializePipelineProperties();
}
println _messageCheckoutPipelineFinished;
}
catch(Exception e)
{
println _errorMessagePipeleineCheckout;
_stageArray.put(_stageCheckoutPipeline,_failure);
throw e;
}
}
def initializePipelineProperties()
{
//git
_gitProjectRepository = _pipelineProps.GIT_REPO;
_gitProjectRepositoryBranch = _pipelineProps.GIT_BRANCH;
//version
_buildVersion = "${_pipelineProps.MAJOR_VER}.${_pipelineProps.MINOR_VER}.${_pipelineProps.PATCH}.${env.BUILD_NUMBER}";
//sonar
if(_nodeOs == _linux)
{
_jdKHome = tool 'jdk1.8';
}
else
{
_jdKHome = tool "win-jdk-8";
}
//artifactory
_artifactoryServerUrl = _pipelineProps.ARTIFACTORY_SERVER_URL;
_artifactoryBaseFolder = _pipelineProps.ARTIFACTORY_BASE_FOLDER;
_artifactNamePrefix = _pipelineProps.ARTIFACT_NAME_PREFIX;
_artifactBuildName = _pipelineProps.ARTIFACT_BUILD_NAME;
_artifactoryVirtualRepo = _pipelineProps.ARTIFACTORY_VIRTUAL_REPO;
_artifactoryPublishRepo = _pipelineProps.ARTIFACTORY_PUBLISH_REPO;
_artifactoryUrl = "${_artifactoryServerUrl}webapp/#/artifacts/browse/tree/General/${_artifactoryPublishRepo}/${_artifactoryBaseFolder}/${_buildVersion}";
_artifactoryTarget = "${_artifactoryPublishRepo}/${_artifactoryBaseFolder}/${_buildVersion}/";
_artifactoryFile = "${_artifactBuildName}-${_buildVersion}.zip";
//pcf
_pcfApiUrl = _pipelineProps.PCF_API_URL;
_pcfAppDomain = _pipelineProps.PCF_APP_DOMAIN;
_pcfOrg = _pipelineProps.PCF_ORG;
_pcfSpace = _pipelineProps.PCF_SPACE;
_pcfAppName = _pipelineProps.PCF_APP_NAME;
//e-mail
_emailTo = _pipelineProps.EMAILTO;
_emailNotificationSubject = _pipelineProps.EMAIL_NOTIFICATION_SUBJECT;
println "${_unicodeInfo} Properties retrieved.."
println "GIT_REPO : ${_gitProjectRepository}";
println "GIT_BRANCH : ${_gitProjectRepositoryBranch}";
println "ARTIFACTORY_SERVER_URL : ${_artifactoryServerUrl}";
println "ARTIFACTORY_BASE_FOLDER : ${_artifactoryBaseFolder}";
println "ARTIFACT_NAME_PREFIX : ${_artifactNamePrefix}";
println "ARTIFACT_BUILD_NAME : ${_artifactBuildName}";
println "ARTIFACTORY_VIRTUAL_REPO : ${_artifactoryVirtualRepo}";
println "ARTIFACTORY_PUBLISH_REPO : ${_artifactoryPublishRepo}";
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*CHECKOUT-PROJECT*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
def runCheckoutProject()
{
try
{
println _messageCheckoutSourceStart;
dir(_dirProjectRepo)
{
git credentialsId:_gitCredentialId, url:_gitProjectRepository, branch:_gitProjectRepositoryBranch
}
println _messageCheckoutSourceFinished;
}
catch(Exception e)
{
println _errorMessageSourceCheckout;
_stageArray.put(_stageCheckoutProject,_failure);
throw e;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*BUILD AUTOMATION/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
def runBuildAutomation()
{
try
{
println _messageBuildAutomationStart;
dir(_dirProjectRepo)
{
setBuildEnv();
//creates package in /dist folder
executeCommand("axis build --prod");
//move ./dist -> ./deployable_package
def sourceFolder = "dist";
def targetFolder = "deployable_package";
if(_nodeOs == _windows)
bat "move ${sourceFolder} ${targetFolder}";
else
sh "mv ${sourceFolder} ${targetFolder}";
//zip it..
zip archive: false, dir: '.', glob: 'deployable_package/**', zipFile: _artifactoryFile
executeCommand("ls -ltr");
}
println _messageBuildAutomationFinish;
}
catch(Exception e)
{
println _errorMessageBuildAutomation;
_stageArray.put(_stageBuildAutomation,_failure);
throw e;
}
}
def setBuildEnv()
{
executeCommand("npm set registry http://tlgsasc2tm0075.r1-core.r1.aig.net:8081/artifactory/api/npm/npm-libs-prod");
executeCommand("npm cache verify");
executeCommand("npm install");
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*LINT-TEST/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
def runLintTest()
{
try
{
println _messageUnitTestStart;
dir(_dirProjectRepo)
{
setBuildEnv();
sh("axis lint")
}
println _messageUnitTestFinish;
}
catch(Exception e)
{
println _errorMessageUnitTest;
_stageArray.put(_stageLintAnalysis,_failure);
throw e;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*UNIT-TEST/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
def runUnitTest()
{
try
{
println _messageUnitTestStart;
dir(_dirProjectRepo)
{
setBuildEnv();
sh("axis test")
}
println _messageUnitTestFinish;
}
catch(Exception e)
{
println _errorMessageUnitTest;
_stageArray.put(_stageUnitTest,_failure);
throw e;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*CODE-ANALYSIS/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
def runCodeAnalysis()
{
try
{
println _messageCodeAnalysisStart;
dir(_dirProjectRepo)
{
}
println _messageCodeAnalysisFinish;
}
catch(Exception e)
{
println _errorMessageCodeAnalysis;
_stageArray.put(_stageCodeAnalysis,_failure);
throw e;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*BUILD MANAGEMENT/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
def runBuildManagement()
{
try
{
println _messageBuildManagementStart;
dir(_dirProjectRepo)
{
def server = Artifactory.server 'artifactory_devops_prod'
def _buildInfo = Artifactory.newBuildInfo();
_buildInfo.env.capture = true;
_buildInfo.env.collect();
_buildInfo.name = "${_artifactBuildName}";
_buildInfo.number = _buildVersion;
def artifactoryTarget = '"' + "${_artifactoryTarget}${_artifactoryFile}" + '"'
def artifactoryPattern = '"' + _artifactoryFile + '"';
echo "INF: AE - runBuildManagement : artifactoryTarget ($artifactoryTarget)"
echo "INF: AE - runBuildManagement : artifactoryPattern ($artifactoryPattern)"
echo "INF: AE - runBuildManagement : _buildInfo ($_buildInfo)"
echo "INF: AE - runBuildManagement : server ($server)"
_commonUtils.doUploadToArtifactory(artifactoryTarget,artifactoryPattern,_buildInfo,server);
}
println _messageBuildManagementFinish;
}
catch(Exception e)
{
println _errorMessageBuildManagement;
_stageArray.put(_stageBuildManagement,_failure);
throw e;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*DEPLOYMENT/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
def runDeployment()
{
try
{
println _messageDeploymentStart;
dir(_dirProjectRepo)
{
def dirPackage = "deployable_package";
dir(dirPackage)
{
withEnv(["JAVA_HOME=${_jdKHome}"])
{
withCredentials([
[$class: 'UsernamePasswordMultiBinding',
credentialsId: 'emea_nprd_credential_id',
usernameVariable: 'PCF_USERNAME',
passwordVariable: 'PCF_PASSWORD']
])
{
try
{
def workingDir = pwd();
def pcfUserName = env.PCF_USERNAME;
def pcfPassword = env.PCF_PASSWORD;
println "Pcf Api Url: ${_pcfApiUrl}";
println "Pcf Org name: ${_pcfOrg}";
println "Pcf Space name : ${_pcfSpace}";
executeCommand("cf login -a ${_pcfApiUrl} -u ${pcfUserName} -p ${pcfPassword} -o ${_pcfOrg} -s ${_pcfSpace}");
if(_nodeOs ==_linux)
sh "cf push -f ../../${_dirPipelineRepo}/manifest.yml";
else
bat "cf push -f ..\\..\\${_dirPipelineRepo}\\manifest.yml";
}
finally
{
executeCommand("cf logout");
}
}
}
}
}
println _messageDeploymentFinish;
}
catch(Exception e)
{
println _errorMessageDeployment;
_stageArray.put(_stageDeployment,_failure);
throw e;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*UTILS*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*Capture the current build stage in CURRENT_STAGE environment variable*/
def setCurrentStage(String currentStage)
{
env.CURRENT_STAGE = currentStage;
}
def isNullOrEmpty(obj)
{
return obj==null || obj=="";
}
/*executes shell or bat command.
* commands should be similar*/
def executeCommand(String cmdStr)
{
try
{
if(_nodeOs == _windows)
bat "${cmdStr}";
else
sh "${cmdStr}";
}
catch(Exception e)
{
println "${_unicodeError} Error occurred while executing command";
throw e;
}
}
def clonerepo(nodeOs, gitRepo, branchName)
{
try
{
withCredentials([string(credentialsId: 'comm_git_clone_token', variable: 'comm_git_clone_token')])
{
if(nodeOs == 'WIN')
{
bat "git clone -b ${branchName} https://${comm_git_clone_token}@${gitRepo}";
}
else
{
sh "scl enable rh-git29 -- git clone -b ${branchName} https://${comm_git_clone_token}@${gitRepo}";
}
}
println "Cloned repo - ${gitRepo}, branch - ${branchName}";
}
catch(Exception e)
{
println "Failed to clone repo - ${gitRepo}";
throw e;
}
}
def sendEmailNotification(status)
{
println "[sendNotification] Status: ${status}";
def urlArray = [:];
_sonarQubeDashboardUrl = "";
_artifactoryUrl = _artifactoryUrl;
_buildVersion = _buildVersion;
if(status==_success)
{
urlArray.put('SonarQube Dashboard',_sonarQubeDashboardUrl);
urlArray.put('Artifacts', _artifactoryUrl);
_commonUtils.sendEmailNotification(_success,_emailNotificationSubject,
_buildVersion,"sprint-release-notes.txt",false,_emailTo,urlArray,_stageArray);
}
else
{
_commonUtils.sendEmailNotification(_failure,_emailNotificationSubject,
_buildVersion,"sprint-release-notes.txt",false,_emailTo,urlArray,_stageArray);
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*INITIALIZATION*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
def initStages()
{
_stageCheckoutPipeline = "Checkout Pipeline";
_stageCheckoutProject = "Checkout Project"
_stageBuildAutomation = "Build Automation";
_stageUnitTest = "Unit Test";
_stageLintAnalysis = "Lint Analysis";
_stageCodeAnalysis = "Code Analysis";
_stageBuildManagement = "Build Management";
_stageDeployment = "Deployment";
_stageTestAutomation = "Test Automation";
_stageSecurityTesting = "Security Testing";
}
/*[MESSAGES]*/
def initMessages()
{
_messageCheckoutPipelineStart = "${_unicodePoints} Checking out build Props...";
_messageCheckoutPipelineFinished = "${_unicodeInfo} Checkout of build Props completed.";
_errorMessagePipeleineCheckout = "${_unicodeError} Error during checkout of build props.";
//Checkout-Code
_messageCheckoutSourceStart = "${_unicodePoints} Checking out project source code.";
_messageCheckoutSourceFinished = "${_unicodeInfo} Checkout of project source code completed.";
_errorMessageSourceCheckout = "${_unicodeError} Error during checking out code.";
//Checkout-complete
_messageCheckoutStageFinished = "Checkout stage completed.";
//error message on directory does not exist
_erroMessageOnDirNotExists = "Error: Target directory does not exist.";
//BuildAutomation
_messageBuildAutomationStart = "${_unicodePoints} Building code...";
_messageBuildAutomationFinish = "${_unicodeInfo} Building code completed.";
_errorMessageBuildAutomation = "${_unicodeError} Error during building of code.";
//UnitTest
_messageUnitTestStart = "${_unicodePoints} Running Unit Test.";
_messageUnitTestFinish = "${_unicodeInfo} Unit Test run successfully."
_errorMessageUnitTest = "${_unicodeError} Error occured while running Unit Test."
//CodeAnalysis
_messageCodeAnalysisStart = "${_unicodePoints} Running Code Analysis...";
_messageCodeAnalysisFinish = "${_unicodeInfo} Code Analysis run successfully."
_errorMessageCodeAnalysis = "${_unicodeError} Error occured while running Code Analysis."
//BuildManagement
_messageBuildManagementStart = "${_unicodePoints} Uploading binaries to Artifactory...";
_messageBuildManagementFinish = "${_unicodeInfo} Uploading binaries to Artifactory completed.";
_errorMessageBuildManagement = "${_unicodeError} Error while uploading binaries to Artifactory.";
//Deployment
_messageDeploymentStart = "${_unicodePoints} Deployment started.";
_messageDeploymentFinish = "${_unicodeInfo} Deployment completed.";
_errorMessageDeployment = "${_unicodeError} Error while deploying the pacakge.";
}
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment