Skip to content

Commit

Permalink
Merge pull request #314 from jglick/subversion
Browse files Browse the repository at this point in the history
Remove `subversion` test dep
  • Loading branch information
jglick authored Aug 7, 2024
2 parents 3479e8f + 4dce43d commit e0cb1f4
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 169 deletions.
40 changes: 4 additions & 36 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,25 +63,20 @@ THE SOFTWARE.
</pluginRepositories>
<properties>
<changelist>999999-SNAPSHOT</changelist>
<jenkins.version>2.454</jenkins.version>
<jenkins.baseline>2.462</jenkins.baseline>
<jenkins.version>${jenkins.baseline}</jenkins.version>
<no-test-jar>false</no-test-jar>
<gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.jenkins.tools.bom</groupId>
<artifactId>bom-2.440.x</artifactId>
<version>2746.vb_79a_1d3e7b_c8</version>
<artifactId>bom-${jenkins.baseline}.x</artifactId>
<version>3221.ve8f7b_fdd149d</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<!-- TODO until in BOM -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>cloudbees-folder</artifactId>
<version>6.919.va_e17e72383f5</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
Expand Down Expand Up @@ -173,39 +168,12 @@ THE SOFTWARE.
<artifactId>git</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>subversion</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-common</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>git</artifactId>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>subversion</artifactId>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.tmatesoft.svnkit</groupId>
<artifactId>svnkit-cli</artifactId>
<version>1.10.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
package org.jenkinsci.plugins.workflow.multibranch;

import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.Extension;
import hudson.Functions;
import hudson.MarkupText;
Expand Down Expand Up @@ -54,14 +55,18 @@
import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;

/**
* Checks out the desired version of the script referred to by scriptPath.
*/
class SCMBinder extends FlowDefinition {
@Restricted(NoExternalUse.class) // just tests
public class SCMBinder extends FlowDefinition {

/** Kill switch for JENKINS-33273 in case of problems. */
static /* not final */ boolean USE_HEAVYWEIGHT_CHECKOUT = Boolean.getBoolean(SCMBinder.class.getName() + ".USE_HEAVYWEIGHT_CHECKOUT"); // TODO 2.4+ use SystemProperties
@SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "Just for scripting.")
public static boolean USE_HEAVYWEIGHT_CHECKOUT = Boolean.getBoolean(SCMBinder.class.getName() + ".USE_HEAVYWEIGHT_CHECKOUT"); // TODO 2.4+ use SystemProperties

Check warning on line 69 in src/main/java/org/jenkinsci/plugins/workflow/multibranch/SCMBinder.java

View check run for this annotation

ci.jenkins.io / Open Tasks Scanner

TODO

NORMAL: 2.4+ use SystemProperties
private String scriptPath = WorkflowBranchProjectFactory.SCRIPT;

public Object readResolve() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@

import hudson.Functions;
import hudson.model.Result;
import hudson.scm.SubversionSCM;
import java.io.File;
import java.nio.charset.StandardCharsets;
import jenkins.branch.BranchSource;
import jenkins.plugins.git.GitSampleRepoRule;
import jenkins.plugins.git.GitStep;
Expand All @@ -47,25 +44,15 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import jenkins.plugins.git.GitSCMSource;
import jenkins.scm.impl.subversion.SubversionSCMSource;
import jenkins.scm.impl.subversion.SubversionSampleRepoRule;
import org.apache.commons.io.FileUtils;
import org.junit.Ignore;
import org.jvnet.hudson.test.FlagRule;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.io.FileMatchers.anExistingFile;
import static org.junit.Assume.assumeFalse;

public class ReadTrustedStepTest {

@ClassRule public static BuildWatcher buildWatcher = new BuildWatcher();
@Rule public JenkinsRule r = new JenkinsRule();
@Rule public GitSampleRepoRule sampleRepo = new GitSampleRepoRule();
@Rule public SubversionSampleRepoRule sampleRepoSvn = new SubversionSampleRepoRule();
@Rule public FlagRule<Boolean> heavyweightCheckoutFlag = new FlagRule<>(() -> SCMBinder.USE_HEAVYWEIGHT_CHECKOUT, v -> { SCMBinder.USE_HEAVYWEIGHT_CHECKOUT = v; });

@Test public void smokes() throws Exception {
Expand Down Expand Up @@ -305,76 +292,4 @@ public void symlinksInNonMultibranchCannotEscapeWorkspaceContextViaReadTrusted()
r.assertLogContains("master.key references a file that is not inside " + r.jenkins.getWorkspaceFor(p), run);
}

@Ignore("There are two checkouts, one from CpsScmFlowDefinition via SCMBinder and one from ReadTrustedStep. Fixing the former requires an updated version of workflow-cps.")
@Issue("SECURITY-2463")
@Test public void multibranchCheckoutDirectoriesAreNotReusedByDifferentScms() throws Exception {
SCMBinder.USE_HEAVYWEIGHT_CHECKOUT = true;
assumeFalse(Functions.isWindows()); // Checkout hook is not cross-platform.
sampleRepo.init();
sampleRepo.git("checkout", "-b", "trunk"); // So we end up using the same project for both SCMs.
sampleRepo.write("Jenkinsfile", "echo('git library'); readTrusted('Jenkinsfile')");
sampleRepo.git("add", "Jenkinsfile");
sampleRepo.git("commit", "--message=init");
sampleRepoSvn.init();
sampleRepoSvn.write("Jenkinsfile", "echo('svn library'); readTrusted('Jenkinsfile')");
// Copy .git folder from the Git repo into the SVN repo as data.
File gitDirInSvnRepo = new File(sampleRepoSvn.wc(), ".git");
FileUtils.copyDirectory(new File(sampleRepo.getRoot(), ".git"), gitDirInSvnRepo);
String jenkinsRootDir = r.jenkins.getRootDir().toString();
// Add a Git post-checkout hook to the .git folder in the SVN repo.
Path postCheckoutHook = gitDirInSvnRepo.toPath().resolve("hooks/post-checkout");
// Always create hooks directory for compatibility with https://github.com/jenkinsci/git-plugin/pull/1207.
Files.createDirectories(postCheckoutHook.getParent());
Files.write(postCheckoutHook, ("#!/bin/sh\ntouch '" + jenkinsRootDir + "/hook-executed'\n").getBytes(StandardCharsets.UTF_8));
sampleRepoSvn.svnkit("add", sampleRepoSvn.wc() + "/Jenkinsfile");
sampleRepoSvn.svnkit("add", sampleRepoSvn.wc() + "/.git");
sampleRepoSvn.svnkit("propset", "svn:executable", "ON", sampleRepoSvn.wc() + "/.git/hooks/post-checkout");
sampleRepoSvn.svnkit("commit", "--message=init", sampleRepoSvn.wc());
// Run a build using the SVN repo.
WorkflowMultiBranchProject mp = r.jenkins.createProject(WorkflowMultiBranchProject.class, "p");
mp.getSourcesList().add(new BranchSource(new SubversionSCMSource("", sampleRepoSvn.prjUrl())));
WorkflowJob p = WorkflowMultiBranchProjectTest.scheduleAndFindBranchProject(mp, "trunk");
r.waitUntilNoActivity();
// Run a build using the Git repo. It should be checked out to a different directory than the SVN repo.
mp.getSourcesList().clear();
mp.getSourcesList().add(new BranchSource(new GitSCMSource("", sampleRepo.toString(), "", "*", "", false)));
WorkflowMultiBranchProjectTest.scheduleAndFindBranchProject(mp, "trunk");
r.waitUntilNoActivity();
assertThat(p.getLastBuild().getNumber(), equalTo(2));
assertThat(new File(r.jenkins.getRootDir(), "hook-executed"), not(anExistingFile()));
}

@Ignore("There are two checkouts, one from CpsScmFlowDefinition and one from ReadTrustedStep. Fixing the former requires an updated version of workflow-cps.")
@Issue("SECURITY-2463")
@Test public void checkoutDirectoriesAreNotReusedByDifferentScms() throws Exception {
SCMBinder.USE_HEAVYWEIGHT_CHECKOUT = true;
assumeFalse(Functions.isWindows()); // Checkout hook is not cross-platform.
sampleRepo.init();
sampleRepo.write("Jenkinsfile", "echo('git library'); readTrusted('Jenkinsfile')");
sampleRepo.git("add", "Jenkinsfile");
sampleRepo.git("commit", "--message=init");
sampleRepoSvn.init();
sampleRepoSvn.write("Jenkinsfile", "echo('subversion library'); readTrusted('Jenkinsfile')");
// Copy .git folder from the Git repo into the SVN repo as data.
File gitDirInSvnRepo = new File(sampleRepoSvn.wc(), ".git");
FileUtils.copyDirectory(new File(sampleRepo.getRoot(), ".git"), gitDirInSvnRepo);
String jenkinsRootDir = r.jenkins.getRootDir().toString();
// Add a Git post-checkout hook to the .git folder in the SVN repo.
Path postCheckoutHook = gitDirInSvnRepo.toPath().resolve("hooks/post-checkout");
// Always create hooks directory for compatibility with https://github.com/jenkinsci/git-plugin/pull/1207.
Files.createDirectories(postCheckoutHook.getParent());
Files.write(postCheckoutHook, ("#!/bin/sh\ntouch '" + jenkinsRootDir + "/hook-executed'\n").getBytes(StandardCharsets.UTF_8));
sampleRepoSvn.svnkit("add", sampleRepoSvn.wc() + "/Jenkinsfile");
sampleRepoSvn.svnkit("add", sampleRepoSvn.wc() + "/.git");
sampleRepoSvn.svnkit("propset", "svn:executable", "ON", sampleRepoSvn.wc() + "/.git/hooks/post-checkout");
sampleRepoSvn.svnkit("commit", "--message=init", sampleRepoSvn.wc());
// Run a build using the SVN repo.
WorkflowJob p = r.createProject(WorkflowJob.class);
p.setDefinition(new CpsScmFlowDefinition(new SubversionSCM(sampleRepoSvn.trunkUrl()), "Jenkinsfile"));
r.buildAndAssertSuccess(p);
// Run a build using the Git repo. It should be checked out to a different directory than the SVN repo.
p.setDefinition(new CpsScmFlowDefinition(new GitStep(sampleRepo.toString()).createSCM(), "Jenkinsfile"));
WorkflowRun b2 = r.buildAndAssertSuccess(p);
assertThat(new File(r.jenkins.getRootDir(), "hook-executed"), not(anExistingFile()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,8 @@
import jenkins.scm.api.SCMRevision;
import jenkins.scm.api.SCMRevisionAction;
import jenkins.scm.api.SCMSourceDescriptor;
import jenkins.scm.impl.subversion.SubversionSCMFileSystem;
import jenkins.scm.impl.subversion.SubversionSCMSource;
import static org.hamcrest.Matchers.*;

import jenkins.scm.impl.subversion.SubversionSampleRepoRule;
import org.acegisecurity.Authentication;
import org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
Expand All @@ -72,7 +69,6 @@ public class SCMBinderTest {
@ClassRule public static BuildWatcher buildWatcher = new BuildWatcher();
@Rule public JenkinsRule r = new JenkinsRule();
@Rule public GitSampleRepoRule sampleGitRepo = new GitSampleRepoRule();
@Rule public SubversionSampleRepoRule sampleSvnRepo = new SubversionSampleRepoRule();

@Test public void exactRevisionGit() throws Exception {
sampleGitRepo.init();
Expand Down Expand Up @@ -131,48 +127,6 @@ public static void assertRevisionAction(WorkflowRun build) {
}
}

static {
System.setProperty(SubversionSCMFileSystem.DISABLE_PROPERTY, "true");
}
@Test public void exactRevisionSubversion() throws Exception {
sampleSvnRepo.init();
ScriptApproval sa = ScriptApproval.get();
sa.approveSignature("staticField hudson.model.Items XSTREAM2");
sa.approveSignature("method com.thoughtworks.xstream.XStream toXML java.lang.Object");
sampleSvnRepo.write("Jenkinsfile", "echo hudson.model.Items.XSTREAM2.toXML(scm); semaphore 'wait'; node {checkout scm; echo readFile('file')}");
sampleSvnRepo.write("file", "initial content");
sampleSvnRepo.svnkit("add", sampleSvnRepo.wc() + "/Jenkinsfile");
sampleSvnRepo.svnkit("commit", "--message=flow", sampleSvnRepo.wc());
WorkflowMultiBranchProject mp = r.jenkins.createProject(WorkflowMultiBranchProject.class, "p");
mp.getSourcesList().add(new BranchSource(new SubversionSCMSource(null, sampleSvnRepo.prjUrl())));
WorkflowJob p = WorkflowMultiBranchProjectTest.scheduleAndFindBranchProject(mp, "trunk");
SemaphoreStep.waitForStart("wait/1", null);
WorkflowRun b1 = p.getLastBuild();
assertNotNull(b1);
assertEquals(1, b1.getNumber());
sampleSvnRepo.write("Jenkinsfile", "node {checkout scm; echo readFile('file').toUpperCase()}");
sampleSvnRepo.write("file", "subsequent content");
sampleSvnRepo.svnkit("commit", "--message=tweaked", sampleSvnRepo.wc());
SemaphoreStep.success("wait/1", null);
WorkflowRun b2 = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
assertEquals(2, b2.getNumber());
r.assertLogContains("initial content", r.waitForCompletion(b1));
r.assertLogContains("SUBSEQUENT CONTENT", b2);
List<ChangeLogSet<? extends ChangeLogSet.Entry>> changeSets = b2.getChangeSets();
/* TODO JENKINS-29326 analogue: currently 2 (they are the same):
assertEquals(1, changeSets.size());
*/
ChangeLogSet<? extends ChangeLogSet.Entry> changeSet = changeSets.get(0);
assertEquals(b2, changeSet.getRun());
assertEquals("svn", changeSet.getKind());
Iterator<? extends ChangeLogSet.Entry> iterator = changeSet.iterator();
assertTrue(iterator.hasNext());
ChangeLogSet.Entry entry = iterator.next();
assertEquals("tweaked", entry.getMsg());
assertEquals("[Jenkinsfile, file]", new TreeSet<>(entry.getAffectedPaths()).toString());
assertFalse(iterator.hasNext());
}

@Test public void deletedJenkinsfile() throws Exception {
sampleGitRepo.init();
sampleGitRepo.write("Jenkinsfile", "node { echo 'Hello World' }");
Expand Down

0 comments on commit e0cb1f4

Please sign in to comment.