| Jakub Josef | 1b75ca8 | 2017-02-20 16:08:13 +0100 | [diff] [blame] | 1 | package com.mirantis.mk | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 2 | import java.util.regex.Pattern | 
| Jakub Josef | ec5098f | 2017-06-15 18:15:32 +0200 | [diff] [blame] | 3 | import com.cloudbees.groovy.cps.NonCPS | 
|  | 4 | import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.GerritCause | 
| Jakub Josef | 1b75ca8 | 2017-02-20 16:08:13 +0100 | [diff] [blame] | 5 | /** | 
|  | 6 | * Gerrit functions | 
|  | 7 | * | 
|  | 8 | */ | 
|  | 9 |  | 
|  | 10 | /** | 
|  | 11 | * Execute git clone and checkout stage from gerrit review | 
|  | 12 | * | 
|  | 13 | * @param config LinkedHashMap | 
|  | 14 | *        config includes next parameters: | 
|  | 15 | *          - credentialsId, id of user which should make checkout | 
| Jakub Josef | bccd786 | 2017-05-30 14:27:15 +0200 | [diff] [blame] | 16 | *          - withMerge, merge master before build | 
|  | 17 | *          - withLocalBranch, prevent detached mode in repo | 
| Jakub Josef | 1b75ca8 | 2017-02-20 16:08:13 +0100 | [diff] [blame] | 18 | *          - withWipeOut, wipe repository and force clone | 
| azvyagintsev | ed1d63e | 2018-09-10 14:25:13 +0300 | [diff] [blame] | 19 | *          - GerritTriggerBuildChooser - use magic GerritTriggerBuildChooser class from gerrit-trigger-plugin. | 
|  | 20 | *            By default,enabled. | 
| Jakub Josef | bccd786 | 2017-05-30 14:27:15 +0200 | [diff] [blame] | 21 | *        Gerrit properties like GERRIT_SCHEMA can be passed in config as gerritSchema or will be obtained from env | 
|  | 22 | * @param extraScmExtensions list of extra scm extensions which will be used for checkout (optional) | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 23 | * @return boolean result | 
| Jakub Josef | 1b75ca8 | 2017-02-20 16:08:13 +0100 | [diff] [blame] | 24 | * | 
|  | 25 | * Usage example: | 
|  | 26 | * //anonymous gerrit checkout | 
|  | 27 | * def gitFunc = new com.mirantis.mcp.Git() | 
|  | 28 | * gitFunc.gerritPatchsetCheckout([ | 
|  | 29 | *   withMerge : true | 
|  | 30 | * ]) | 
|  | 31 | * | 
|  | 32 | * def gitFunc = new com.mirantis.mcp.Git() | 
|  | 33 | * gitFunc.gerritPatchsetCheckout([ | 
|  | 34 | *   credentialsId : 'mcp-ci-gerrit', | 
|  | 35 | *   withMerge : true | 
|  | 36 | * ]) | 
|  | 37 | */ | 
| Jakub Josef | bccd786 | 2017-05-30 14:27:15 +0200 | [diff] [blame] | 38 | def gerritPatchsetCheckout(LinkedHashMap config, List extraScmExtensions = []) { | 
| Jakub Josef | 1b75ca8 | 2017-02-20 16:08:13 +0100 | [diff] [blame] | 39 | def merge = config.get('withMerge', false) | 
|  | 40 | def wipe = config.get('withWipeOut', false) | 
| Jakub Josef | bccd786 | 2017-05-30 14:27:15 +0200 | [diff] [blame] | 41 | def localBranch = config.get('withLocalBranch', false) | 
| Jakub Josef | 1b75ca8 | 2017-02-20 16:08:13 +0100 | [diff] [blame] | 42 | def credentials = config.get('credentialsId','') | 
| Jakub Josef | 71c46a6 | 2017-03-29 14:55:33 +0200 | [diff] [blame] | 43 | def gerritScheme = config.get('gerritScheme', env["GERRIT_SCHEME"] ? env["GERRIT_SCHEME"] : "") | 
|  | 44 | def gerritRefSpec = config.get('gerritRefSpec', env["GERRIT_REFSPEC"] ? env["GERRIT_REFSPEC"] : "") | 
|  | 45 | def gerritName = config.get('gerritName', env["GERRIT_NAME"] ? env["GERRIT_NAME"] : "") | 
|  | 46 | def gerritHost = config.get('gerritHost', env["GERRIT_HOST"] ?  env["GERRIT_HOST"] : "") | 
|  | 47 | def gerritPort = config.get('gerritPort', env["GERRIT_PORT"] ? env["GERRIT_PORT"] : "") | 
|  | 48 | def gerritProject = config.get('gerritProject', env["GERRIT_PROJECT"] ? env["GERRIT_PROJECT"] : "") | 
|  | 49 | def gerritBranch = config.get('gerritBranch', env["GERRIT_BRANCH"] ? env["GERRIT_BRANCH"] : "") | 
| chnyda | 96a1e8a | 2017-03-28 16:02:13 +0200 | [diff] [blame] | 50 | def path = config.get('path', "") | 
| chnyda | 7d25fc9 | 2017-03-29 10:51:59 +0200 | [diff] [blame] | 51 | def depth = config.get('depth', 0) | 
|  | 52 | def timeout = config.get('timeout', 20) | 
| azvyagintsev | ed1d63e | 2018-09-10 14:25:13 +0300 | [diff] [blame] | 53 | def GerritTriggerBuildChooser = config.get('useGerritTriggerBuildChooser', true) | 
| Jakub Josef | 1b75ca8 | 2017-02-20 16:08:13 +0100 | [diff] [blame] | 54 |  | 
| Dmitry Pyzhov | 169f812 | 2017-12-06 14:44:41 +0300 | [diff] [blame] | 55 | def invalidParams = _getInvalidGerritParams(config) | 
|  | 56 | if (invalidParams.isEmpty()) { | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 57 | // default parameters | 
|  | 58 | def scmExtensions = [ | 
|  | 59 | [$class: 'CleanCheckout'], | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 60 | [$class: 'CheckoutOption', timeout: timeout], | 
|  | 61 | [$class: 'CloneOption', depth: depth, noTags: false, reference: '', shallow: depth > 0, timeout: timeout] | 
|  | 62 | ] | 
|  | 63 | def scmUserRemoteConfigs = [ | 
|  | 64 | name: 'gerrit', | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 65 | ] | 
| Jakub Josef | 30fc921 | 2017-04-04 11:47:19 +0200 | [diff] [blame] | 66 | if(gerritRefSpec && gerritRefSpec != ""){ | 
|  | 67 | scmUserRemoteConfigs.put('refspec', gerritRefSpec) | 
|  | 68 | } | 
| Jakub Josef | 1b75ca8 | 2017-02-20 16:08:13 +0100 | [diff] [blame] | 69 |  | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 70 | if (credentials == '') { | 
|  | 71 | // then try to checkout in anonymous mode | 
|  | 72 | scmUserRemoteConfigs.put('url',"${gerritScheme}://${gerritHost}/${gerritProject}") | 
|  | 73 | } else { | 
|  | 74 | // else use ssh checkout | 
|  | 75 | scmUserRemoteConfigs.put('url',"ssh://${gerritName}@${gerritHost}:${gerritPort}/${gerritProject}.git") | 
|  | 76 | scmUserRemoteConfigs.put('credentialsId',credentials) | 
|  | 77 | } | 
| Jakub Josef | 1b75ca8 | 2017-02-20 16:08:13 +0100 | [diff] [blame] | 78 |  | 
| azvyagintsev | ed1d63e | 2018-09-10 14:25:13 +0300 | [diff] [blame] | 79 | // Usefull, if we only need to clone branch. W\o any refspec magic | 
|  | 80 | if (GerritTriggerBuildChooser) { | 
|  | 81 | scmExtensions.add([$class: 'BuildChooserSetting', buildChooser: [$class: 'GerritTriggerBuildChooser']],) | 
|  | 82 | } | 
|  | 83 |  | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 84 | // if we need to "merge" code from patchset to GERRIT_BRANCH branch | 
|  | 85 | if (merge) { | 
| vnaumov | 37b735d | 2018-08-27 16:55:07 +0400 | [diff] [blame] | 86 | scmExtensions.add([$class: 'PreBuildMerge', options: [fastForwardMode: 'FF', mergeRemote: 'gerrit', mergeStrategy: 'DEFAULT', mergeTarget: gerritBranch]]) | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 87 | } | 
|  | 88 | // we need wipe workspace before checkout | 
|  | 89 | if (wipe) { | 
|  | 90 | scmExtensions.add([$class: 'WipeWorkspace']) | 
|  | 91 | } | 
| Jakub Josef | 1b75ca8 | 2017-02-20 16:08:13 +0100 | [diff] [blame] | 92 |  | 
| Jakub Josef | bccd786 | 2017-05-30 14:27:15 +0200 | [diff] [blame] | 93 | if(localBranch){ | 
|  | 94 | scmExtensions.add([$class: 'LocalBranch', localBranch: gerritBranch]) | 
|  | 95 | } | 
|  | 96 |  | 
|  | 97 | if(!extraScmExtensions.isEmpty()){ | 
|  | 98 | scmExtensions.addAll(extraScmExtensions) | 
|  | 99 | } | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 100 | if (path == "") { | 
| chnyda | 96a1e8a | 2017-03-28 16:02:13 +0200 | [diff] [blame] | 101 | checkout( | 
|  | 102 | scm: [ | 
|  | 103 | $class: 'GitSCM', | 
|  | 104 | branches: [[name: "${gerritBranch}"]], | 
|  | 105 | extensions: scmExtensions, | 
|  | 106 | userRemoteConfigs: [scmUserRemoteConfigs] | 
|  | 107 | ] | 
|  | 108 | ) | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 109 | } else { | 
|  | 110 | dir(path) { | 
|  | 111 | checkout( | 
|  | 112 | scm: [ | 
|  | 113 | $class: 'GitSCM', | 
|  | 114 | branches: [[name: "${gerritBranch}"]], | 
|  | 115 | extensions: scmExtensions, | 
|  | 116 | userRemoteConfigs: [scmUserRemoteConfigs] | 
|  | 117 | ] | 
|  | 118 | ) | 
|  | 119 | } | 
| chnyda | 96a1e8a | 2017-03-28 16:02:13 +0200 | [diff] [blame] | 120 | } | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 121 | return true | 
| Jakub Josef | 73d6214 | 2017-03-29 17:07:18 +0200 | [diff] [blame] | 122 | }else{ | 
| Dmitry Pyzhov | 169f812 | 2017-12-06 14:44:41 +0300 | [diff] [blame] | 123 | throw new Exception("Cannot perform gerrit checkout, missed config options: " + invalidParams) | 
| chnyda | 96a1e8a | 2017-03-28 16:02:13 +0200 | [diff] [blame] | 124 | } | 
| Jakub Josef | 30fc921 | 2017-04-04 11:47:19 +0200 | [diff] [blame] | 125 | return false | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 126 | } | 
|  | 127 | /** | 
|  | 128 | * Execute git clone and checkout stage from gerrit review | 
|  | 129 | * | 
| Jakub Josef | ad34dbf | 2017-03-29 17:52:31 +0200 | [diff] [blame] | 130 | * @param gerritUrl gerrit url with scheme | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 131 | *    "${GERRIT_SCHEME}://${GERRIT_NAME}@${GERRIT_HOST}:${GERRIT_PORT}/${GERRIT_PROJECT}.git | 
| Jakub Josef | ad34dbf | 2017-03-29 17:52:31 +0200 | [diff] [blame] | 132 | * @param gerritRef gerrit ref spec | 
|  | 133 | * @param gerritBranch gerrit branch | 
|  | 134 | * @param credentialsId jenkins credentials id | 
| Dmitry Pyzhov | e832b0a | 2017-12-06 14:43:25 +0300 | [diff] [blame] | 135 | * @param path checkout path, optional, default is empty string which means workspace root | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 136 | * @return boolean result | 
|  | 137 | */ | 
| Dmitry Pyzhov | e832b0a | 2017-12-06 14:43:25 +0300 | [diff] [blame] | 138 | def gerritPatchsetCheckout(gerritUrl, gerritRef, gerritBranch, credentialsId, path="") { | 
| Jakub Josef | ad34dbf | 2017-03-29 17:52:31 +0200 | [diff] [blame] | 139 | def gerritParams = _getGerritParamsFromUrl(gerritUrl) | 
| Jakub Josef | d383f39 | 2017-03-29 16:52:04 +0200 | [diff] [blame] | 140 | if(gerritParams.size() == 5){ | 
| Dmitry Pyzhov | e832b0a | 2017-12-06 14:43:25 +0300 | [diff] [blame] | 141 | if (path==""){ | 
|  | 142 | gerritPatchsetCheckout([ | 
|  | 143 | credentialsId : credentialsId, | 
|  | 144 | gerritBranch: gerritBranch, | 
|  | 145 | gerritRefSpec: gerritRef, | 
|  | 146 | gerritScheme: gerritParams[0], | 
|  | 147 | gerritName: gerritParams[1], | 
|  | 148 | gerritHost: gerritParams[2], | 
|  | 149 | gerritPort: gerritParams[3], | 
|  | 150 | gerritProject: gerritParams[4] | 
|  | 151 | ]) | 
|  | 152 | return true | 
|  | 153 | } else { | 
|  | 154 | dir(path) { | 
|  | 155 | gerritPatchsetCheckout([ | 
|  | 156 | credentialsId : credentialsId, | 
|  | 157 | gerritBranch: gerritBranch, | 
|  | 158 | gerritRefSpec: gerritRef, | 
|  | 159 | gerritScheme: gerritParams[0], | 
|  | 160 | gerritName: gerritParams[1], | 
|  | 161 | gerritHost: gerritParams[2], | 
|  | 162 | gerritPort: gerritParams[3], | 
|  | 163 | gerritProject: gerritParams[4] | 
|  | 164 | ]) | 
|  | 165 | return true | 
|  | 166 | } | 
|  | 167 | } | 
| Jakub Josef | c70c2a3 | 2017-03-29 16:38:30 +0200 | [diff] [blame] | 168 | } | 
|  | 169 | return false | 
|  | 170 | } | 
|  | 171 |  | 
| Jakub Josef | 50c9c3a | 2017-04-10 14:32:35 +0200 | [diff] [blame] | 172 | /** | 
|  | 173 | * Return gerrit change object from gerrit API | 
| Jakub Josef | 50c9c3a | 2017-04-10 14:32:35 +0200 | [diff] [blame] | 174 | * @param gerritName gerrit user name (usually GERRIT_NAME property) | 
| Jakub Josef | b735dd4 | 2017-04-10 15:31:19 +0200 | [diff] [blame] | 175 | * @param gerritHost gerrit host (usually GERRIT_HOST property) | 
| Sergey Otpuschennikov | 8d1aec1 | 2020-06-17 00:54:07 +0400 | [diff] [blame] | 176 | * @param gerritPort gerrit port (usually GERRIT_PORT property, default 29418) | 
| Jakub Josef | 50c9c3a | 2017-04-10 14:32:35 +0200 | [diff] [blame] | 177 | * @param gerritChangeNumber gerrit change number (usually GERRIT_CHANGE_NUMBER property) | 
|  | 178 | * @param credentialsId jenkins credentials id for gerrit | 
| Jakub Josef | 5aa33de | 2017-06-16 12:23:45 +0200 | [diff] [blame] | 179 | * @param includeCurrentPatchset do you want to include current (last) patchset | 
| Jakub Josef | 50c9c3a | 2017-04-10 14:32:35 +0200 | [diff] [blame] | 180 | * @return gerrit change object | 
|  | 181 | */ | 
| Sergey Otpuschennikov | 8d1aec1 | 2020-06-17 00:54:07 +0400 | [diff] [blame] | 182 | def getGerritChange(gerritName, gerritHost, gerritChangeNumber, credentialsId, includeCurrentPatchset = false, gerritPort = '29418'){ | 
| Jakub Josef | 50c9c3a | 2017-04-10 14:32:35 +0200 | [diff] [blame] | 183 | def common = new com.mirantis.mk.Common() | 
|  | 184 | def ssh = new com.mirantis.mk.Ssh() | 
|  | 185 | ssh.prepareSshAgentKey(credentialsId) | 
| Sergey Otpuschennikov | 8d1aec1 | 2020-06-17 00:54:07 +0400 | [diff] [blame] | 186 | ssh.ensureKnownHosts("${gerritHost}:${gerritPort}") | 
| Jakub Josef | 5aa33de | 2017-06-16 12:23:45 +0200 | [diff] [blame] | 187 | def curPatchset = ""; | 
|  | 188 | if(includeCurrentPatchset){ | 
|  | 189 | curPatchset = "--current-patch-set" | 
|  | 190 | } | 
| Dmitry Burmistrov | 066f3d4 | 2022-10-28 15:49:33 +0400 | [diff] [blame] | 191 | return common.parseJSON(ssh.agentSh(String.format("ssh -p %s %s@%s gerrit query ${curPatchset} --commit-message --format=JSON change:%s", gerritPort, gerritName, gerritHost, gerritChangeNumber))) | 
| Jakub Josef | 50c9c3a | 2017-04-10 14:32:35 +0200 | [diff] [blame] | 192 | } | 
|  | 193 |  | 
| Jakub Josef | 4edd743 | 2017-05-10 17:58:56 +0200 | [diff] [blame] | 194 | /** | 
|  | 195 | * Returns list of Gerrit trigger requested builds | 
|  | 196 | * @param allBuilds list of all builds of some job | 
|  | 197 | * @param gerritChange gerrit change number | 
|  | 198 | * @param excludePatchset gerrit patchset number which will be excluded from builds, optional null | 
|  | 199 | */ | 
|  | 200 | @NonCPS | 
|  | 201 | def getGerritTriggeredBuilds(allBuilds, gerritChange, excludePatchset = null){ | 
|  | 202 | return allBuilds.findAll{job -> | 
|  | 203 | def cause = job.causes[0] | 
| Jakub Josef | ec5098f | 2017-06-15 18:15:32 +0200 | [diff] [blame] | 204 | if(cause instanceof GerritCause && | 
| Denis Egorenko | f0568dd | 2019-01-16 13:53:34 +0400 | [diff] [blame] | 205 | (cause.getEvent() instanceof com.sonymobile.tools.gerrit.gerritevents.dto.events.PatchsetCreated || | 
|  | 206 | cause.getEvent() instanceof com.sonymobile.tools.gerrit.gerritevents.dto.events.CommentAdded)) { | 
| Jakub Josef | 4edd743 | 2017-05-10 17:58:56 +0200 | [diff] [blame] | 207 | if(excludePatchset == null || excludePatchset == 0){ | 
|  | 208 | return cause.event.change.number.equals(String.valueOf(gerritChange)) | 
|  | 209 | }else{ | 
|  | 210 | return cause.event.change.number.equals(String.valueOf(gerritChange)) && !cause.event.patchSet.number.equals(String.valueOf(excludePatchset)) | 
|  | 211 | } | 
|  | 212 | } | 
|  | 213 | return false | 
|  | 214 | } | 
|  | 215 | } | 
| Jakub Josef | 62899fd | 2017-06-15 18:53:46 +0200 | [diff] [blame] | 216 | /** | 
| Jakub Josef | 5aa33de | 2017-06-16 12:23:45 +0200 | [diff] [blame] | 217 | * Returns boolean result of test given gerrit patchset for given approval type and value | 
|  | 218 | * @param patchset gerrit patchset | 
| Jakub Josef | 62899fd | 2017-06-15 18:53:46 +0200 | [diff] [blame] | 219 | * @param approvalType type of tested approval (optional, default Verified) | 
| Jakub Josef | 798bfc5 | 2017-06-16 12:44:23 +0200 | [diff] [blame] | 220 | * @param approvalValue value of tested approval (optional, default empty string which means any value) | 
| Jakub Josef | 62899fd | 2017-06-15 18:53:46 +0200 | [diff] [blame] | 221 | * @return boolean result | 
| Jakub Josef | 5aa33de | 2017-06-16 12:23:45 +0200 | [diff] [blame] | 222 | * @example patchsetHasApproval(gerrit.getGerritChange(*,*,*,*, true).currentPatchSet) | 
| Jakub Josef | 62899fd | 2017-06-15 18:53:46 +0200 | [diff] [blame] | 223 | */ | 
| Jakub Josef | 5aa33de | 2017-06-16 12:23:45 +0200 | [diff] [blame] | 224 | @NonCPS | 
| Jakub Josef | 798bfc5 | 2017-06-16 12:44:23 +0200 | [diff] [blame] | 225 | def patchsetHasApproval(patchSet, approvalType="Verified", approvalValue = ""){ | 
| Jakub Josef | 5aa33de | 2017-06-16 12:23:45 +0200 | [diff] [blame] | 226 | if(patchSet && patchSet.approvals){ | 
|  | 227 | for(int i=0; i < patchSet.approvals.size();i++){ | 
|  | 228 | def approval = patchSet.approvals.get(i) | 
| Jakub Josef | 798bfc5 | 2017-06-16 12:44:23 +0200 | [diff] [blame] | 229 | if(approval.type.equals(approvalType)){ | 
|  | 230 | if(approvalValue.equals("") || approval.value.equals(approvalValue)){ | 
|  | 231 | return true | 
| Jakub Josef | 996ada8 | 2017-06-16 12:59:43 +0200 | [diff] [blame] | 232 | }else if(approvalValue.equals("+") && Integer.parseInt(approval.value) > 0) { | 
|  | 233 | return true | 
|  | 234 | }else if(approvalValue.equals("-") && Integer.parseInt(approval.value) < 0) { | 
|  | 235 | return true | 
| Jakub Josef | 798bfc5 | 2017-06-16 12:44:23 +0200 | [diff] [blame] | 236 | } | 
| Jakub Josef | 5aa33de | 2017-06-16 12:23:45 +0200 | [diff] [blame] | 237 | } | 
|  | 238 | } | 
| Jakub Josef | 62899fd | 2017-06-15 18:53:46 +0200 | [diff] [blame] | 239 | } | 
|  | 240 | return false | 
|  | 241 | } | 
| Jakub Josef | 4edd743 | 2017-05-10 17:58:56 +0200 | [diff] [blame] | 242 |  | 
| Jakub Josef | d383f39 | 2017-03-29 16:52:04 +0200 | [diff] [blame] | 243 | @NonCPS | 
|  | 244 | def _getGerritParamsFromUrl(gitUrl){ | 
|  | 245 | def gitUrlPattern = Pattern.compile("(.+):\\/\\/(.+)@(.+):(.+)\\/(.+)") | 
|  | 246 | def gitUrlMatcher = gitUrlPattern.matcher(gitUrl) | 
|  | 247 | if(gitUrlMatcher.find() && gitUrlMatcher.groupCount() == 5){ | 
|  | 248 | return [gitUrlMatcher.group(1),gitUrlMatcher.group(2),gitUrlMatcher.group(3),gitUrlMatcher.group(4),gitUrlMatcher.group(5)] | 
|  | 249 | } | 
|  | 250 | return [] | 
|  | 251 | } | 
|  | 252 |  | 
| Dmitry Pyzhov | 169f812 | 2017-12-06 14:44:41 +0300 | [diff] [blame] | 253 | def _getInvalidGerritParams(LinkedHashMap config){ | 
|  | 254 | def requiredParams = ["gerritScheme", "gerritName", "gerritHost", "gerritPort", "gerritProject", "gerritBranch"] | 
|  | 255 | def missedParams = requiredParams - config.keySet() | 
|  | 256 | def badParams = config.subMap(requiredParams).findAll{it.value in [null, '']}.keySet() | 
|  | 257 | return badParams + missedParams | 
| vnaumov | 37b735d | 2018-08-27 16:55:07 +0400 | [diff] [blame] | 258 | } | 
| Denis Egorenko | 3253f46 | 2018-12-05 19:05:41 +0400 | [diff] [blame] | 259 |  | 
|  | 260 | /** | 
|  | 261 | * Post Gerrit comment from CI user | 
|  | 262 | * | 
|  | 263 | * @param config map which contains next params: | 
|  | 264 | *  gerritName - gerrit user name (usually GERRIT_NAME property) | 
|  | 265 | *  gerritHost - gerrit host (usually GERRIT_HOST property) | 
|  | 266 | *  gerritChangeNumber - gerrit change number (usually GERRIT_CHANGE_NUMBER property) | 
|  | 267 | *  gerritPatchSetNumber - gerrit patch set number (usually GERRIT_PATCHSET_NUMBER property) | 
|  | 268 | *  message - message to send to gerrit review patch | 
|  | 269 | *  credentialsId - jenkins credentials id for gerrit | 
|  | 270 | */ | 
|  | 271 | def postGerritComment(LinkedHashMap config) { | 
|  | 272 | def common = new com.mirantis.mk.Common() | 
|  | 273 | def ssh = new com.mirantis.mk.Ssh() | 
|  | 274 | String gerritName = config.get('gerritName') | 
|  | 275 | String gerritHost = config.get('gerritHost') | 
|  | 276 | String gerritChangeNumber = config.get('gerritChangeNumber') | 
|  | 277 | String gerritPatchSetNumber = config.get('gerritPatchSetNumber') | 
|  | 278 | String message = config.get('message') | 
|  | 279 | String credentialsId = config.get('credentialsId') | 
|  | 280 |  | 
|  | 281 | ssh.prepareSshAgentKey(credentialsId) | 
|  | 282 | ssh.ensureKnownHosts(gerritHost) | 
|  | 283 | ssh.agentSh(String.format("ssh -p 29418 %s@%s gerrit review %s,%s -m \"'%s'\" --code-review 0", gerritName, gerritHost, gerritChangeNumber, gerritPatchSetNumber, message)) | 
|  | 284 | } | 
| Denis Egorenko | 26da6c1 | 2018-11-16 14:38:42 +0400 | [diff] [blame] | 285 |  | 
|  | 286 | /** | 
|  | 287 | * Return map of dependent patches info for current patch set | 
|  | 288 | * based on commit message hints: Depends-On: https://gerrit_address/_CHANGE_NUMBER_ | 
|  | 289 | * @param changeInfo Map Info about current patch set, such as: | 
|  | 290 | *   gerritName Gerrit user name (usually GERRIT_NAME property) | 
|  | 291 | *   gerritHost Gerrit host (usually GERRIT_HOST property) | 
|  | 292 | *   gerritChangeNumber Gerrit change number (usually GERRIT_CHANGE_NUMBER property) | 
|  | 293 | *   credentialsId Jenkins credentials id for gerrit | 
|  | 294 | * @return map of dependent patches info | 
|  | 295 | */ | 
|  | 296 | LinkedHashMap getDependentPatches(LinkedHashMap changeInfo) { | 
|  | 297 | def dependentPatches = [:] | 
| Vladimir Khlyunev | 8091f63 | 2023-01-13 12:55:47 +0000 | [diff] [blame] | 298 | def currentChange = getGerritChange(changeInfo.gerritName, changeInfo.gerritHost, changeInfo.gerritChangeNumber, changeInfo.credentialsId, true) | 
|  | 299 | def dependentCommits = currentChange.commitMessage.tokenize('\n').findAll { it  ==~ /Depends-On: \b[^ ]+\b(\/)?/  } | 
| Denis Egorenko | 26da6c1 | 2018-11-16 14:38:42 +0400 | [diff] [blame] | 300 | if (dependentCommits) { | 
|  | 301 | dependentCommits.each { commit -> | 
|  | 302 | def patchLink = commit.tokenize(' ')[1] | 
|  | 303 | def changeNumber = patchLink.tokenize('/')[-1].trim() | 
|  | 304 | def dependentCommit = getGerritChange(changeInfo.gerritName, changeInfo.gerritHost, changeNumber, changeInfo.credentialsId, true) | 
|  | 305 | if (dependentCommit.status == "NEW") { | 
|  | 306 | dependentPatches[dependentCommit.project] = [ | 
|  | 307 | 'number': dependentCommit.number, | 
|  | 308 | 'ref': dependentCommit.currentPatchSet.ref, | 
|  | 309 | 'branch': dependentCommit.branch, | 
|  | 310 | ] | 
|  | 311 | } | 
|  | 312 | } | 
|  | 313 | } | 
|  | 314 | return dependentPatches | 
|  | 315 | } | 
| Oleksii Grudev | a64e5b2 | 2019-06-11 11:21:02 +0300 | [diff] [blame] | 316 |  | 
|  | 317 | /** | 
|  | 318 | * Find Gerrit change(s) according to various input parameters like owner, topic, etc. | 
|  | 319 | * @param gerritAuth        A map containing information about Gerrit. Should include | 
|  | 320 | *                          HOST, PORT and USER | 
|  | 321 | * @param changeParams      Parameters to identify Geriit change e.g.: owner, topic, | 
|  | 322 | *                          status, branch, project | 
| Alexandr Lovtsov | 5d22b2d | 2020-12-16 14:52:57 +0300 | [diff] [blame] | 323 | * @param extraFlags        Additional flags for gerrit querry for example | 
|  | 324 | *                          '--current-patch-set' or '--comments' as a simple string | 
| Oleksii Grudev | a64e5b2 | 2019-06-11 11:21:02 +0300 | [diff] [blame] | 325 | */ | 
| azvyagintsev | a00870c | 2023-12-07 12:59:12 +0200 | [diff] [blame] | 326 | def findGerritChange(credentialsId, LinkedHashMap gerritAuth, LinkedHashMap changeParams, String extraFlags = '', String sshOpts = '') { | 
| Oleksii Grudev | a64e5b2 | 2019-06-11 11:21:02 +0300 | [diff] [blame] | 327 | scriptText = """ | 
| azvyagintsev | a00870c | 2023-12-07 12:59:12 +0200 | [diff] [blame] | 328 | ssh ${sshOpts} -p ${gerritAuth['PORT']} ${gerritAuth['USER']}@${gerritAuth['HOST']} \ | 
| Alexandr Lovtsov | 5d22b2d | 2020-12-16 14:52:57 +0300 | [diff] [blame] | 329 | gerrit query ${extraFlags} \ | 
| Oleksii Grudev | a64e5b2 | 2019-06-11 11:21:02 +0300 | [diff] [blame] | 330 | --format JSON \ | 
|  | 331 | """ | 
|  | 332 | changeParams.each { | 
|  | 333 | scriptText += " ${it.key}:${it.value}" | 
|  | 334 | } | 
|  | 335 | scriptText += " | fgrep -v runTimeMilliseconds || :" | 
|  | 336 | sshagent([credentialsId]) { | 
|  | 337 | jsonChange = sh( | 
| azvyagintsev | a00870c | 2023-12-07 12:59:12 +0200 | [diff] [blame] | 338 | script: scriptText, | 
|  | 339 | returnStdout: true, | 
|  | 340 | ).trim() | 
| Oleksii Grudev | a64e5b2 | 2019-06-11 11:21:02 +0300 | [diff] [blame] | 341 | } | 
|  | 342 | return jsonChange | 
|  | 343 | } | 
|  | 344 |  | 
|  | 345 | /** | 
|  | 346 | * Download Gerrit review by number | 
|  | 347 | * | 
|  | 348 | * @param credentialsId            credentials ID | 
|  | 349 | * @param virtualenv               virtualenv path | 
|  | 350 | * @param repoDir                  repository directory | 
|  | 351 | * @param gitRemote                the value of git remote | 
|  | 352 | * @param changeNum                the number of change to download | 
|  | 353 | */ | 
|  | 354 | def getGerritChangeByNum(credentialsId, virtualEnv, repoDir, gitRemote, changeNum) { | 
|  | 355 | def python = new com.mirantis.mk.Python() | 
|  | 356 | sshagent([credentialsId]) { | 
|  | 357 | dir(repoDir) { | 
|  | 358 | python.runVirtualenvCommand(virtualEnv, "git review -r ${gitRemote} -d ${changeNum}") | 
|  | 359 | } | 
|  | 360 | } | 
|  | 361 | } | 
|  | 362 |  | 
|  | 363 | /** | 
|  | 364 | * Post Gerrit review | 
|  | 365 | * @param credentialsId            credentials ID | 
|  | 366 | * @param virtualenv               virtualenv path | 
|  | 367 | * @param repoDir                  repository directory | 
|  | 368 | * @param gitName                  committer name | 
|  | 369 | * @param gitEmail                 committer email | 
|  | 370 | * @param gitRemote                the value of git remote | 
|  | 371 | * @param gitTopic                 the name of the topic | 
|  | 372 | * @param gitBranch                the name of git branch | 
|  | 373 | */ | 
|  | 374 | def postGerritReview(credentialsId, virtualEnv, repoDir, gitName, gitEmail, gitRemote, gitTopic, gitBranch) { | 
|  | 375 | def python = new com.mirantis.mk.Python() | 
| Dmitry Teselkin | 3bb1c03 | 2019-12-12 19:33:58 +0300 | [diff] [blame] | 376 | def common = new com.mirantis.mk.Common() | 
| Oleksii Grudev | a64e5b2 | 2019-06-11 11:21:02 +0300 | [diff] [blame] | 377 | def cmdText = """ | 
|  | 378 | GIT_COMMITTER_NAME=${gitName} \ | 
|  | 379 | GIT_COMMITTER_EMAIL=${gitEmail} \ | 
|  | 380 | git review -r ${gitRemote} \ | 
|  | 381 | -t ${gitTopic} \ | 
|  | 382 | ${gitBranch} | 
|  | 383 | """ | 
|  | 384 | sshagent([credentialsId]) { | 
|  | 385 | dir(repoDir) { | 
| Dmitry Teselkin | 3bb1c03 | 2019-12-12 19:33:58 +0300 | [diff] [blame] | 386 | res = python.runVirtualenvCommand(virtualEnv, cmdText) | 
|  | 387 | common.infoMsg(res) | 
| Oleksii Grudev | a64e5b2 | 2019-06-11 11:21:02 +0300 | [diff] [blame] | 388 | } | 
|  | 389 | } | 
|  | 390 | } | 
| Denis Egorenko | f35e00b | 2019-11-13 16:29:50 +0400 | [diff] [blame] | 391 |  | 
|  | 392 | /** | 
|  | 393 | * Prepare and upload Gerrit commit from prepared repo | 
|  | 394 | * @param LinkedHashMap params dict with parameters | 
|  | 395 | *   venvDir - Absolute path to virtualenv dir | 
|  | 396 | *   gerritCredentials - credentialsId | 
|  | 397 | *   gerritHost - gerrit host | 
|  | 398 | *   gerritPort - gerrit port | 
|  | 399 | *   repoDir - path to repo dir | 
|  | 400 | *   repoProject - repo name | 
|  | 401 | *   repoBranch - repo branch | 
|  | 402 | *   changeCommitComment - comment for commit message | 
|  | 403 | *   changeAuthorName - change author | 
|  | 404 | *   changeAuthorEmail - author email | 
|  | 405 | *   changeTopic - change topic | 
|  | 406 | *   gitRemote - git remote | 
|  | 407 | *   returnChangeInfo - whether to return info about uploaded change | 
|  | 408 | * | 
|  | 409 | * @return map with change info if returnChangeInfo set to true | 
|  | 410 | */ | 
|  | 411 | def prepareGerritAutoCommit(LinkedHashMap params) { | 
|  | 412 | def common = new com.mirantis.mk.Common() | 
|  | 413 | def git = new com.mirantis.mk.Git() | 
|  | 414 | String venvDir = params.get('venvDir') | 
|  | 415 | String gerritCredentials = params.get('gerritCredentials') | 
|  | 416 | String gerritHost = params.get('gerritHost', 'gerrit.mcp.mirantis.net') | 
|  | 417 | String gerritPort = params.get('gerritPort', '29418') | 
|  | 418 | String gerritUser = common.getCredentialsById(gerritCredentials, 'sshKey').username | 
|  | 419 | String repoDir = params.get('repoDir') | 
|  | 420 | String repoProject = params.get('repoProject') | 
|  | 421 | String repoBranch = params.get('repoBranch', 'master') | 
|  | 422 | String changeCommitComment = params.get('changeCommitComment') | 
|  | 423 | String changeAuthorName = params.get('changeAuthorName', 'MCP-CI') | 
|  | 424 | String changeAuthorEmail = params.get('changeAuthorEmail', 'mcp-ci-jenkins@ci.mcp.mirantis.net') | 
|  | 425 | String changeTopic = params.get('changeTopic', 'auto_ci') | 
|  | 426 | Boolean returnChangeInfo = params.get('returnChangeInfo', false) | 
|  | 427 | String gitRemote = params.get('gitRemote', '') | 
|  | 428 | if (! gitRemote) { | 
|  | 429 | dir(repoDir) { | 
|  | 430 | gitRemote = sh( | 
|  | 431 | script: | 
|  | 432 | 'git remote -v | head -n1 | cut -f1', | 
|  | 433 | returnStdout: true, | 
|  | 434 | ).trim() | 
|  | 435 | } | 
|  | 436 | } | 
|  | 437 | def gerritAuth = ['PORT': gerritPort, 'USER': gerritUser, 'HOST': gerritHost ] | 
|  | 438 | def changeParams = ['owner': gerritUser, 'status': 'open', 'project': repoProject, 'branch': repoBranch, 'topic': changeTopic] | 
|  | 439 | // find if there is old commit present | 
|  | 440 | def gerritChange = findGerritChange(gerritCredentials, gerritAuth, changeParams) | 
|  | 441 | def changeId = '' | 
|  | 442 | if (gerritChange) { | 
|  | 443 | try { | 
|  | 444 | def jsonChange = readJSON text: gerritChange | 
|  | 445 | changeId = "Change-Id: ${jsonChange['id']}".toString() | 
|  | 446 | } catch (Exception error) { | 
|  | 447 | common.errorMsg("Can't parse ouput from Gerrit. Check that user ${changeAuthorName} does not have several \ | 
|  | 448 | open commits to ${repoProject} repo and ${repoBranch} branch with topic ${changeTopic}") | 
|  | 449 | throw error | 
|  | 450 | } | 
|  | 451 | } | 
|  | 452 | def commitMessage = | 
|  | 453 | """${changeCommitComment} | 
|  | 454 |  | 
|  | 455 | |${changeId} | 
|  | 456 | """.stripMargin() | 
|  | 457 | git.commitGitChanges(repoDir, commitMessage, changeAuthorEmail, changeAuthorName, false) | 
|  | 458 | //post change | 
|  | 459 | postGerritReview(gerritCredentials, venvDir, repoDir, changeAuthorName, changeAuthorEmail, gitRemote, changeTopic, repoBranch) | 
|  | 460 | if (returnChangeInfo) { | 
|  | 461 | gerritChange = findGerritChange(gerritCredentials, gerritAuth, changeParams) | 
|  | 462 | jsonChange = readJSON text: gerritChange | 
|  | 463 | return getGerritChange(gerritUser, gerritHost, jsonChange['number'], gerritCredentials, true) | 
|  | 464 | } | 
|  | 465 | } | 
| Mykyta Karpin | 0373e49 | 2020-04-17 11:30:19 +0300 | [diff] [blame] | 466 |  | 
|  | 467 | /** | 
| Mykyta Karpin | 82a2e2a | 2021-07-09 17:53:01 +0300 | [diff] [blame] | 468 | * Get email and username from credentials id | 
|  | 469 | * @param credentialsId      Credentials ID to use for source Git | 
|  | 470 | */ | 
|  | 471 | def getGerritUserOptions(credentialsId) { | 
|  | 472 | def changeAuthorName = "MCP-CI" | 
|  | 473 | def changeAuthorEmail = "mcp-ci-jenkins@ci.mcp.mirantis.net" | 
|  | 474 |  | 
|  | 475 | switch (credentialsId) { | 
|  | 476 | case 'mos-ci': | 
|  | 477 | changeAuthorName = "MOS-CI" | 
|  | 478 | changeAuthorEmail = "infra+mos-ci@mirantis.com" | 
|  | 479 | break; | 
|  | 480 | case 'mcp-ci-gerrit': | 
|  | 481 | changeAuthorName = "MCP-CI" | 
|  | 482 | changeAuthorEmail = "mcp-ci-jenkins@ci.mcp.mirantis.net" | 
|  | 483 | break; | 
| Vasyl Saienko | 56d08f4 | 2024-08-01 12:53:04 +0300 | [diff] [blame] | 484 | case 'product-ci': | 
|  | 485 | changeAuThorName = "Product CI" | 
|  | 486 | changeAuthorEmail = "infra+product-ci@mirantis.com" | 
|  | 487 | break; | 
| Vasyl Saienko | 8ee26a0 | 2024-08-02 19:13:51 +0300 | [diff] [blame] | 488 | case 'services-ci': | 
|  | 489 | changeAuThorName = "Services CI" | 
|  | 490 | changeAuthorEmail = "infra+services-ci@mirantis.com" | 
|  | 491 | break; | 
| Mykyta Karpin | 82a2e2a | 2021-07-09 17:53:01 +0300 | [diff] [blame] | 492 | } | 
|  | 493 | return ["changeAuthorName": changeAuthorName, | 
|  | 494 | "changeAuthorEmail": changeAuthorEmail] | 
|  | 495 | } | 
|  | 496 |  | 
|  | 497 | /** | 
| Mykyta Karpin | 0373e49 | 2020-04-17 11:30:19 +0300 | [diff] [blame] | 498 | * Download change from gerrit, if needed repository maybe pre cloned | 
|  | 499 | * | 
|  | 500 | * @param path               Directory to checkout repository to | 
|  | 501 | * @param url                Source Gerrit repository URL | 
|  | 502 | * @param reference          Gerrit reference to download (e.g refs/changes/77/66777/16) | 
|  | 503 | * @param type               type of gerrit download | 
|  | 504 | * @param credentialsId      Credentials ID to use for source Git | 
|  | 505 | * @param gitCheckoutParams  map with additional parameters for git.checkoutGitRepository method e.g: | 
|  | 506 | *                           [ branch: 'master', poll: true, timeout: 10, depth: 0 ] | 
|  | 507 | * @param doGitClone      boolean whether to pre clone and do some checkout | 
|  | 508 | */ | 
|  | 509 | def downloadChange(path, url, reference, credentialsId, type = 'cherry-pick', doGitClone = true, Map gitCheckoutParams = [:]){ | 
| Mykyta Karpin | 32cafd6 | 2021-07-01 17:28:03 +0300 | [diff] [blame] | 510 | def common = new com.mirantis.mk.Common() | 
| Mykyta Karpin | 0373e49 | 2020-04-17 11:30:19 +0300 | [diff] [blame] | 511 | def git = new com.mirantis.mk.Git() | 
|  | 512 | def ssh = new com.mirantis.mk.Ssh() | 
|  | 513 | def cmd | 
| Mykyta Karpin | 32cafd6 | 2021-07-01 17:28:03 +0300 | [diff] [blame] | 514 | def credentials = common.getCredentialsById(credentialsId) | 
| Mykyta Karpin | 82a2e2a | 2021-07-09 17:53:01 +0300 | [diff] [blame] | 515 | Map gerritUserOptions = getGerritUserOptions(credentialsId) | 
| Mykyta Karpin | 0ff6878 | 2021-07-09 18:38:43 +0300 | [diff] [blame] | 516 | String gitCommiterOpts = "GIT_COMMITTER_EMAIL=\'${gerritUserOptions['changeAuthorEmail']}\' GIT_COMMITTER_NAME=\'${gerritUserOptions['changeAuthorName']}\'" | 
| Mykyta Karpin | 0373e49 | 2020-04-17 11:30:19 +0300 | [diff] [blame] | 517 | switch(type) { | 
|  | 518 | case 'cherry-pick': | 
| Mykyta Karpin | 82a2e2a | 2021-07-09 17:53:01 +0300 | [diff] [blame] | 519 | cmd = "git fetch ${url} ${reference} && ${gitCommiterOpts} git cherry-pick FETCH_HEAD" | 
| Mykyta Karpin | 0373e49 | 2020-04-17 11:30:19 +0300 | [diff] [blame] | 520 | break; | 
|  | 521 | case 'format-patch': | 
|  | 522 | cmd = "git fetch ${url} ${reference} && git format-patch -1 --stdout FETCH_HEAD" | 
|  | 523 | break; | 
|  | 524 | case 'pull': | 
|  | 525 | cmd = "git pull ${url} ${reference}" | 
|  | 526 | break; | 
|  | 527 | default: | 
|  | 528 | error("Unsupported gerrit download type") | 
|  | 529 | } | 
|  | 530 | if (doGitClone) { | 
|  | 531 | def branch =  gitCheckoutParams.get('branch', 'master') | 
|  | 532 | def poll = gitCheckoutParams.get('poll', true) | 
|  | 533 | def timeout = gitCheckoutParams.get('timeout', 10) | 
|  | 534 | def depth = gitCheckoutParams.get('depth', 0) | 
|  | 535 | git.checkoutGitRepository(path, url, branch, credentialsId, poll, timeout, depth, '') | 
|  | 536 | } | 
| Mykyta Karpin | 32cafd6 | 2021-07-01 17:28:03 +0300 | [diff] [blame] | 537 | sshagent (credentials: [credentialsId]) { | 
|  | 538 | dir(path){ | 
|  | 539 | sh(script: "GIT_SSH_COMMAND='ssh -l ${credentials.username}' ${cmd}", returnStdout:true) | 
|  | 540 | } | 
| Mykyta Karpin | 0373e49 | 2020-04-17 11:30:19 +0300 | [diff] [blame] | 541 | } | 
|  | 542 | } | 
|  | 543 |  | 
|  | 544 | /** | 
|  | 545 | * Parse gerrit event text and if Workflow +1 is detected, | 
|  | 546 | * return true | 
|  | 547 | * | 
|  | 548 | * @param gerritEventCommentText  gerrit event comment text | 
|  | 549 | * @param gerritEventType         type of gerrit event | 
|  | 550 | */ | 
|  | 551 | def isGate(gerritEventCommentText, gerritEventType) { | 
|  | 552 | def common = new com.mirantis.mk.Common() | 
|  | 553 | def gerritEventCommentTextStr = '' | 
|  | 554 | def res = false | 
|  | 555 | if (gerritEventCommentText) { | 
|  | 556 | try{ | 
|  | 557 | gerritEventCommentTextStr = new String(gerritEventCommentText.decodeBase64()) | 
|  | 558 | } catch (e) { | 
|  | 559 | gerritEventCommentTextStr = gerritEventCommentText | 
|  | 560 | } | 
|  | 561 | common.infoMsg("GERRIT_EVENT_COMMENT_TEXT is ${gerritEventCommentTextStr}") | 
|  | 562 | } | 
| Mykyta Karpin | 4d03a40 | 2022-12-28 15:21:24 +0200 | [diff] [blame] | 563 | def gateComment = gerritEventCommentTextStr.split('\n')[0] | 
| Mykyta Karpin | f96210a | 2022-12-29 09:30:50 +0200 | [diff] [blame] | 564 | if (gerritEventType == 'comment-added' && gateComment =~ /^Patch Set \d+:\s.*Workflow\+1.*$/) { | 
| Mykyta Karpin | 0373e49 | 2020-04-17 11:30:19 +0300 | [diff] [blame] | 565 | common.infoMsg("Running in gate mode") | 
|  | 566 | res = true | 
|  | 567 | } | 
|  | 568 | return res | 
|  | 569 | } | 
| Ihor Hryshchenko | 4801bd5 | 2023-11-29 18:07:02 +0200 | [diff] [blame] | 570 |  | 
|  | 571 | /** | 
|  | 572 | * Get gerrit change based on a given refspec. | 
|  | 573 | * | 
|  | 574 | * @param gerritAuth A map containing Gerrit authentication details (credentialsId, USER, HOST, PORT). | 
|  | 575 | * @param repoName The name of the repository. | 
|  | 576 | * @param refSpec The refspec or commit hash. | 
|  | 577 | * @return A map containing information about the Gerrit change. | 
|  | 578 | */ | 
|  | 579 | def getGerritChangeInfoByRefspec(Map gerritAuth, String repoName, String refSpec) { | 
| Ihor Hryshchenko | f922141 | 2024-12-03 12:53:29 +0200 | [diff] [blame] | 580 | def common = new com.mirantis.mk.Common() | 
|  | 581 | String commitHash = '' | 
|  | 582 | if (refSpec.startsWith('refs/') || refSpec == 'master') { | 
|  | 583 | // why we have retry here? bz infra is awesome and stable! | 
|  | 584 | common.retry(15, 10) { | 
|  | 585 | sshagent([gerritAuth['credentialsId']]) { | 
|  | 586 | commitHash = sh(script: "git ls-remote ssh://${gerritAuth['USER']}@${gerritAuth['HOST']}:${gerritAuth['PORT']}/${repoName} ${refSpec}", returnStdout: true).trim().split('\\t')[0] | 
|  | 587 | } | 
|  | 588 | } | 
|  | 589 | } else { | 
|  | 590 | commitHash = refSpec | 
| Ihor Hryshchenko | 4801bd5 | 2023-11-29 18:07:02 +0200 | [diff] [blame] | 591 | } | 
| Ihor Hryshchenko | f922141 | 2024-12-03 12:53:29 +0200 | [diff] [blame] | 592 | if (!commitHash) { | 
|  | 593 | common.errorMsg("Could not get commit hash for refspec '${refSpec}'") | 
|  | 594 | return [:] | 
|  | 595 | } | 
|  | 596 | LinkedHashMap gerritQuery = [ | 
|  | 597 | 'commit': commitHash, | 
|  | 598 | ] | 
|  | 599 | String gerritFlags = '--current-patch-set' | 
|  | 600 | String patchsetRawJson = findGerritChange(gerritAuth['credentialsId'], gerritAuth, gerritQuery, gerritFlags) | 
|  | 601 | if (!patchsetRawJson) { | 
|  | 602 | // WARNING(alexz): gerrit search only by CR. so merge event,like https://gerrit.mcp.mirantis.com/plugins/gitiles/kaas/si-tests/+/cabb45ea73ac538c653d62cb0a2ffb4802521251 | 
|  | 603 | // will not be catched here. In that case, return dummy raw_commit_hash only | 
|  | 604 | common.errorMsg("Could not find gerrit change as refspec '${refSpec}' (commit: ${commitHash})") | 
|  | 605 | return ['raw_commit_hash': commitHash] | 
|  | 606 | } | 
|  | 607 | try { | 
|  | 608 | // It can (and should) return only one json for given commitHash | 
|  | 609 | return readYaml(text: patchsetRawJson) | 
|  | 610 | } catch (Exception e) { | 
|  | 611 | common.errorMsg("Could not parse JSON: ${patchsetRawJson}\nError: ${e}") | 
|  | 612 | return [:] | 
|  | 613 | } | 
| Ihor Hryshchenko | 4801bd5 | 2023-11-29 18:07:02 +0200 | [diff] [blame] | 614 | } | 
| Ihor Hryshchenko | f922141 | 2024-12-03 12:53:29 +0200 | [diff] [blame] | 615 |  | 
|  | 616 | /** | 
|  | 617 | * Get gerrit repository tags with gerrit API. | 
|  | 618 | * | 
|  | 619 | * @param repoName The name of the repository. | 
|  | 620 | * @param credentialsId jenkins credentials id. | 
|  | 621 | * @param trimTag Whether to trim the leading 'v' from tags. | 
|  | 622 | * @return A list containing all repository tags. | 
|  | 623 | */ | 
|  | 624 | def listRepoTags(String repoName, String credentialsId, Boolean trimTag = false) { | 
|  | 625 | def common = new com.mirantis.mk.Common() | 
|  | 626 | def replacePattern = trimTag ? 'refs/tags/v' : 'refs/tags/' | 
|  | 627 | def coreTags = '' | 
|  | 628 | def tags = [] | 
|  | 629 | withCredentials([usernamePassword(credentialsId: credentialsId, | 
|  | 630 | usernameVariable: 'GERRIT_USERNAME', | 
|  | 631 | passwordVariable: 'GERRIT_PASSWORD')]) { | 
|  | 632 | common.retry(15, 10) { | 
|  | 633 | coreTags = sh(script: "echo \${GERRIT_PASSWORD} | curl -u ${GERRIT_USERNAME} https://gerrit.mcp.mirantis.com/a/projects/${repoName}/tags", returnStdout: true).trim() | 
|  | 634 | } | 
|  | 635 | } | 
|  | 636 | def jsonResponse = coreTags.split('\n').last() | 
|  | 637 | def jsonTags = readJSON text: jsonResponse | 
|  | 638 | jsonTags.each { tagData -> | 
|  | 639 | def tag = tagData['ref']?.replace(replacePattern, '') | 
|  | 640 | if (tag) { | 
|  | 641 | tags.add(tag) | 
|  | 642 | } | 
|  | 643 | } | 
|  | 644 |  | 
|  | 645 | return tags | 
|  | 646 | } |