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