【问题标题】:Access Azure pipeline build information within groovy script在 groovy 脚本中访问 Azure 管道构建信息
【发布时间】:2020-05-21 15:39:04
【问题描述】:

我的团队正在创建将 Jenkins 管道转换为 azure DevOps 管道的概念证明。我发现的挑战之一是使用 groovy 脚本,我们利用 Jenkins 内置变量来收集签入文件、已删除文件、Jenkins 节点名称等。我们希望不需要重新编码现有的 groovy脚本并回收我们已有的代码。有没有办法在 groovy 脚本中获取 azure 管道信息。

我尝试了许多不同措辞的谷歌搜索,但我无法找到任何关于使用 azure 管道变量的 java/groovy 的示例。

任何帮助将不胜感激。

您将在下面找到我们当前用于 Jenkins 管道/构建定义的 groovy 脚本,这是我们需要转换的。

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}"
    }

}

【问题讨论】:

    标签: azure groovy azure-pipelines


    【解决方案1】:

    Groovy 似乎支持开箱即用的 HTTP,因此您可以尝试使用不带任何库的 Groovy DevOps REST API

    关于 Azure DevOps Services Build REST API,请参考以下链接:

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

    Groovy中如何使用REST API,可以参考这个案例: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());
    }
    

    【讨论】:

    • 你查看我的回复了吗?有用吗?
    • 我将在接下来的一两天内再次挑选它,并让您知道它是如何工作的!理论上听起来不错,我会尽快更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-18
    • 1970-01-01
    • 2021-10-15
    • 2017-01-19
    • 2019-03-28
    • 2022-08-14
    • 2018-05-14
    相关资源
    最近更新 更多