3838import hudson .scm .SCM ;
3939import hudson .util .FormValidation ;
4040import jenkins .model .Jenkins ;
41+ import org .jenkinsci .plugins .workflow .flow .FlowDefinition ;
42+ import org .jenkinsci .plugins .workflow .job .WorkflowJob ;
4143import org .jenkinsci .plugins .workflow .job .WorkflowRun ;
4244import org .kohsuke .accmod .Restricted ;
4345import 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