blob: f699b3e913e1efc2448ea8cff10ac8e2dbddb0c8 [file] [log] [blame]
Sergey Kolekonovba203982016-12-21 18:32:17 +04001package com.mirantis.mk
2
3/**
4 *
5 * Git functions
6 *
7 */
8
9/**
10 * Checkout single git repository
11 *
12 * @param path Directory to checkout repository to
13 * @param url Source Git repository URL
14 * @param branch Source Git repository branch
15 * @param credentialsId Credentials ID to use for source Git
Jakub Josef7dccebe2017-03-06 18:08:32 +010016 * @param poll Enable git polling (default true)
17 * @param timeout Set checkout timeout (default 10)
Jakub Josef61f29e62017-03-08 16:42:06 +010018 * @param depth Git depth param (default 0 means no depth)
Alexandr Lovtsove818e102019-07-29 14:45:01 +030019 * @param reference Git reference param to checkout (default empyt, i.e. no reference)
Sergey Kolekonovba203982016-12-21 18:32:17 +040020 */
Alexandr Lovtsove818e102019-07-29 14:45:01 +030021def checkoutGitRepository(path, url, branch, credentialsId = null, poll = true, timeout = 10, depth = 0, reference = ''){
Alexandr Lovtsov73786142019-09-02 17:45:12 +030022 def branch_name = reference ? 'FETCH_HEAD' : "*/${branch}"
Sergey Kolekonovba203982016-12-21 18:32:17 +040023 dir(path) {
Jakub Josef6fa8cb12017-03-06 18:20:08 +010024 checkout(
25 changelog:true,
26 poll: poll,
27 scm: [
28 $class: 'GitSCM',
Alexandr Lovtsov73786142019-09-02 17:45:12 +030029 branches: [[name: branch_name]],
Jakub Josef6fa8cb12017-03-06 18:20:08 +010030 doGenerateSubmoduleConfigurations: false,
31 extensions: [
Jakub Josef61f29e62017-03-08 16:42:06 +010032 [$class: 'CheckoutOption', timeout: timeout],
Alexandr Lovtsov73786142019-09-02 17:45:12 +030033 [$class: 'CloneOption', depth: depth, noTags: false, shallow: depth > 0, timeout: timeout]],
Jakub Josef6fa8cb12017-03-06 18:20:08 +010034 submoduleCfg: [],
Alexandr Lovtsov73786142019-09-02 17:45:12 +030035 userRemoteConfigs: [[url: url, credentialsId: credentialsId, refspec: reference]]]
Jakub Josef6fa8cb12017-03-06 18:20:08 +010036 )
Sergey Kolekonovba203982016-12-21 18:32:17 +040037 sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
38 }
39}
40
41/**
42 * Parse HEAD of current directory and return commit hash
43 */
44def getGitCommit() {
45 git_commit = sh (
46 script: 'git rev-parse HEAD',
47 returnStdout: true
48 ).trim()
49 return git_commit
50}
51
52/**
Ales Komarekfb7cbcb2017-02-24 14:02:03 +010053 * Change actual working branch of repo
54 *
55 * @param path Path to the git repository
56 * @param branch Branch desired to switch to
57 */
58def changeGitBranch(path, branch) {
59 dir(path) {
60 git_cmd = sh (
Leontii Istominb4f4ae12018-02-27 20:25:43 +010061 script: "git checkout ${branch}",
Ales Komarekfb7cbcb2017-02-24 14:02:03 +010062 returnStdout: true
63 ).trim()
64 }
65 return git_cmd
66}
67
68/**
Ales Komarekc3a8b972017-03-24 13:57:25 +010069 * Get remote URL
70 *
71 * @param name Name of remote (default any)
72 * @param type Type (fetch or push, default fetch)
73 */
74def getGitRemote(name = '', type = 'fetch') {
75 gitRemote = sh (
76 script: "git remote -v | grep '${name}' | grep ${type} | awk '{print \$2}' | head -1",
77 returnStdout: true
78 ).trim()
79 return gitRemote
80}
81
82/**
Alexandr Lovtsovd1540612020-05-07 14:10:37 +030083 * Get commit message for given commit reference
84 */
85def getGitCommitMessage(String path, String commitRef = 'HEAD') {
86 dir(path) {
87 commitMsg = sh (
88 script: "git log --format=%B -n 1 ${commitRef}",
89 returnStdout: true
90 ).trim()
91 }
92 return commitMsg
93}
94
95/**
Ales Komarekc3a8b972017-03-24 13:57:25 +010096 * Create new working branch for repo
97 *
98 * @param path Path to the git repository
99 * @param branch Branch desired to switch to
100 */
101def createGitBranch(path, branch) {
102 def git_cmd
103 dir(path) {
104 git_cmd = sh (
105 script: "git checkout -b ${branch}",
106 returnStdout: true
107 ).trim()
108 }
109 return git_cmd
110}
111
112/**
Ales Komarekfb7cbcb2017-02-24 14:02:03 +0100113 * Commit changes to the git repo
114 *
115 * @param path Path to the git repository
116 * @param message A commit message
Denis Egorenkof4c45512019-03-04 15:53:36 +0400117 * @param global Use global config
Oleksii Grudeva64e5b22019-06-11 11:21:02 +0300118 * @param amend Whether to use "--amend" in commit command
Ales Komarekfb7cbcb2017-02-24 14:02:03 +0100119 */
Oleksii Grudeva64e5b22019-06-11 11:21:02 +0300120def commitGitChanges(path, message, gitEmail='jenkins@localhost', gitName='jenkins-slave', global=false, amend=false) {
Ales Komarekc3a8b972017-03-24 13:57:25 +0100121 def git_cmd
Oleksii Grudeva64e5b22019-06-11 11:21:02 +0300122 def gitOpts
Denis Egorenkof4c45512019-03-04 15:53:36 +0400123 def global_arg = ''
124 if (global) {
125 global_arg = '--global'
126 }
Oleksii Grudeva64e5b22019-06-11 11:21:02 +0300127 if (amend) {
128 gitOpts = '--amend'
129 } else {
130 gitOpts = ''
131 }
Ales Komarekfb7cbcb2017-02-24 14:02:03 +0100132 dir(path) {
Denis Egorenkof4c45512019-03-04 15:53:36 +0400133 sh "git config ${global_arg} user.email '${gitEmail}'"
134 sh "git config ${global_arg} user.name '${gitName}'"
Tomáš Kukráldf7bebc2017-03-27 15:12:43 +0200135
Ales Komarekfb7cbcb2017-02-24 14:02:03 +0100136 sh(
137 script: 'git add -A',
138 returnStdout: true
139 ).trim()
140 git_cmd = sh(
Oleksii Grudeva64e5b22019-06-11 11:21:02 +0300141 script: "git commit ${gitOpts} -m '${message}'",
Ales Komarekfb7cbcb2017-02-24 14:02:03 +0100142 returnStdout: true
143 ).trim()
144 }
145 return git_cmd
146}
147
Ales Komarekfb7cbcb2017-02-24 14:02:03 +0100148/**
149 * Push git changes to remote repo
150 *
Ales Komarekc3a8b972017-03-24 13:57:25 +0100151 * @param path Path to the local git repository
Ales Komarekfb7cbcb2017-02-24 14:02:03 +0100152 * @param branch Branch on the remote git repository
153 * @param remote Name of the remote repository
Ales Komarekc3a8b972017-03-24 13:57:25 +0100154 * @param credentialsId Credentials with write permissions
Ales Komarekfb7cbcb2017-02-24 14:02:03 +0100155 */
Ales Komarekc3a8b972017-03-24 13:57:25 +0100156def pushGitChanges(path, branch = 'master', remote = 'origin', credentialsId = null) {
157 def ssh = new com.mirantis.mk.Ssh()
Ales Komarekfb7cbcb2017-02-24 14:02:03 +0100158 dir(path) {
Ales Komarekc3a8b972017-03-24 13:57:25 +0100159 if (credentialsId == null) {
160 sh script: "git push ${remote} ${branch}"
161 }
162 else {
163 ssh.prepareSshAgentKey(credentialsId)
164 ssh.runSshAgentCommand("git push ${remote} ${branch}")
165 }
Ales Komarekfb7cbcb2017-02-24 14:02:03 +0100166 }
Ales Komarekfb7cbcb2017-02-24 14:02:03 +0100167}
168
Ales Komarekc3a8b972017-03-24 13:57:25 +0100169
Sergey Kolekonovba203982016-12-21 18:32:17 +0400170/**
Filip Pytloun49d66302017-03-06 10:26:22 +0100171 * Mirror git repository, merge target changes (downstream) on top of source
172 * (upstream) and push target or both if pushSource is true
173 *
174 * @param sourceUrl Source git repository
175 * @param targetUrl Target git repository
Ivan Berezovskiycf269442019-07-18 16:15:26 +0400176 * @param credentialsId Credentials id to use for accessing target repositories
Filip Pytloun49d66302017-03-06 10:26:22 +0100177 * @param branches List or comma-separated string of branches to sync
178 * @param followTags Mirror tags
179 * @param pushSource Push back into source branch, resulting in 2-way sync
180 * @param pushSourceTags Push target tags into source or skip pushing tags
181 * @param gitEmail Email for creation of merge commits
182 * @param gitName Name for creation of merge commits
Sergey Kolekonovba203982016-12-21 18:32:17 +0400183 */
Ivan Berezovskiycf269442019-07-18 16:15:26 +0400184def mirrorGit(sourceUrl, targetUrl, credentialsId, branches, followTags = false, pushSource = false, pushSourceTags = false, gitEmail = 'jenkins@localhost', gitName = 'Jenkins', sourceRemote = 'origin') {
Jakub Josef668dc2b2017-06-19 16:55:26 +0200185 def common = new com.mirantis.mk.Common()
186 def ssh = new com.mirantis.mk.Ssh()
Sergey Kolekonovba203982016-12-21 18:32:17 +0400187 if (branches instanceof String) {
188 branches = branches.tokenize(',')
189 }
Ivan Berezovskiycf269442019-07-18 16:15:26 +0400190 // If both source and target repos are secured and accessible via http/https,
191 // we need to switch GIT_ASKPASS value when running git commands
192 def sourceAskPass
193 def targetAskPass
Sergey Kolekonovba203982016-12-21 18:32:17 +0400194
Ivan Berezovskiycf269442019-07-18 16:15:26 +0400195 def sshCreds = common.getCredentialsById(credentialsId, 'sshKey') // True if found
196 if (sshCreds) {
197 ssh.prepareSshAgentKey(credentialsId)
198 ssh.ensureKnownHosts(targetUrl)
199 sh "git config user.name '${gitName}'"
200 } else {
201 withCredentials([[$class : 'UsernamePasswordMultiBinding',
202 credentialsId : credentialsId,
203 passwordVariable: 'GIT_PASSWORD',
204 usernameVariable: 'GIT_USERNAME']]) {
205 sh """
206 set +x
207 git config --global credential.${targetUrl}.username \${GIT_USERNAME}
208 echo "echo \${GIT_PASSWORD}" > ${WORKSPACE}/${credentialsId}_askpass.sh
209 chmod +x ${WORKSPACE}/${credentialsId}_askpass.sh
210 git config user.name \${GIT_USERNAME}
211 """
212 sourceAskPass = env.GIT_ASKPASS ?: ''
213 targetAskPass = "${WORKSPACE}/${credentialsId}_askpass.sh"
214 }
215 }
Filip Pytloun49d66302017-03-06 10:26:22 +0100216 sh "git config user.email '${gitEmail}'"
Filip Pytloun49d66302017-03-06 10:26:22 +0100217
Jakub Josef1caa7ae2017-08-21 16:39:00 +0200218 def remoteExistence = sh(script: "git remote -v | grep ${TARGET_URL} | grep target", returnStatus: true)
Ivan Berezovskiycf269442019-07-18 16:15:26 +0400219 if(remoteExistence == 0) {
220 // silently try to remove target
221 sh(script: "git remote remove target", returnStatus: true)
Jakub Josef1caa7ae2017-08-21 16:39:00 +0200222 }
Ivan Berezovskiycf269442019-07-18 16:15:26 +0400223 sh("git remote add target ${TARGET_URL}")
224 if (sshCreds) {
225 ssh.agentSh "git remote update --prune"
226 } else {
227 env.GIT_ASKPASS = sourceAskPass
228 sh "git remote update ${sourceRemote} --prune"
229 env.GIT_ASKPASS = targetAskPass
230 sh "git remote update target --prune"
231 }
Filip Pytloun49d66302017-03-06 10:26:22 +0100232
Sergey Kolekonovba203982016-12-21 18:32:17 +0400233 for (i=0; i < branches.size; i++) {
234 branch = branches[i]
Jakub Josef668dc2b2017-06-19 16:55:26 +0200235 sh "git branch | grep ${branch} || git checkout -b ${branch}"
236 def resetResult = sh(script: "git checkout ${branch} && git reset --hard origin/${branch}", returnStatus: true)
237 if(resetResult != 0){
238 common.warningMsg("Cannot reset to origin/${branch} for perform git mirror, trying to reset from target/${branch}")
239 resetResult = sh(script: "git checkout ${branch} && git reset --hard target/${branch}", returnStatus: true)
240 if(resetResult != 0){
241 throw new Exception("Cannot reset even to target/${branch}, git mirroring failed!")
242 }
243 }
Sergey Kolekonovba203982016-12-21 18:32:17 +0400244
Sergey Kolekonovba203982016-12-21 18:32:17 +0400245 sh "git ls-tree target/${branch} && git merge --no-edit --ff target/${branch} || echo 'Target repository is empty, skipping merge'"
246 followTagsArg = followTags ? "--follow-tags" : ""
Ivan Berezovskiycf269442019-07-18 16:15:26 +0400247 if (sshCreds) {
248 ssh.agentSh "git push ${followTagsArg} target HEAD:${branch}"
249 } else {
250 sh "git push ${followTagsArg} target HEAD:${branch}"
251 }
Filip Pytloun49d66302017-03-06 10:26:22 +0100252
253 if (pushSource == true) {
254 followTagsArg = followTags && pushSourceTags ? "--follow-tags" : ""
Ivan Berezovskiycf269442019-07-18 16:15:26 +0400255 if (sshCreds) {
256 ssh.agentSh "git push ${followTagsArg} origin HEAD:${branch}"
257 } else {
258 sh "git push ${followTagsArg} origin HEAD:${branch}"
259 }
Filip Pytloun49d66302017-03-06 10:26:22 +0100260 }
261 }
Filip Pytloun49d66302017-03-06 10:26:22 +0100262 if (followTags == true) {
Ivan Berezovskiycf269442019-07-18 16:15:26 +0400263 if (sshCreds) {
264 ssh.agentSh "git push -f target --tags"
265 } else {
266 sh "git push -f target --tags"
267 }
Filip Pytloun49d66302017-03-06 10:26:22 +0100268
269 if (pushSourceTags == true) {
Ivan Berezovskiycf269442019-07-18 16:15:26 +0400270 if (sshCreds) {
271 ssh.agentSh "git push -f origin --tags"
272 } else {
273 sh "git push -f origin --tags"
274 }
Filip Pytloun49d66302017-03-06 10:26:22 +0100275 }
Sergey Kolekonovba203982016-12-21 18:32:17 +0400276 }
Jakub Josefecf8b452017-04-20 13:34:29 +0200277 sh "git remote rm target"
Ivan Berezovskiycf269442019-07-18 16:15:26 +0400278 if (!sshCreds) {
279 sh "set +x; rm -f ${targetAskPass}"
280 sh "git config --global --unset credential.${targetUrl}.username"
281 }
Sergey Kolekonovba203982016-12-21 18:32:17 +0400282}
Martin Polreich765f7ba2019-03-12 16:39:25 +0100283
284
285/**
286 * Return all branches for the defined git repository that match the matcher.
287 *
288 * @param repoUrl URL of git repository
289 * @param branchMatcher matcher to filter out the branches (If '' or '*', returns all branches without filtering)
290 * @return branchesList list of branches
291 */
292
293def getBranchesForGitRepo(repoUrl, branchMatcher = ''){
294
295 if (branchMatcher.equals("*")) {
296 branchMatcher = ''
297 }
298 branchesList = sh (
299 script: "git ls-remote --heads ${repoUrl} | cut -f2 | grep -e '${branchMatcher}' | sed 's/refs\\/heads\\///g'",
300 returnStdout: true
301 ).trim()
302 return branchesList.tokenize('\n')
Oleksii Grudeva64e5b22019-06-11 11:21:02 +0300303}
304
Mykyta Karpin82437932019-06-06 14:08:18 +0300305/**
306 * Method for preparing a tag to be SemVer 2 compatible, and can handle next cases:
307 * - length of tag splitted by dots is more than 3
308 * - first part of splitted tag starts not from digit
309 * - length of tag is lower than 3
310 *
311 * @param tag String which contains a git tag from repository
312 * @return HashMap HashMap in the form: ['version': 'x.x.x', 'extra': 'x.x.x'], extra
313 * is added only if size of original tag splitted by dots is more than 3
314 */
315
316def prepareTag(tag){
317 def parts = tag.tokenize('.')
318 def res = [:]
319 // Handle case with tags like v1.1.1
320 parts[0] = parts[0].replaceFirst("[^\\d.]", '')
321 // handle different sizes of tags - 1.1.1.1 or 1.1.1.1rc1
322 if (parts.size() > 3){
323 res['extra'] = parts[3..-1].join('.')
324 } else if (parts.size() < 3){
325 (parts.size()..2).each {
326 parts[it] = '0'
327 }
328 }
329 res['version'] = "${parts[0]}.${parts[1]}.${parts[2]}"
330 return res
331}
332
333/**
334 * Method for incrementing SemVer 2 compatible version
335 *
336 * @param version String which contains main part of SemVer2 version - '2.1.0'
337 * @return string String conaining version with Patch part of version incremented by 1
338 */
339
340def incrementVersion(version){
341 def parts = checkVersion(version)
342 return "${parts[0]}.${parts[1]}.${parts[2].toInteger() + 1}"
343}
344
345/**
346 * Method for checking whether version is compatible with Sem Ver 2
347 *
348 * @param version String which contains main part of SemVer2 version - '2.1.0'
349 * @return list With 3 strings as result of splitting version by dots
350 */
351
352def checkVersion(version) {
353 def parts = version.tokenize('.')
354 if (parts.size() != 3 || !(parts[0] ==~ /^\d+/)) {
355 error "Bad version ${version}"
356 }
357 return parts
358}
359
360/**
361 * Method for constructing SemVer2 compatible version from tag in Git repository:
362 * - if current commit matches the last tag, last tag will be returned as version
363 * - if no tag found assuming no release was done, version will be 0.0.1 with pre release metadata
364 * - if tag found - patch part of version will be incremented and pre-release metadata will be added
365 *
366 *
367 * @param repoDir String which contains path to directory with git repository
368 * @param allowNonSemVer2 Bool whether to allow working with tags which aren't compatible
369 * with Sem Ver 2 (not in form X.Y.Z). if set to true tag will be
370* converted to Sem Ver 2 version e.g tag 1.1.1.1rc1 -> version 1.1.1-1rc1
371 * @return version String
372 */
373def getVersion(repoDir, allowNonSemVer2 = false) {
374 def common = new com.mirantis.mk.Common()
375 dir(repoDir){
376 def cmd = common.shCmdStatus('git describe --tags --first-parent --abbrev=0')
377 def tag_data = [:]
378 def last_tag = cmd['stdout'].trim()
379 def commits_since_tag
380 if (cmd['status'] != 0){
381 if (cmd['stderr'].contains('fatal: No names found, cannot describe anything')){
382 common.warningMsg('No parent tag found, using initial version 0.0.0')
383 tag_data['version'] = '0.0.0'
384 commits_since_tag = sh(script: 'git rev-list --count HEAD', returnStdout: true).trim()
385 } else {
386 error("Something went wrong, cannot find git information ${cmd['stderr']}")
387 }
388 } else {
389 tag_data['version'] = last_tag
390 commits_since_tag = sh(script: "git rev-list --count ${last_tag}..HEAD", returnStdout: true).trim()
391 }
392 try {
393 checkVersion(tag_data['version'])
394 } catch (Exception e) {
395 if (allowNonSemVer2){
396 common.errorMsg(
397 """Git tag isn't compatible with SemVer2, but allowNonSemVer2 is set.
398 Trying to convert git tag to Sem Ver 2 compatible version
399 ${e.message}""")
400 tag_data = prepareTag(tag_data['version'])
401 } else {
402 error("Git tag isn't compatible with SemVer2\n${e.message}")
403 }
404 }
405 // If current commit is exact match to the first parent tag than return it
406 def pre_release_meta = []
407 if (tag_data.get('extra')){
408 pre_release_meta.add(tag_data['extra'])
409 }
410 if (common.shCmdStatus('git describe --tags --first-parent --exact-match')['status'] == 0){
411 if (pre_release_meta){
412 return "${tag_data['version']}-${pre_release_meta[0]}"
413 } else {
414 return tag_data['version']
415 }
416 }
417 // If we away from last tag for some number of commits - add additional metadata and increment version
418 pre_release_meta.add(commits_since_tag)
419 def next_version = incrementVersion(tag_data['version'])
420 def commit_sha = sh(script: 'git rev-parse --short=7 HEAD', returnStdout: true).trim()
421 return "${next_version}-${pre_release_meta.join('.')}-${commit_sha}"
422 }
423}
Mykyta Karpinf5b6c162019-08-08 14:28:15 +0300424
425
426/**
427 * Method for uploading a change request
428 *
429 * @param repo String which contains path to directory with git repository
430 * @param credentialsId Credentials id to use for accessing target repositories
431 * @param commit Id of commit which should be uploaded
432 * @param branch Name of the branch for uploading
433 * @param topic Topic of the change
434 *
435 */
436def pushForReview(repo, credentialsId, commit, branch, topic='', remote='origin') {
437 def common = new com.mirantis.mk.Common()
438 def ssh = new com.mirantis.mk.Ssh()
439 common.infoMsg("Uploading commit ${commit} to ${branch} for review...")
440
441 def pushArg = "${commit}:refs/for/${branch}"
442 def process = [:]
443 if (topic){
444 pushArg += '%topic=' + topic
445 }
446 dir(repo){
447 ssh.prepareSshAgentKey(credentialsId)
448 ssh.runSshAgentCommand("git push ${remote} ${pushArg}")
449 }
450}
451
452/**
453 * Generates a commit message with predefined or auto generate change id. If change
454 * id isn't provided, changeIdSeed and current sha of git head will be used in
455 * generation of commit change id.
456 *
457 * @param repo String which contains path to directory with git repository
458 * @param message Commit message main part
459 * @param changeId User defined change-id usually sha1 hash
460 * @param changeIdSeed Custom part of change id which can be added during change id generation
461 *
462 *
463 * @return commitMessage Multiline String with generated commit message
464 */
465def genCommitMessage(repo, message, changeId = '', changeIdSeed = ''){
466 def git = new com.mirantis.mk.Git()
467 def common = new com.mirantis.mk.Common()
468 def commitMessage
469 def id = changeId
470 def seed = changeIdSeed
471 if (!id) {
472 if (!seed){
473 seed = common.generateRandomHashString(32)
474 }
475 def head_sha
476 dir(repo){
477 head_sha = git.getGitCommit()
478 }
479 id = 'I' + sh(script: 'echo -n ' + seed + head_sha + ' | sha1sum | awk \'{print $1}\'', returnStdout: true)
480 }
481 commitMessage =
482 """${message}
483
484 |Change-Id: ${id}
485 """.stripMargin()
486
487 return commitMessage
488}
Alexandr Lovtsov4fdafd92019-09-09 17:52:16 +0200489
490/**
491 * Update (or create if cannot find) gerrit change request
492 *
493 * @param params Map of parameters to customize commit
494 * - gerritAuth A map containing information about Gerrit. Should include HOST, PORT and USER
495 * - credentialsId Jenkins credentials id for gerrit
496 * - repo Local directory with repository
497 * - comment Commit comment
498 * - change_id_seed Custom part of change id which can be added during change id generation
499 * - branch Name of the branch for uploading
500 * - topic Topic of the change
501 * - project Gerrit project to search in for gerrit change request
502 * - status Change request's status to search for
503 * - changeAuthorEmail Author's email of the change
504 * - changeAuthorName Author's name of the change
505 */
506def updateChangeRequest(Map params) {
507 def gerrit = new com.mirantis.mk.Gerrit()
508
509 def commitMessage
510 def auth = params['gerritAuth']
511 def creds = params['credentialsId']
512 def repo = params['repo']
513 def comment = params['comment']
514 def change_id_seed = params.get('change_id_seed', JOB_NAME)
515 def branch = params['branch']
516 def topic = params['topic']
517 def project = params['project']
518 def status = params.get('status', 'open')
519 def changeAuthorEmail = params['changeAuthorEmail']
520 def changeAuthorName = params['changeAuthorName']
521
522 def changeParams = ['owner': auth['USER'], 'status': status, 'project': project, 'branch': branch, 'topic': topic]
523 def gerritChange = gerrit.findGerritChange(creds, auth, changeParams)
524 def changeId
525 def commit
526 if (gerritChange) {
527 def jsonChange = readJSON text: gerritChange
528 changeId = jsonChange['id']
529 }
530 commitMessage = genCommitMessage(repo, comment, changeId, change_id_seed)
531 commitGitChanges(repo, commitMessage, changeAuthorEmail, changeAuthorName, false, false)
532 dir(repo){
533 commit = getGitCommit()
534 }
535 pushForReview(repo, creds, commit, branch, topic)
536}