1

My team is creating a proof of concept of converting a Jenkins pipeline to an azure DevOps pipeline. One of the challenges I am finding is the use of the groovy scripts which we leverage the Jenkins built-in variables to gather checked-in files, deleted files, Jenkins node name, etc. We were hoping to not need to recode the existing groovy scripts and recycle the code we already have. Is there a way to get the azure pipeline information within a groovy script.

I have attempted many google searches with different wordings and I am unable to find any examples on java/groovy using azure pipeline variables.

Any help whatsoever would be greatly appreciated.

Below you will find our current groovy script for Jenkins pipelines/build definitions and is what we need to be converted.

import java.lang.*;
import java.io.Writer;

import jenkins.*;
import jenkins.model.*;

import hudson.*;
import hudson.model.*;
import hudson.util.*;
import hudson.scm.*;

import groovy.transform.Field;
import groovy.json.*;

def build = Thread.currentThread()?.executable;

println " ** CHANGESET ** ";
def changeSet = build.getChangeSet();
def items = changeSet.getItems();

def changedFilesPathsForDeploy = [];

def changedFilesPathsForUndeploy = [];

for(int i = 0 ; i < items.length; i++) {
    gitChangeSet = items[i];
    author = gitChangeSet.getAuthorName();
    comment = gitChangeSet.getComment().replaceAll("\\n", " ");
    rev = gitChangeSet.getRevision();
    paths = gitChangeSet.getPaths();

    println "      ${ i + 1 }. ${ comment }";
    println "          Commit: ${ rev }  (by ${ author }) ";
    for(hudson.plugins.git.GitChangeSet.Path path : paths) {
        editType = path.getEditType();
        if(editType == hudson.scm.EditType.ADD || editType == hudson.scm.EditType.EDIT) {
            changedFilesPathsForDeploy.add(path.getPath());
            if (editType == hudson.scm.EditType.ADD) {
                println "             +  ${ path.getPath() }";
            } else {
                println "             M  ${ path.getPath() }";
            }
        } else if(editType == hudson.scm.EditType.DELETE) {
            println "             -  ${ path.getPath() }";
            changedFilesPathsForUndeploy.add(path.getPath());
        }
    }
}

println "\n:> Creating deploy map";
def deployMap = JsonOutput.toJson(createChangesMap(changedFilesPathsForDeploy));

println ":> Creating undeploy map";
def undeployMap = JsonOutput.toJson(createChangesMap(changedFilesPathsForUndeploy));

buildJsonAssets(deployMap, undeployMap);

@Field def types = [
    "classes"             : "ApexClass",
    "components"          : "ApexComponent",
    "pages"               : "ApexPage",
    "triggers"            : "ApexTrigger",
    "connectedApps"       : "ConnectedApp",
    "applications"        : "CustomApplication",
    "labels"              : "CustomLabels",
    "objects"             : "CustomObject",
    "tabs"                : "CustomTab",
    "flows"               : "Flow",
    "layouts"             : "Layout",
    "permissionsets"      : "PermissionSet",
    "profiles"            : "Profile",
    "remoteSiteSettings"  : "RemoteSiteSetting",
    "reports"             : "Report",
    "reportTypes"         : "ReportType",
    "staticresources"     : "StaticResource",
    "workflows"           : "Workflow",
] as Map;

def createChangesMap(def affectedFiles) {
    def fileNames = [];
    def foldersAndFiles = [ LSApp: false ];
    def flattenedFiles = affectedFiles.flatten();

    flattenedFiles.each { it ->

        def changes = it.split('/').collect { it as Object };

        if (changes.first() == 'src') {
            fileNames.add(changes);
        } else if (changes.first() == 'LSApp') {
            foldersAndFiles[ 'LSApp' ] = true;
        }
    }

    def finalMap = retrieveFoldersAndFiles(fileNames, foldersAndFiles);

    return finalMap;
}

def retrieveFoldersAndFiles(def pathLists, def foldersAndFiles) {
    def folder;

    pathLists.each { pathList ->
        def filename = pathList.last().tokenize('.').first();

        pathList.each { key ->

            filename = key == 'objects' ? pathList.take(5).last() : filename;

            if (types.containsKey(key)) {
                folder = types[ key ];

                if (foldersAndFiles.containsKey(folder)) {
                    foldersAndFiles[ folder ] = foldersAndFiles[ folder ] + filename;
                } else {
                    foldersAndFiles[ folder ] = [ filename ] as Set;
                }
            }
        }      
    }

    return foldersAndFiles;
}

def buildJsonAssets(def deployJson, def undeployJson) {


    try {
        if(build.workspace.isRemote()){
            channel = build.workspace.channel;
            fpDeploy = new FilePath( channel, build.workspace.toString() + "/SFDX/partial_dep/configs/deploy.json" );
            fpUndeploy = new FilePath( channel, build.workspace.toString() + "/SFDX/partial_dep/configs/undeploy.json" );
        } else {
            fpDeploy = new FilePath( new File(build.workspace.toString() + "/SFDX/partial_dep/configs/deploy.json") );
            fpUndeploy = new FilePath( new File(build.workspace.toString() + "/SFDX/partial_dep/configs/undeploy.json") );
        }

        if(fpDeploy != null) {
            println "\n:> Storing changes to DEPLOY.JSON";
            fpDeploy.write(deployJson, null); //writing to file
        }

        if(fpUndeploy != null) {
            println ":> Storing changes to UNDEPLOY.JSON";
            fpUndeploy.write(undeployJson, null); //writing to file 
        }   

    } catch (IOException error) {
        println "Unable to create file: ${error}"
    }

}
Nicole Phillips
  • 753
  • 1
  • 18
  • 41

1 Answers1

1

It seems Groovy supports HTTP out-of-the-box, so you may try DevOps REST API using Groovy without any libraries.

Regarding Azure DevOps Services Build REST API, please refer to the link below:

https://learn.microsoft.com/en-us/rest/api/azure/devops/build/?view=azure-devops-rest-5.1

Regarding how to use REST API in Groovy, you may refer to this case: Groovy built-in REST/HTTP client?:

Native Groovy GET and POST

// GET
def get = new URL("https://httpbin.org/get").openConnection();
def getRC = get.getResponseCode();
println(getRC);
if(getRC.equals(200)) {
    println(get.getInputStream().getText());
}

// POST
def post = new URL("https://httpbin.org/post").openConnection();
def message = '{"message":"this is a message"}'
post.setRequestMethod("POST")
post.setDoOutput(true)
post.setRequestProperty("Content-Type", "application/json")
post.getOutputStream().write(message.getBytes("UTF-8"));
def postRC = post.getResponseCode();
println(postRC);
if(postRC.equals(200)) {
    println(post.getInputStream().getText());
}
Cece Dong - MSFT
  • 29,631
  • 1
  • 24
  • 39