github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/src/com/sap/piper/JenkinsUtils.groovy (about)

     1  package com.sap.piper
     2  
     3  import com.cloudbees.groovy.cps.NonCPS
     4  import hudson.Functions
     5  import hudson.tasks.junit.TestResultAction
     6  
     7  import jenkins.model.Jenkins
     8  
     9  import org.apache.commons.io.IOUtils
    10  import org.jenkinsci.plugins.workflow.libs.LibrariesAction
    11  import org.jenkinsci.plugins.workflow.steps.MissingContextVariableException
    12  
    13  @NonCPS
    14  def getActiveJenkinsInstance() {
    15      return Jenkins.getActiveInstance()
    16  }
    17  
    18  @API
    19  @NonCPS
    20  static def isPluginActive(pluginId) {
    21      return Jenkins.instance.pluginManager.plugins.find { p -> p.isActive() && p.getShortName() == pluginId }
    22  }
    23  
    24  static boolean hasTestFailures(build){
    25      //build: https://javadoc.jenkins.io/plugin/workflow-support/org/jenkinsci/plugins/workflow/support/steps/build/RunWrapper.html
    26      //getRawBuild: https://javadoc.jenkins.io/plugin/workflow-job/org/jenkinsci/plugins/workflow/job/WorkflowRun.html
    27      //getAction: http://www.hudson-ci.org/javadoc/hudson/tasks/junit/TestResultAction.html
    28      def action = build?.getRawBuild()?.getAction(TestResultAction.class)
    29      return action && action.getFailCount() != 0
    30  }
    31  
    32  boolean addWarningsNGParser(String id, String name, String regex, String script, String example = ''){
    33      def classLoader = this.getClass().getClassLoader()
    34      // usage of class loader to avoid plugin dependency for other use cases of JenkinsUtils class
    35      def parserConfig = classLoader.loadClass('io.jenkins.plugins.analysis.warnings.groovy.ParserConfiguration', true)?.getInstance()
    36  
    37      if(parserConfig.contains(id)){
    38          return false
    39      }else{
    40          parserConfig.setParsers(
    41              parserConfig.getParsers().plus(
    42                  classLoader.loadClass('io.jenkins.plugins.analysis.warnings.groovy.GroovyParser', true)?.newInstance(id, name, regex, script, example)
    43              )
    44          )
    45          return true
    46      }
    47  }
    48  
    49  @NonCPS
    50  static String getFullBuildLog(currentBuild) {
    51      Reader reader = currentBuild.getRawBuild().getLogReader()
    52      String logContent = IOUtils.toString(reader);
    53      reader.close();
    54      reader = null
    55      return logContent
    56  }
    57  
    58  def nodeAvailable() {
    59      try {
    60          sh "echo 'Node is available!'"
    61      } catch (MissingContextVariableException e) {
    62          echo "No node context available."
    63          return false
    64      }
    65      return true
    66  }
    67  
    68  
    69  @NonCPS
    70  def getCurrentBuildInstance() {
    71      return currentBuild
    72  }
    73  
    74  @NonCPS
    75  def getParentJob() {
    76      return getRawBuild().getParent()
    77  }
    78  
    79  @NonCPS
    80  def getRawBuild() {
    81      return getCurrentBuildInstance().rawBuild
    82  }
    83  
    84  def isJobStartedByTimer() {
    85      return isJobStartedByCause(hudson.triggers.TimerTrigger.TimerTriggerCause.class)
    86  }
    87  
    88  def isJobStartedByUser() {
    89      return isJobStartedByCause(hudson.model.Cause.UserIdCause.class)
    90  }
    91  
    92  @NonCPS
    93  def isJobStartedByCause(Class cause) {
    94      def startedByGivenCause = false
    95      def detectedCause = getRawBuild().getCause(cause)
    96      if (null != detectedCause) {
    97          startedByGivenCause = true
    98          echo "Found build cause ${detectedCause}"
    99      }
   100      return startedByGivenCause
   101  }
   102  
   103  @NonCPS
   104  String getIssueCommentTriggerAction() {
   105      try {
   106          def triggerCause = getRawBuild().getCause(org.jenkinsci.plugins.pipeline.github.trigger.IssueCommentCause)
   107          if (triggerCause) {
   108              //triggerPattern e.g. like '.* /piper ([a-z]*) .*'
   109              def matcher = triggerCause.comment =~ triggerCause.triggerPattern
   110              if (matcher) {
   111                  return matcher[0][1]
   112              }
   113          }
   114          return null
   115      } catch (err) {
   116          return null
   117      }
   118  }
   119  
   120  def getJobStartedByUserId() {
   121      return getRawBuild().getCause(hudson.model.Cause.UserIdCause.class)?.getUserId()
   122  }
   123  
   124  @NonCPS
   125  def getLibrariesInfo() {
   126      def libraries = []
   127      def build = getRawBuild()
   128      def libs = build.getAction(LibrariesAction.class).getLibraries()
   129  
   130      for (def i = 0; i < libs.size(); i++) {
   131          Map lib = [:]
   132  
   133          lib['name'] = libs[i].name
   134          lib['version'] = libs[i].version
   135          lib['trusted'] = libs[i].trusted
   136          libraries.add(lib)
   137      }
   138  
   139      return libraries
   140  }
   141  
   142  @NonCPS
   143  void addRunSideBarLink(String relativeUrl, String displayName, String relativeIconPath) {
   144      try {
   145          def linkActionClass = this.class.classLoader.loadClass("hudson.plugins.sidebar_link.LinkAction")
   146          if (relativeUrl != null && displayName != null) {
   147              def run = getRawBuild()
   148              def iconPath = (null != relativeIconPath) ? "${Functions.getResourcePath()}/${relativeIconPath}" : null
   149              def action = linkActionClass.newInstance(relativeUrl, displayName, iconPath)
   150              echo "Added run level sidebar link to '${action.getUrlName()}' with name '${action.getDisplayName()}' and icon '${action.getIconFileName()}'"
   151              run.getActions().add(action)
   152          }
   153      } catch (e) {
   154          e.printStackTrace()
   155      }
   156  }
   157  
   158  @NonCPS
   159  def getPlugin(name){
   160      for (plugin in getActiveJenkinsInstance().pluginManager.plugins) {
   161          if (name == plugin.getShortName()) {
   162              return plugin
   163          }
   164      }
   165      return null
   166  }
   167  
   168  @NonCPS
   169  String getPluginVersion(name) {
   170      return getPlugin(name)?.getVersion()
   171  }
   172  
   173  @NonCPS
   174  void addJobSideBarLink(String relativeUrl, String displayName, String relativeIconPath) {
   175      try {
   176          def linkActionClass = this.class.classLoader.loadClass("hudson.plugins.sidebar_link.LinkAction")
   177          if (relativeUrl != null && displayName != null) {
   178              def parentJob = getParentJob()
   179              def buildNumber = getCurrentBuildInstance().number
   180              def iconPath = (null != relativeIconPath) ? "${Functions.getResourcePath()}/${relativeIconPath}" : null
   181              def action = linkActionClass.newInstance("${buildNumber}/${relativeUrl}", displayName, iconPath)
   182              echo "Added job level sidebar link to '${action.getUrlName()}' with name '${action.getDisplayName()}' and icon '${action.getIconFileName()}'"
   183              parentJob.getActions().add(action)
   184          }
   185      } catch (e) {
   186          e.printStackTrace()
   187      }
   188  }
   189  
   190  @NonCPS
   191  void removeJobSideBarLinks(String relativeUrl = null) {
   192      try {
   193          def linkActionClass = this.class.classLoader.loadClass("hudson.plugins.sidebar_link.LinkAction")
   194          def parentJob = getParentJob()
   195          def listToRemove = new ArrayList()
   196          for (def action : parentJob.getActions()) {
   197              if (linkActionClass.isAssignableFrom(action.getClass()) && (null == relativeUrl || action.getUrlName().endsWith(relativeUrl))) {
   198                  echo "Removing job level sidebar link to '${action.getUrlName()}' with name '${action.getDisplayName()}' and icon '${action.getIconFileName()}'"
   199                  listToRemove.add(action)
   200              }
   201          }
   202          parentJob.getActions().removeAll(listToRemove)
   203          echo "Removed Jenkins global sidebar links ${listToRemove}"
   204      } catch (e) {
   205          e.printStackTrace()
   206      }
   207  }
   208  
   209  void handleStepResults(String stepName, boolean failOnMissingReports, boolean failOnMissingLinks) {
   210      def reportsFileName = "${stepName}_reports.json"
   211      def reportsFileExists = fileExists(file: reportsFileName)
   212      if (failOnMissingReports && !reportsFileExists) {
   213          error "Expected to find ${reportsFileName} in workspace but it is not there"
   214      } else if (reportsFileExists) {
   215          def reports = readJSON(file: reportsFileName)
   216          for (report in reports) {
   217              String target = report['target'] as String
   218              if (target != null && target.startsWith("./")) {
   219                  // archiveArtifacts does not match any files when they start with "./",
   220                  // even though that is a correct relative path.
   221                  target = target.substring(2)
   222              }
   223              archiveArtifacts artifacts: target, allowEmptyArchive: !report['mandatory']
   224          }
   225      }
   226  
   227      def linksFileName = "${stepName}_links.json"
   228      def linksFileExists = fileExists(file: linksFileName)
   229      if (failOnMissingLinks && !linksFileExists) {
   230          error "Expected to find ${linksFileName} in workspace but it is not there"
   231      } else if (linksFileExists) {
   232          def links = readJSON(file: linksFileName)
   233          for (link in links) {
   234              if(link['scope'] == 'job') {
   235                  removeJobSideBarLinks(link['target'])
   236                  addJobSideBarLink(link['target'], link['name'], "images/24x24/graph.png")
   237              }
   238              addRunSideBarLink(link['target'], link['name'], "images/24x24/graph.png")
   239          }
   240      }
   241  }
   242  
   243  def getInstance() {
   244      Jenkins.get()
   245  }