Skip to content

Commit 1412970

Browse files
authored
Merge pull request #68 from jglick/SCMSource.owner-JENKINS-43802
[JENKINS-43802] No context available for credentials from SCMSource.retrieve(String, TaskListener)
2 parents b474666 + 8dae8d9 commit 1412970

File tree

6 files changed

+90
-19
lines changed

6 files changed

+90
-19
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
<useBeta>true</useBeta>
7070
<workflow-cps-plugin.version>2.71</workflow-cps-plugin.version>
7171
<git-plugin.version>4.0.0-rc</git-plugin.version>
72-
<scm-api-plugin.version>2.4.0</scm-api-plugin.version>
72+
<scm-api-plugin.version>2.6.3</scm-api-plugin.version>
7373
<workflow-scm-step-plugin.version>2.7</workflow-scm-step-plugin.version>
7474
<workflow-multibranch-plugin.version>2.21</workflow-multibranch-plugin.version>
7575
<workflow-step-api-plugin.version>2.20</workflow-step-api-plugin.version>

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

+5-4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import jenkins.model.Jenkins;
4040
import org.kohsuke.accmod.Restricted;
4141
import org.kohsuke.accmod.restrictions.NoExternalUse;
42+
import org.kohsuke.stapler.AncestorInPath;
4243
import org.kohsuke.stapler.DataBoundConstructor;
4344
import org.kohsuke.stapler.DataBoundSetter;
4445
import org.kohsuke.stapler.QueryParameter;
@@ -159,7 +160,7 @@ public FormValidation doCheckName(@QueryParameter String name) {
159160
return FormValidation.ok();
160161
}
161162

162-
public FormValidation doCheckDefaultVersion(@QueryParameter String defaultVersion, @QueryParameter boolean implicit, @QueryParameter boolean allowVersionOverride, @QueryParameter String name) {
163+
public FormValidation doCheckDefaultVersion(@AncestorInPath Item context, @QueryParameter String defaultVersion, @QueryParameter boolean implicit, @QueryParameter boolean allowVersionOverride, @QueryParameter String name) {
163164
if (defaultVersion.isEmpty()) {
164165
if (implicit) {
165166
return FormValidation.error("If you load a library implicitly, you must specify a default version.");
@@ -172,7 +173,7 @@ public FormValidation doCheckDefaultVersion(@QueryParameter String defaultVersio
172173
for (LibraryResolver resolver : ExtensionList.lookup(LibraryResolver.class)) {
173174
for (LibraryConfiguration config : resolver.fromConfiguration(Stapler.getCurrentRequest())) {
174175
if (config.getName().equals(name)) {
175-
return config.getRetriever().validateVersion(name, defaultVersion);
176+
return config.getRetriever().validateVersion(name, defaultVersion, context);
176177
}
177178
}
178179
}
@@ -181,14 +182,14 @@ public FormValidation doCheckDefaultVersion(@QueryParameter String defaultVersio
181182
}
182183

183184
/* TODO currently impossible; autoCompleteField does not support passing neighboring fields:
184-
public AutoCompletionCandidates doAutoCompleteDefaultVersion(@QueryParameter String defaultVersion, @QueryParameter String name) {
185+
public AutoCompletionCandidates doAutoCompleteDefaultVersion(@AncestorInPath Item context, @QueryParameter String defaultVersion, @QueryParameter String name) {
185186
AutoCompletionCandidates candidates = new AutoCompletionCandidates();
186187
for (LibraryResolver resolver : ExtensionList.lookup(LibraryResolver.class)) {
187188
for LibraryConfiguration config : resolver.fromConfiguration(Stapler.getCurrentRequest()) {
188189
// TODO define LibraryRetriever.completeVersions
189190
if (config.getName().equals(name) && config.getRetriever() instanceof SCMSourceRetriever) {
190191
try {
191-
for (String revision : ((SCMSourceRetriever) config.getRetriever()).getScm().fetchRevisions(null)) {
192+
for (String revision : ((SCMSourceRetriever) config.getRetriever()).getScm().fetchRevisions(null, context)) {
192193
if (revision.startsWith(defaultVersion)) {
193194
candidates.add(revision);
194195
}

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

+15-2
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,13 @@
2727
import hudson.AbortException;
2828
import hudson.ExtensionPoint;
2929
import hudson.FilePath;
30+
import hudson.Util;
3031
import hudson.model.AbstractDescribableImpl;
32+
import hudson.model.Item;
3133
import hudson.model.Run;
3234
import hudson.model.TaskListener;
3335
import hudson.util.FormValidation;
36+
import javax.annotation.CheckForNull;
3437
import javax.annotation.Nonnull;
3538

3639
/**
@@ -59,16 +62,26 @@ public abstract class LibraryRetriever extends AbstractDescribableImpl<LibraryRe
5962
* @param listener a way to report progress
6063
* @throws Exception if there is any problem (use {@link AbortException} for user errors)
6164
*/
65+
// TODO this should have been made nonabstract and deprecated and delegated to the new version; may be able to use access-modifier to help
6266
public abstract void retrieve(@Nonnull String name, @Nonnull String version, @Nonnull FilePath target, @Nonnull Run<?,?> run, @Nonnull TaskListener listener) throws Exception;
6367

68+
@Deprecated
69+
public FormValidation validateVersion(@Nonnull String name, @Nonnull String version) {
70+
if (Util.isOverridden(LibraryRetriever.class, getClass(), "validateVersion", String.class, String.class, Item.class)) {
71+
return validateVersion(name, version, null);
72+
}
73+
return FormValidation.ok();
74+
}
75+
6476
/**
6577
* Offer to validate a proposed {@code version} for {@link #retrieve}.
6678
* @param name the proposed library name
6779
* @param version a proposed version
80+
* @param context optional context in which this runs
6881
* @return by default, OK
6982
*/
70-
public FormValidation validateVersion(@Nonnull String name, @Nonnull String version) {
71-
return FormValidation.ok();
83+
public FormValidation validateVersion(@Nonnull String name, @Nonnull String version, @CheckForNull Item context) {
84+
return validateVersion(name, version);
7285
}
7386

7487
@Override public LibraryRetrieverDescriptor getDescriptor() {

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import hudson.Util;
3030
import hudson.model.Descriptor;
3131
import hudson.model.DescriptorVisibilityFilter;
32+
import hudson.model.Item;
3233
import hudson.model.Items;
3334
import hudson.model.Run;
3435
import hudson.model.TaskListener;
@@ -67,7 +68,8 @@ public SCM getScm() {
6768
@Override public void retrieve(String name, String version, FilePath target, Run<?, ?> run, TaskListener listener) throws Exception {
6869
SCMSourceRetriever.doRetrieve(name, true, scm, target, run, listener);
6970
}
70-
@Override public FormValidation validateVersion(String name, String version) {
71+
72+
@Override public FormValidation validateVersion(String name, String version, Item context) {
7173
if (!Items.XSTREAM2.toXML(scm).contains("${library." + name + ".version}")) {
7274
return FormValidation.warningWithMarkup("When using <b>" + getDescriptor().getDisplayName() + "</b>, you will need to include <code>${library." + Util.escape(name) + ".version}</code> in the SCM configuration somewhere.");
7375
}

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

+6-5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import hudson.model.Computer;
3535
import hudson.model.Descriptor;
3636
import hudson.model.DescriptorVisibilityFilter;
37+
import hudson.model.Item;
3738
import hudson.model.Node;
3839
import hudson.model.Run;
3940
import hudson.model.TaskListener;
@@ -85,7 +86,7 @@ public SCMSource getScm() {
8586
}
8687

8788
@Override public void retrieve(String name, String version, boolean changelog, FilePath target, Run<?, ?> run, TaskListener listener) throws Exception {
88-
SCMRevision revision = retrySCMOperation(listener, () -> scm.fetch(version, listener));
89+
SCMRevision revision = retrySCMOperation(listener, () -> scm.fetch(version, listener, run.getParent()));
8990
if (revision == null) {
9091
throw new AbortException("No version " + version + " found for library " + name);
9192
}
@@ -164,11 +165,11 @@ private static String getFilePathSuffix() {
164165
return System.getProperty(WorkspaceList.class.getName(), "@");
165166
}
166167

167-
@Override public FormValidation validateVersion(String name, String version) {
168+
@Override public FormValidation validateVersion(String name, String version, Item context) {
168169
StringWriter w = new StringWriter();
169170
try {
170171
StreamTaskListener listener = new StreamTaskListener(w);
171-
SCMRevision revision = scm.fetch(version, listener);
172+
SCMRevision revision = scm.fetch(version, listener, context);
172173
if (revision != null) {
173174
// TODO validate repository structure using SCMFileSystem when implemented (JENKINS-33273)
174175
return FormValidation.ok("Currently maps to revision: " + revision);
@@ -189,13 +190,13 @@ private static String getFilePathSuffix() {
189190
}
190191

191192
/**
192-
* Returns only implementations overriding {@link SCMSource#retrieve(String, TaskListener)}.
193+
* Returns only implementations overriding {@link SCMSource#retrieve(String, TaskListener)} or {@link SCMSource#retrieve(String, TaskListener, Item)}.
193194
*/
194195
@Restricted(NoExternalUse.class) // Jelly, Hider
195196
public Collection<SCMSourceDescriptor> getSCMDescriptors() {
196197
List<SCMSourceDescriptor> descriptors = new ArrayList<>();
197198
for (SCMSourceDescriptor d : ExtensionList.lookup(SCMSourceDescriptor.class)) {
198-
if (Util.isOverridden(SCMSource.class, d.clazz, "retrieve", String.class, TaskListener.class)) {
199+
if (Util.isOverridden(SCMSource.class, d.clazz, "retrieve", String.class, TaskListener.class) || Util.isOverridden(SCMSource.class, d.clazz, "retrieve", String.class, TaskListener.class, Item.class)) {
199200
descriptors.add(d);
200201
}
201202
}

src/test/java/org/jenkinsci/plugins/workflow/libs/SCMSourceRetrieverTest.java

+60-6
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,39 @@
2424

2525
package org.jenkinsci.plugins.workflow.libs;
2626

27+
import hudson.AbortException;
2728
import hudson.FilePath;
29+
import hudson.model.Item;
2830
import hudson.model.Result;
31+
import hudson.model.TaskListener;
32+
import hudson.scm.ChangeLogSet;
33+
import hudson.scm.SCM;
2934
import hudson.slaves.WorkspaceList;
30-
31-
import java.util.List;
32-
import java.util.Iterator;
35+
import java.io.IOException;
3336
import java.util.Collections;
37+
import java.util.Iterator;
38+
import java.util.List;
3439
import jenkins.plugins.git.GitSCMSource;
3540
import jenkins.plugins.git.GitSampleRepoRule;
41+
import jenkins.scm.api.SCMHead;
42+
import jenkins.scm.api.SCMHeadEvent;
43+
import jenkins.scm.api.SCMHeadObserver;
44+
import jenkins.scm.api.SCMRevision;
3645
import jenkins.scm.api.SCMSource;
46+
import jenkins.scm.api.SCMSourceCriteria;
47+
import jenkins.scm.api.SCMSourceDescriptor;
3748
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
3849
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
3950
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
40-
import hudson.scm.ChangeLogSet;
41-
import org.junit.ClassRule;
42-
import org.junit.Test;
4351
import static org.junit.Assert.*;
52+
import org.junit.ClassRule;
4453
import org.junit.Rule;
54+
import org.junit.Test;
4555
import org.jvnet.hudson.test.BuildWatcher;
4656
import org.jvnet.hudson.test.Issue;
4757
import org.jvnet.hudson.test.JenkinsRule;
58+
import org.jvnet.hudson.test.SingleFileSCM;
59+
import org.jvnet.hudson.test.TestExtension;
4860

4961
public class SCMSourceRetrieverTest {
5062

@@ -133,6 +145,48 @@ public class SCMSourceRetrieverTest {
133145
}
134146
}
135147

148+
@Issue("JENKINS-43802")
149+
@Test public void owner() throws Exception {
150+
GlobalLibraries.get().setLibraries(Collections.singletonList(
151+
new LibraryConfiguration("test", new SCMSourceRetriever(new NeedsOwnerSCMSource()))));
152+
WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p");
153+
p.setDefinition(new CpsFlowDefinition("@Library('test@abc123') import libVersion; echo(/loaded lib #${libVersion()}/)", true));
154+
WorkflowRun b = r.buildAndAssertSuccess(p);
155+
r.assertLogContains("loaded lib #abc123", b);
156+
r.assertLogContains("Running in retrieve from p", b);
157+
}
158+
public static final class NeedsOwnerSCMSource extends SCMSource {
159+
@Override protected SCMRevision retrieve(String version, TaskListener listener, Item context) throws IOException, InterruptedException {
160+
if (context == null) {
161+
throw new AbortException("No context in retrieve!");
162+
} else {
163+
listener.getLogger().println("Running in retrieve from " + context.getFullName());
164+
}
165+
return new DummySCMRevision(version, new SCMHead("trunk"));
166+
}
167+
@Override public SCM build(SCMHead head, SCMRevision revision) {
168+
String version = ((DummySCMRevision) revision).version;
169+
return new SingleFileSCM("vars/libVersion.groovy", ("def call() {'" + version + "'}").getBytes());
170+
}
171+
private static final class DummySCMRevision extends SCMRevision {
172+
private final String version;
173+
DummySCMRevision(String version, SCMHead head) {
174+
super(head);
175+
this.version = version;
176+
}
177+
@Override public boolean equals(Object obj) {
178+
return obj instanceof DummySCMRevision && version.equals(((DummySCMRevision) obj).version);
179+
}
180+
@Override public int hashCode() {
181+
return version.hashCode();
182+
}
183+
}
184+
@Override protected void retrieve(SCMSourceCriteria criteria, SCMHeadObserver observer, SCMHeadEvent<?> event, TaskListener listener) throws IOException, InterruptedException {
185+
throw new IOException("not implemented");
186+
}
187+
@TestExtension("owner") public static final class DescriptorImpl extends SCMSourceDescriptor {}
188+
}
189+
136190
@Test public void retry() throws Exception {
137191
WorkflowRun b = prepareRetryTests(new FailingSCMSource());
138192
r.assertLogContains("Failing 'checkout' on purpose!", b);

0 commit comments

Comments
 (0)