diff --git a/src/main/java/jenkins/plugins/git/GitSCMFileSystem.java b/src/main/java/jenkins/plugins/git/GitSCMFileSystem.java index d419b6e6b1..f9535e372b 100644 --- a/src/main/java/jenkins/plugins/git/GitSCMFileSystem.java +++ b/src/main/java/jenkins/plugins/git/GitSCMFileSystem.java @@ -35,6 +35,7 @@ import hudson.EnvVars; import hudson.Extension; import hudson.model.Item; +import hudson.model.Run; import hudson.model.TaskListener; import hudson.plugins.git.BranchSpec; import hudson.plugins.git.GitException; @@ -284,9 +285,54 @@ public boolean supportsDescriptor(SCMSourceDescriptor descriptor) { return AbstractGitSCMSource.class.isAssignableFrom(descriptor.clazz); } + static class HeadNameResult { + final String headName; + final String prefix; + + private HeadNameResult(String headName, String prefix) { + this.headName = headName; + this.prefix = prefix; + } + + static HeadNameResult calculate(@NonNull BranchSpec branchSpec, + @CheckForNull SCMRevision rev, + @CheckForNull EnvVars env) { + String branchSpecExpandedName = branchSpec.getName(); + if (env != null) { + branchSpecExpandedName = env.expand(branchSpecExpandedName); + } + + String prefix = Constants.R_HEADS; + if (branchSpecExpandedName.startsWith(Constants.R_TAGS)) { + prefix = Constants.R_TAGS; + } + + String headName; + if (rev != null) { + headName = env.expand(rev.getHead().getName()); + } else { + if (branchSpecExpandedName.startsWith(prefix)) { + headName = branchSpecExpandedName.substring(prefix.length()); + } else if (branchSpecExpandedName.startsWith("*/")) { + headName = branchSpecExpandedName.substring(2); + } else { + headName = branchSpecExpandedName; + } + } + return new HeadNameResult(headName, prefix); + } + } + @Override public SCMFileSystem build(@NonNull Item owner, @NonNull SCM scm, @CheckForNull SCMRevision rev) throws IOException, InterruptedException { + return build(owner, scm, rev, null); + } + + @Override + public SCMFileSystem build(@NonNull Item owner, @NonNull SCM scm, @CheckForNull SCMRevision rev, + @CheckForNull Run _build) + throws IOException, InterruptedException { if (rev != null && !(rev instanceof AbstractGitSCMSource.SCMRevisionImpl)) { return null; } @@ -302,6 +348,12 @@ public SCMFileSystem build(@NonNull Item owner, @NonNull SCM scm, @CheckForNull listener.getLogger().println("Git remote url is null"); return null; } + + EnvVars env = null; + if (_build != null) { + env = _build.getEnvironment(listener); + } + String cacheEntry = AbstractGitSCMSource.getCacheEntry(remote); Lock cacheLock = AbstractGitSCMSource.getCacheLock(cacheEntry); cacheLock.lock(); @@ -346,27 +398,15 @@ public SCMFileSystem build(@NonNull Item owner, @NonNull SCM scm, @CheckForNull } catch (URISyntaxException ex) { listener.getLogger().println("URI syntax exception for '" + remoteName + "' " + ex); } - String prefix = Constants.R_HEADS; - if(branchSpec.getName().startsWith(Constants.R_TAGS)){ - prefix = Constants.R_TAGS; - } - String headName; - if (rev != null) { - headName = rev.getHead().getName(); - } else { - if (branchSpec.getName().startsWith(prefix)){ - headName = branchSpec.getName().substring(prefix.length()); - } else if (branchSpec.getName().startsWith("*/")) { - headName = branchSpec.getName().substring(2); - } else { - headName = branchSpec.getName(); - } - } + + HeadNameResult headNameResult = HeadNameResult.calculate(branchSpec, rev, env); + client.fetch_().prune(true).from(remoteURI, Collections.singletonList(new RefSpec( - "+" + prefix + headName + ":" + Constants.R_REMOTES + remoteName + "/" - + headName))).execute(); + "+" + headNameResult.prefix + headNameResult.headName + ":" + Constants.R_REMOTES + remoteName + "/" + + headNameResult.headName))).execute(); + listener.getLogger().println("Done."); - return new GitSCMFileSystem(client, remote, Constants.R_REMOTES + remoteName + "/" +headName, (AbstractGitSCMSource.SCMRevisionImpl) rev); + return new GitSCMFileSystem(client, remote, Constants.R_REMOTES + remoteName + "/" + headNameResult.headName, (AbstractGitSCMSource.SCMRevisionImpl) rev); } finally { cacheLock.unlock(); } diff --git a/src/test/java/jenkins/plugins/git/GitSCMFileSystemTest.java b/src/test/java/jenkins/plugins/git/GitSCMFileSystemTest.java index 9575124853..59b2bf2875 100644 --- a/src/test/java/jenkins/plugins/git/GitSCMFileSystemTest.java +++ b/src/test/java/jenkins/plugins/git/GitSCMFileSystemTest.java @@ -42,6 +42,8 @@ import jenkins.scm.api.SCMRevision; import jenkins.scm.api.SCMSource; import jenkins.scm.api.SCMSourceDescriptor; + +import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.jenkinsci.plugins.gitclient.Git; import org.jenkinsci.plugins.gitclient.GitClient; @@ -426,6 +428,40 @@ public void filesystem_supports_descriptor() throws Exception { assertTrue(SCMFileSystem.supports(descriptor)); } + @Issue("JENKINS-42971") + @Test + public void calculate_head_name_with_env() throws Exception { + GitSCMFileSystem.BuilderImpl.HeadNameResult result1 = GitSCMFileSystem.BuilderImpl.HeadNameResult.calculate(new BranchSpec("${BRANCH}"), null, + new EnvVars("BRANCH", "master-a")); + assertEquals("master-a", result1.headName); + assertEquals(Constants.R_HEADS, result1.prefix); + + GitSCMFileSystem.BuilderImpl.HeadNameResult result2 = GitSCMFileSystem.BuilderImpl.HeadNameResult.calculate(new BranchSpec("${BRANCH}"), null, + new EnvVars("BRANCH", "refs/heads/master-b")); + assertEquals("master-b", result2.headName); + assertEquals(Constants.R_HEADS, result2.prefix); + + GitSCMFileSystem.BuilderImpl.HeadNameResult result3 = GitSCMFileSystem.BuilderImpl.HeadNameResult.calculate(new BranchSpec("refs/heads/${BRANCH}"), null, + new EnvVars("BRANCH", "master-c")); + assertEquals("master-c", result3.headName); + assertEquals(Constants.R_HEADS, result3.prefix); + + GitSCMFileSystem.BuilderImpl.HeadNameResult result4 = GitSCMFileSystem.BuilderImpl.HeadNameResult.calculate(new BranchSpec("${BRANCH}"), null, + null); + assertEquals("${BRANCH}", result4.headName); + assertEquals(Constants.R_HEADS, result4.prefix); + + GitSCMFileSystem.BuilderImpl.HeadNameResult result5 = GitSCMFileSystem.BuilderImpl.HeadNameResult.calculate(new BranchSpec("*/${BRANCH}"), null, + new EnvVars("BRANCH", "master-d")); + assertEquals("master-d", result5.headName); + assertEquals(Constants.R_HEADS, result5.prefix); + + GitSCMFileSystem.BuilderImpl.HeadNameResult result6 = GitSCMFileSystem.BuilderImpl.HeadNameResult.calculate(new BranchSpec("*/master-e"), null, + new EnvVars("BRANCH", "dummy")); + assertEquals("master-e", result6.headName); + assertEquals(Constants.R_HEADS, result6.prefix); + } + /** inline ${@link hudson.Functions#isWindows()} to prevent a transient remote classloader issue */ private boolean isWindows() { return java.io.File.pathSeparatorChar==';';