Skip to content

Commit

Permalink
Allow remote polling to work with multiple simple branches
Browse files Browse the repository at this point in the history
As long as the branch specs can't match multiple remote branches, then
remote polling can be used since it can (and already does) match each
branch spec against the map returned from `git ls-remote`. Add a
separate helper to determine if all branch specs are simple and use that
to determine if workspace polling is required.
  • Loading branch information
dbnicholson committed Feb 13, 2025
1 parent ea4629d commit efd3f8f
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 7 deletions.
41 changes: 35 additions & 6 deletions src/main/java/hudson/plugins/git/GitSCM.java
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,37 @@ private String getSingleBranch(EnvVars env) {
return branch;
}

/**
* If any branch can match a multiple remote branches, then workspace polling is required.
*
* Returns {@code true} if any branches require workspace polling.
*/
private boolean branchesRequireWorkspaceForPolling(@NonNull EnvVars env, @CheckForNull TaskListener listener) {
for (BranchSpec branchSpec : getBranches()) {
final String branch = branchSpec.getName();
final String expandedBranch = env.expand(branch);

// If the branch contains a wildcard anywhere other than a leading */ or is empty (which is intepreted as
// **), it can match multiple remote branches.
final String strippedBranch = expandedBranch.replaceAll("^\\*/", "");
if (strippedBranch.equals("") || strippedBranch.contains("*")) {
if (listener != null) {
final PrintStream log = listener.getLogger();

if (branch.equals(expandedBranch)) {

Check warning on line 684 in src/main/java/hudson/plugins/git/GitSCM.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 684 is only partially covered, one branch is missing
log.printf("Branch '%s' requires workspace for polling%n", branch);
} else {
log.printf("Branch '%s' (expanded to '%s') requires workspace for polling%n",

Check warning on line 687 in src/main/java/hudson/plugins/git/GitSCM.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 687 is not covered by tests
branch, expandedBranch);
}
}
return true;
}
}

return false;
}

@Override
public SCMRevisionState calcRevisionsFromBuild(Run<?, ?> abstractBuild, FilePath workspace, Launcher launcher, TaskListener taskListener) throws IOException, InterruptedException {
return SCMRevisionState.NONE;
Expand All @@ -672,17 +703,15 @@ public SCMRevisionState calcRevisionsFromBuild(Run<?, ?> abstractBuild, FilePath
@Override
public boolean requiresWorkspaceForPolling() {
// TODO would need to use hudson.plugins.git.util.GitUtils.getPollEnvironment

Check warning on line 705 in src/main/java/hudson/plugins/git/GitSCM.java

View check run for this annotation

ci.jenkins.io / Open Tasks Scanner

TODO

NORMAL: would need to use hudson.plugins.git.util.GitUtils.getPollEnvironment
return requiresWorkspaceForPolling(new EnvVars());
return requiresWorkspaceForPolling(new EnvVars(), null);
}

/* Package protected for test access */
boolean requiresWorkspaceForPolling(EnvVars environment) {
boolean requiresWorkspaceForPolling(EnvVars environment, TaskListener listener) {
for (GitSCMExtension ext : getExtensions()) {
if (ext.requiresWorkspaceForPolling()) return true;
}

final String singleBranch = getSingleBranch(environment);
return singleBranch == null || singleBranch.equals("**");
return branchesRequireWorkspaceForPolling(environment, listener);
}

@Override
Expand Down Expand Up @@ -717,7 +746,7 @@ private PollingResult compareRemoteRevisionWithImpl(Job<?, ?> project, Launcher

final String singleBranch = getSingleBranch(pollEnv);

if (!requiresWorkspaceForPolling(pollEnv)) {
if (!requiresWorkspaceForPolling(pollEnv, listener)) {

final EnvVars environment = project instanceof AbstractProject<?,?> ap ? GitUtils.getPollEnvironment(ap, workspace, launcher, listener, false) : new EnvVars();

Expand Down
24 changes: 24 additions & 0 deletions src/test/java/hudson/plugins/git/GitSCMTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2630,6 +2630,30 @@ public void testPolling_CanDoRemotePollingIfOneBranchButMultipleRepositories() t
assertFalse(pollingResult.hasChanges());
}

@Test
public void testPolling_CanDoRemotePollingIfMultipleBranches() throws Exception {
assumeTrue("Test class max time " + MAX_SECONDS_FOR_THESE_TESTS + " exceeded", isTimeAvailable());
FreeStyleProject project = createFreeStyleProject();
List<BranchSpec> branchSpecs = Arrays.asList(
new BranchSpec("*/master"),
new BranchSpec("*/stable"));
GitSCM scm = new GitSCM(createRemoteRepositories(),
branchSpecs, null, null,
Collections.emptyList());
project.setScm(scm);
assertFalse("scm should not require workspace for polling", scm.requiresWorkspaceForPolling());

commit("commitFile1", johnDoe, "Commit number 1");
git.branch("stable");

FreeStyleBuild first_build = project.scheduleBuild2(0, new Cause.UserIdCause()).get();
r.assertBuildStatus(Result.SUCCESS, first_build);

first_build.getWorkspace().deleteContents();
PollingResult pollingResult = scm.poll(project, null, first_build.getWorkspace(), listener, null);
assertFalse(pollingResult.hasChanges());
}

@Issue("JENKINS-24467")
@Test
public void testPolling_environmentValueAsEnvironmentContributingAction() throws Exception {
Expand Down
26 changes: 25 additions & 1 deletion src/test/java/hudson/plugins/git/GitSCMUnitTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,30 @@ public void testRequiresWorkspaceForPollingMultiBranch() throws Exception {
List<BranchSpec> branches = new ArrayList<>();
branches.add(new BranchSpec("master"));
branches.add(new BranchSpec("origin/master"));
GitSCM bigGitSCM = new GitSCM(createRepoList(repoURL, null),
branches,
null, null, Collections.emptyList());
assertFalse(bigGitSCM.requiresWorkspaceForPolling());
}

@Test
public void testRequiresWorkspaceForPollingMultiBranchWithWildcardRemoteName() throws Exception {
/* Multi-branch use case */
List<BranchSpec> branches = new ArrayList<>();
branches.add(new BranchSpec("master"));
branches.add(new BranchSpec("*/master"));
GitSCM bigGitSCM = new GitSCM(createRepoList(repoURL, null),
branches,
null, null, Collections.emptyList());
assertFalse(bigGitSCM.requiresWorkspaceForPolling());
}

@Test
public void testRequiresWorkspaceForPollingMultiBranchWithWildcardSuffix() throws Exception {
/* Multi-branch use case */
List<BranchSpec> branches = new ArrayList<>();
branches.add(new BranchSpec("master"));
branches.add(new BranchSpec("*/stable*"));
GitSCM bigGitSCM = new GitSCM(createRepoList(repoURL, null),
branches,
null, null, Collections.emptyList());
Expand All @@ -275,7 +299,7 @@ public void testRequiresWorkspaceForPollingEmptyBranchName() throws Exception {
GitSCM bigGitSCM = new GitSCM(createRepoList(repoURL, null),
Collections.singletonList(new BranchSpec("${A}")),
null, null, Collections.emptyList());
assertTrue(bigGitSCM.requiresWorkspaceForPolling(env));
assertTrue(bigGitSCM.requiresWorkspaceForPolling(env, null));
}

@Test
Expand Down

0 comments on commit efd3f8f

Please sign in to comment.