Skip to content

Commit 5f0b6dc

Browse files
committed
LibraryConfiguration: defaultedVersion(): check for BRANCH_NAME first; and then it is safer to check getSCMs() not for WorkflowRun, but for the FlowDefinition from WorkflowJob [JENKINS-69731]
1 parent 768f251 commit 5f0b6dc

File tree

1 file changed

+109
-59
lines changed

1 file changed

+109
-59
lines changed

src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryConfiguration.java

Lines changed: 109 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import hudson.scm.SCM;
3939
import hudson.util.FormValidation;
4040
import jenkins.model.Jenkins;
41+
import org.jenkinsci.plugins.workflow.flow.FlowDefinition;
42+
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
4143
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
4244
import org.kohsuke.accmod.Restricted;
4345
import org.kohsuke.accmod.restrictions.NoExternalUse;
@@ -196,66 +198,126 @@ public LibraryCachingConfiguration getCachingConfiguration() {
196198

197199
// without a runParent we can't validateVersion() anyway
198200
if (runParent != null) {
199-
// First ask SCM source of the pipeline (if any),
200-
// as the most authoritative source of the branch
201-
// name we want:
201+
// First, check if envvar BRANCH_NAME is defined?
202+
// Trust the plugins and situations where it is set.
202203
try {
203-
if (run instanceof WorkflowRun) {
204+
runVersion = run.getEnvironment(listener).get("BRANCH_NAME", null);
205+
} catch (Exception x) {
206+
// no-op, keep null
207+
}
208+
209+
if (runVersion == null) {
210+
// Probably not in a multibranch pipeline workflow
211+
// type of job?
212+
// Ask for SCM source of the pipeline (if any),
213+
// as the most authoritative source of the branch
214+
// name we want:
215+
SCM scm0 = null;
216+
217+
if (runParent instanceof WorkflowJob) {
218+
// This covers both "Multibranch Pipeline"
219+
// and "Pipeline script from SCM" jobs;
220+
// it also covers "inline" pipeline scripts
221+
// but should return an empty Collection of
222+
// SCMs since there is no SCM attached to
223+
// the "static source".
224+
// TODO: If there are "pre-loaded libraries"
225+
// in a Jenkins deployment, can they interfere?
226+
FlowDefinition fd = ((WorkflowJob)runParent).getDefinition();
227+
if (fd != null) {
228+
for (SCM scmN : fd.getSCMs()) {
229+
if ("hudson.plugins.git.GitSCM".equals(scmN.getClass().getName())) {
230+
// The best we can do here is accept
231+
// the first seen SCM (with branch
232+
// support which we know how to query).
233+
scm0 = scmN;
234+
break;
235+
}
236+
}
237+
}
238+
}
239+
240+
/*
241+
// NOTE: the list of SCMs used by the run does not
242+
// seem trustworthy: if an "inline" pipeline script
243+
// (not from SCM) is used, there is no "relevant"
244+
// branch name to request; however the list of SCMs
245+
// would be populated as @Library lines are processed
246+
// and some SCM sources get checked out.
247+
if (scm0 == null && run instanceof WorkflowRun) {
204248
// This covers both "Multibranch Pipeline"
205249
// and "Pipeline script from SCM" jobs;
206250
// it also covers "inline" pipeline scripts
207251
// but throws a hudson.AbortException since
208252
// there is no SCM attached.
209-
WorkflowRun wfRun = (WorkflowRun) run;
210-
SCM scm0 = wfRun.getSCMs().get(0);
211-
if (scm0 != null) {
212-
// Avoid importing GitSCM and so requiring that
213-
// it is always installed even if not used by
214-
// particular Jenkins deployment (using e.g.
215-
// SVN, Gerritt, etc.). Our aim is to query this:
216-
// runVersion = scm0.getBranches().first().getExpandedName(run.getEnvironment(listener));
217-
// https://mkyong.com/java/how-to-use-reflection-to-call-java-method-at-runtime/
218-
Class noparams[] = {};
219-
Class[] paramEnvVars = new Class[1];
220-
paramEnvVars[0] = EnvVars.class;
221-
if ("hudson.plugins.git.GitSCM".equals(scm0.getClass().getName())) {
222-
// https://javadoc.jenkins.io/plugin/git/hudson/plugins/git/GitSCM.html#getBranches() =>
223-
// https://javadoc.jenkins.io/plugin/git/hudson/plugins/git/BranchSpec.html#toString()
224-
Method methodGetBranches = null;
253+
try {
254+
WorkflowRun wfRun = (WorkflowRun) run;
255+
scm0 = wfRun.getSCMs().get(0);
256+
} catch (Exception x) {
257+
// no-op, keep null
258+
}
259+
}
260+
*/
261+
262+
if (scm0 != null) {
263+
// Avoid importing GitSCM and so requiring that
264+
// it is always installed even if not used by
265+
// particular Jenkins deployment (using e.g.
266+
// SVN, Gerritt, etc.). Our aim is to query this:
267+
// runVersion = scm0.getBranches().first().getExpandedName(run.getEnvironment(listener));
268+
// https://mkyong.com/java/how-to-use-reflection-to-call-java-method-at-runtime/
269+
Class noparams[] = {};
270+
Class[] paramEnvVars = new Class[1];
271+
paramEnvVars[0] = EnvVars.class;
272+
if ("hudson.plugins.git.GitSCM".equals(scm0.getClass().getName())) {
273+
// https://javadoc.jenkins.io/plugin/git/hudson/plugins/git/GitSCM.html#getBranches() =>
274+
// https://javadoc.jenkins.io/plugin/git/hudson/plugins/git/BranchSpec.html#toString()
275+
Method methodGetBranches = null;
276+
try {
277+
methodGetBranches = scm0.getClass().getDeclaredMethod("getBranches", noparams);
278+
} catch (Exception x) {
279+
// NoSuchMethodException | SecurityException | NullPointerException
280+
methodGetBranches = null;
281+
}
282+
if (methodGetBranches != null) {
283+
Object branchList = null;
225284
try {
226-
methodGetBranches = scm0.getClass().getDeclaredMethod("getBranches", noparams);
285+
branchList = methodGetBranches.invoke(scm0);
227286
} catch (Exception x) {
228-
// NoSuchMethodException | SecurityException | NullPointerException
229-
methodGetBranches = null;
287+
// InvocationTargetException | IllegalAccessException
288+
branchList = null;
230289
}
231-
if (methodGetBranches != null) {
232-
Object branchList = methodGetBranches.invoke(scm0);
233-
if (branchList instanceof List) {
234-
Object branch0 = ((List<Object>) branchList).get(0);
235-
if ("hudson.plugins.git.BranchSpec".equals(branch0.getClass().getName())) {
236-
Method methodGetExpandedName = null;
290+
if (branchList != null && branchList instanceof List) {
291+
Object branch0 = ((List<Object>) branchList).get(0);
292+
if ("hudson.plugins.git.BranchSpec".equals(branch0.getClass().getName())) {
293+
Method methodGetExpandedName = null;
294+
try {
295+
methodGetExpandedName = branch0.getClass().getDeclaredMethod("getExpandedName", paramEnvVars);
296+
} catch (Exception x) {
297+
methodGetExpandedName = null;
298+
}
299+
if (methodGetExpandedName != null) {
300+
// Handle possible shell-templated branch specs:
301+
Object expandedBranchName = null;
237302
try {
238-
methodGetExpandedName = branch0.getClass().getDeclaredMethod("getExpandedName", paramEnvVars);
303+
expandedBranchName = methodGetExpandedName.invoke(branch0, run.getEnvironment(listener));
239304
} catch (Exception x) {
240-
methodGetExpandedName = null;
305+
// IllegalAccessException | IOException
306+
expandedBranchName = null;
241307
}
242-
if (methodGetExpandedName != null) {
243-
// Handle possible shell-templated branch specs:
244-
Object expandedBranchName = methodGetExpandedName.invoke(branch0, run.getEnvironment(listener));
245-
if (expandedBranchName != null) {
246-
runVersion = expandedBranchName.toString();
247-
}
308+
if (expandedBranchName != null) {
309+
runVersion = expandedBranchName.toString();
248310
}
249-
if (runVersion == null || "".equals(runVersion)) {
250-
runVersion = branch0.toString();
251-
}
252-
} // else unknown class, make no blind guesses
253-
}
254-
} // else not really the GitSCM we know?
255-
} // else SVN, Gerritt or some other SCM -
256-
// add handling when needed and known how
257-
// or rely on BRANCH_NAME (if set) below...
258-
}
311+
}
312+
if (runVersion == null || "".equals(runVersion)) {
313+
runVersion = branch0.toString();
314+
}
315+
} // else unknown class, make no blind guesses
316+
}
317+
} // else not really the GitSCM we know?
318+
} // else SVN, Gerritt or some other SCM -
319+
// add handling when needed and known how
320+
// or rely on BRANCH_NAME (if set) below...
259321

260322
// Still alive? Chop off leading '*/'
261323
// (if any) from single-branch MBP and
@@ -264,18 +326,6 @@ public LibraryCachingConfiguration getCachingConfiguration() {
264326
runVersion = runVersion.replaceFirst("^\\*/", "");
265327
}
266328
}
267-
} catch (Exception x) {
268-
// no-op, keep null
269-
}
270-
271-
if (runVersion == null) {
272-
// Probably not in a multibranch pipeline workflow
273-
// type of job? Is envvar BRANCH_NAME defined?
274-
try {
275-
runVersion = run.getEnvironment(listener).get("BRANCH_NAME", null);
276-
} catch (Exception x) {
277-
// no-op, keep null
278-
}
279329
}
280330

281331
// Note: if runVersion remains null (unresolved -

0 commit comments

Comments
 (0)