blob: 529203374810e6d2d73591c7206e750975d1dea0 [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)
Sergey Kolekonovba203982016-12-21 18:32:17 +040018 */
Jakub Josef7dccebe2017-03-06 18:08:32 +010019def checkoutGitRepository(path, url, branch, credentialsId = null, poll = true, timeout = 10){
20 checkout(
21 changelog:true,
22 poll: poll,
23 scm: [
24 $class: 'GitSCM',
25 branches: [[name: "*/${branch}"]],
Sergey Kolekonovba203982016-12-21 18:32:17 +040026 doGenerateSubmoduleConfigurations: false,
Jakub Josef7dccebe2017-03-06 18:08:32 +010027 extensions: [
28 [$class: 'RelativeTargetDirectory', relativeTargetDir: path],
29 [$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false, timeout: timeout]],
Sergey Kolekonovba203982016-12-21 18:32:17 +040030 submoduleCfg: [],
Jakub Josef7dccebe2017-03-06 18:08:32 +010031 userRemoteConfigs: [[url: url, credentialsId: credentialsId]]]
32 )
Sergey Kolekonovba203982016-12-21 18:32:17 +040033 dir(path) {
34 sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
35 }
36}
37
38/**
39 * Parse HEAD of current directory and return commit hash
40 */
41def getGitCommit() {
42 git_commit = sh (
43 script: 'git rev-parse HEAD',
44 returnStdout: true
45 ).trim()
46 return git_commit
47}
48
49/**
Filip Pytloun49d66302017-03-06 10:26:22 +010050 * Get remote URL
51 *
Filip Pytloun3e4a1c92017-03-06 11:36:51 +010052 * @param name Name of remote (default any)
Filip Pytloun49d66302017-03-06 10:26:22 +010053 * @param type Type (fetch or push, default fetch)
54 */
Filip Pytloun3e4a1c92017-03-06 11:36:51 +010055def getGitRemote(name = '', type = 'fetch') {
Filip Pytloun49d66302017-03-06 10:26:22 +010056 gitRemote = sh (
Filip Pytloun3e4a1c92017-03-06 11:36:51 +010057 script: "git remote -v | grep '${name}' | grep ${type} | awk '{print \$2}' | head -1",
Filip Pytloun49d66302017-03-06 10:26:22 +010058 returnStdout: true
59 ).trim()
60 return gitRemote
61}
62
63/**
Ales Komarekfb7cbcb2017-02-24 14:02:03 +010064 * Change actual working branch of repo
65 *
66 * @param path Path to the git repository
67 * @param branch Branch desired to switch to
68 */
69def changeGitBranch(path, branch) {
70 dir(path) {
71 git_cmd = sh (
72 script: "git checkout -b ${branch}",
73 returnStdout: true
74 ).trim()
75 }
76 return git_cmd
77}
78
79/**
80 * Commit changes to the git repo
81 *
82 * @param path Path to the git repository
83 * @param message A commit message
84 */
85def commitGitChanges(path, message) {
86 dir(path) {
87 sh(
88 script: 'git add -A',
89 returnStdout: true
90 ).trim()
91 git_cmd = sh(
92 script: "git commit -m '${message}'",
93 returnStdout: true
94 ).trim()
95 }
96 return git_cmd
97}
98
99
100/**
101 * Push git changes to remote repo
102 *
103 * @param path Path to the git repository
104 * @param branch Branch on the remote git repository
105 * @param remote Name of the remote repository
106 */
107def pushGitChanges(path, branch = 'master', remote = 'origin') {
108 dir(path) {
109 git_cmd = sh(
110 script: "git push ${remote} ${branch}",
111 returnStdout: true
112 ).trim()
113 }
114 return git_cmd
115}
116
117
118/**
Sergey Kolekonovba203982016-12-21 18:32:17 +0400119 * Checkout git repositories in parallel
120 *
121 * @param path Directory to checkout to
122 * @param url Git repository url
123 * @param branch Git repository branch
124 * @param credentialsId Credentials ID to use
125 * @param poll Poll automatically
126 * @param clean Clean status
127 */
128def checkoutGitParallel(path, url, branch, credentialsId = null, poll = true, clean = true) {
129 return {
130 print "Checking out ${url}, branch ${branch} into ${path}"
131 dir(path) {
132 git url: url,
133 branch: branch,
134 credentialsId: credentialsId,
135 poll: poll,
136 clean: clean
137 }
138 }
139}
140
141/**
Filip Pytloun49d66302017-03-06 10:26:22 +0100142 * Mirror git repository, merge target changes (downstream) on top of source
143 * (upstream) and push target or both if pushSource is true
144 *
145 * @param sourceUrl Source git repository
146 * @param targetUrl Target git repository
147 * @param credentialsId Credentials id to use for accessing source/target
148 * repositories
149 * @param branches List or comma-separated string of branches to sync
150 * @param followTags Mirror tags
151 * @param pushSource Push back into source branch, resulting in 2-way sync
152 * @param pushSourceTags Push target tags into source or skip pushing tags
153 * @param gitEmail Email for creation of merge commits
154 * @param gitName Name for creation of merge commits
Sergey Kolekonovba203982016-12-21 18:32:17 +0400155 */
Filip Pytloun49d66302017-03-06 10:26:22 +0100156def mirrorGit(sourceUrl, targetUrl, credentialsId, branches, followTags = false, pushSource = false, pushSourceTags = false, gitEmail = 'jenkins@localhost', gitName = 'Jenkins') {
Sergey Kolekonovba203982016-12-21 18:32:17 +0400157 if (branches instanceof String) {
158 branches = branches.tokenize(',')
159 }
Sergey Kolekonovba203982016-12-21 18:32:17 +0400160
Filip Pytloun49d66302017-03-06 10:26:22 +0100161 def ssh = new com.mirantis.mk.Ssh()
162 ssh.prepareSshAgentKey(credentialsId)
163 ssh.ensureKnownHosts(targetUrl)
164 sh "git config user.email '${gitEmail}'"
165 sh "git config user.name '${gitName}'"
166
167 sh "git remote | grep target || git remote add target ${TARGET_URL}"
168 ssh.agentSh "git remote update --prune"
169
Sergey Kolekonovba203982016-12-21 18:32:17 +0400170 for (i=0; i < branches.size; i++) {
171 branch = branches[i]
172 sh "git branch | grep ${branch} || git checkout -b ${branch} origin/${branch}"
173 sh "git branch | grep ${branch} && git checkout ${branch} && git reset --hard origin/${branch}"
174
Sergey Kolekonovba203982016-12-21 18:32:17 +0400175 sh "git ls-tree target/${branch} && git merge --no-edit --ff target/${branch} || echo 'Target repository is empty, skipping merge'"
176 followTagsArg = followTags ? "--follow-tags" : ""
Filip Pytloun49d66302017-03-06 10:26:22 +0100177 ssh.agentSh "git push ${followTagsArg} target HEAD:${branch}"
178
179 if (pushSource == true) {
180 followTagsArg = followTags && pushSourceTags ? "--follow-tags" : ""
Filip Pytlounb36387e2017-03-06 11:39:19 +0100181 ssh.agentSh "git push ${followTagsArg} origin HEAD:${branch}"
Filip Pytloun49d66302017-03-06 10:26:22 +0100182 }
183 }
184
185 if (followTags == true) {
186 ssh.agentSh "git push target --tags"
187
188 if (pushSourceTags == true) {
189 ssh.agentSh "git push origin --tags"
190 }
Sergey Kolekonovba203982016-12-21 18:32:17 +0400191 }
192}