This repository has been archived by the owner on Sep 25, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 102
/
Copy pathcheckoutScm.groovy
217 lines (191 loc) · 7.95 KB
/
checkoutScm.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/*-
* #%L
* wcm.io
* %%
* Copyright (C) 2017 wcm.io DevOps
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import hudson.plugins.git.UserRemoteConfig
import hudson.tasks.UserAvatarResolver
import io.wcm.devops.jenkins.pipeline.credentials.Credential
import io.wcm.devops.jenkins.pipeline.credentials.CredentialConstants
import io.wcm.devops.jenkins.pipeline.credentials.CredentialParser
import io.wcm.devops.jenkins.pipeline.environment.EnvironmentConstants
import io.wcm.devops.jenkins.pipeline.environment.EnvironmentUtils
import io.wcm.devops.jenkins.pipeline.utils.ConfigConstants
import io.wcm.devops.jenkins.pipeline.utils.PatternMatcher
import io.wcm.devops.jenkins.pipeline.utils.TypeUtils
import io.wcm.devops.jenkins.pipeline.utils.logging.Logger
import io.wcm.devops.jenkins.pipeline.utils.resources.JsonLibraryResource
import net.sf.json.JSON
import org.jenkinsci.plugins.workflow.cps.DSL
/**
* Step which takes care about checking out source code from git. Other SCMs are currently not supported.
*
* Variant 1: When scm variable is present and config scm.useScmVar is set to true the configured SCM from the job
* itself is used to checkout.
*
* Variant 2: When config scm.useScmVar is not set to true the value from config scm.url is used for checkout. In this
* mode the step tries to auto lookup the Jenkins credentials from resources/credentials/scm/credentials.json based on
* the url to checkout.
*
* See <a href="vars/checkoutScm.md">checkoutScm.md</a> for detailed documentation
*
* Defaults:
* branches: master and develop
* extensions: LocalBranch
*
* @param config configuration object
* @return The SCM Checkout result
*/
def call(Map config) {
Logger log = new Logger(this)
// retrieve the configuration
Map scmCfg = (Map) config[ConfigConstants.SCM] ?: [:]
Boolean useScmVar = scmCfg[ConfigConstants.SCM_USE_SCM_VAR] ? scmCfg[ConfigConstants.SCM_USE_SCM_VAR] : false
TypeUtils typeUtils = new TypeUtils()
EnvironmentUtils envUtils = new EnvironmentUtils(this)
Map scmCheckoutResult = null
if (useScmVar && scm) {
// checkout by using provided scm, used when Jenkinsfile is in the project repository
log.info("Found configuration to use existing scm var, checking out with scm configuration from job")
scmCheckoutResult = checkoutWithScmVar()
} else {
// checkout by using the provided scm configuration, used when Jenkinsfile is not in the project repository
log.info("Checking out with provided configuration")
scmCheckoutResult = checkoutWithConfiguration(scmCfg, log)
}
// set checkout result into env vars (but only when they are not already present
if (typeUtils.isMap(scmCheckoutResult)) {
scmCheckoutResult.each {
key, value ->
log.debug("key: $key", "value: $value")
envUtils.setEnvWhenEmpty(key, value)
}
}
// initially detect the git branch based on the current checkout
gitTools.getBranch()
// set the scm url to environment variable SCM_URL
setScmUrl(config)
return scmCheckoutResult
}
/**
* Runs the checkout by using the provided scm variable
*
* @return result of checkout step
*/
Object checkoutWithScmVar() {
Logger log = new Logger("checkoutScm.checkoutWithScmVar")
List scmBranches = []
try {
scmBranches = scm.getBranches()
}
catch (Exception ex) {
log.warn("The used SCM does not provide the 'getBranches()' method.")
}
String remoteName = "origin";
List userRemoteConfigs = []
try {
userRemoteConfigs = scm.getUserRemoteConfigs()
} catch (Exception ex) {
log.warn("The used SCM does not provide the 'getUserRemoteConfigs()' method.")
}
for (UserRemoteConfig remote in userRemoteConfigs) {
remoteName = remote.getName()
if (remoteName == null || remoteName.isEmpty()) {
remoteName = "origin";
}
}
Map result = checkout scm
String checkoutBranchName = result[EnvironmentConstants.GIT_BRANCH]
// check for a differing branch name. This may occur when the pipeline library is building itself and was checked out before by the folder shared libraries
// and is now checked out for the build
if (result && scmBranches && scmBranches.size() == 1) {
String scmBranchName = scmBranches[0]
log.debug("Branch name from scm object", scmBranchName)
// remove */ prefix
scmBranchName = scmBranchName.replace("*/","")
log.debug("Cleaned branch name", scmBranchName)
scmBranchName = remoteName + "/" + scmBranchName
log.debug("Branchname with origin", scmBranchName)
log.debug("checkoutBranchName", checkoutBranchName)
if (scmBranchName != checkoutBranchName) {
log.debug("branchName from SCM object ('$scmBranchName') does not match checkoutBranchName ('$checkoutBranchName'), apply fix")
result[EnvironmentConstants.GIT_BRANCH] = scmBranchName
}
}
return result
}
/**
* Runs the checkout by using the provided scm configuration
*
* @param scmCfg The configuration used for checkout
* @param log The logger instance
* @return result of checkout step
*/
Object checkoutWithConfiguration(Map scmCfg, Logger log) {
// parse the configuration with defaults
String credentialsId = scmCfg[ConfigConstants.SCM_CREDENTIALS_ID]
String url = scmCfg[ConfigConstants.SCM_URL]
List branches = (List) scmCfg[ConfigConstants.SCM_BRANCHES] ?: [[name: '*/master'], [name: '*/develop']]
List submoduleCfg = (List) scmCfg[ConfigConstants.SCM_SUBMODULE_CONFIG] ?: []
List extensions = (List) scmCfg[ConfigConstants.SCM_EXTENSIONS] ?: [[$class: 'LocalBranch']]
Boolean doGenerateSubmoduleConfigurations = scmCfg[ConfigConstants.SCM_DO_GENERATE_SUBMODULE_CONFIGURATION] != null ? scmCfg[ConfigConstants.SCM_DO_GENERATE_SUBMODULE_CONFIGURATION] : false
Map userRemoteConfig = (Map) scmCfg[ConfigConstants.SCM_USER_REMOTE_CONFIG] ?: [:]
List userRemoteConfigs = (List) scmCfg[ConfigConstants.SCM_USER_REMOTE_CONFIGS] ?: []
log.debug("url: ", url)
log.debug("branches: ", branches)
if (userRemoteConfigs.size() > 0) {
// use userRemoteConfigs when provided
log.info("userRemoteConfigs found in provided configuration, do not auto credential lookup", userRemoteConfigs)
} else if (userRemoteConfig.size() > 0) {
// use userRemoteConfig when provided
userRemoteConfigs.push(userRemoteConfig)
} else {
// since url is necessary for this part fail when not present
if (url == null) {
log.fatal("No scm url provided, aborting")
error("$this: No scm url provided, aborting")
}
// do credential auto lookup
if (credentialsId == null) {
log.debug("no credentials id passed, try auto lookup")
Credential credential = credentials.lookupScmCredential(url)
if (credential != null) {
credentialsId = credential.getId()
}
}
// add the url to the userRemoteConfigs
userRemoteConfig.put("url", url)
// only add credentials when provided/found
if (credentialsId != null) {
userRemoteConfig.put("credentialsId", credentialsId)
}
// prepare the userRemoteConfigs object
log.info("checkoutScm from $url, with credentials: $credentialsId")
userRemoteConfigs.add(userRemoteConfig)
}
// call the checkout step
return checkout(
[
$class : 'GitSCM',
branches : branches,
doGenerateSubmoduleConfigurations: doGenerateSubmoduleConfigurations,
extensions : extensions,
submoduleCfg : submoduleCfg,
userRemoteConfigs : userRemoteConfigs
]
)
}