Skip to content

Commit 3ab523c

Browse files
[JENKINS-43052] Warn if a deprecated extension is used in Pipeline (#3905)
* Warn in Pipeline when RelativeTargetDirectory extension is used * Warn in Pipeline when deprecated polling extensions are used * Warn in Pipeline when deprecated polling and message exclusion extensions are used * Warn in Pipeline build log when PreBuildMerge extension is used * Warn in Pipeline build log when WipeWorkspace extension is used * [JENKINS-43052] Standardize Pipeline deprecation warnings to DEPRECATED prefix * Add Pipeline Workflow tests for deprecated GitSCM extensions * Guard against null Run in PreBuildMerge.decorateRevisionToBuild * Use consistent spacing * Add comment explaining why instanceof is not used * Use scmGit() in a block quote for easier reading of test source * Use more precise assertion of expected deprecation message * Improve Pipeline deprecation Workflow tests and align warnings * Normalize sampleRepo path in Workflow tests for Windows compatibility * Reduce diffs to master branch * Escape backslash in test repository path * Use beforeCheckout to warn on each deprecated extension Consistent coding pattern and avoids the need for a variable to decide if the message has been displayed. Messages will be displayed each checkout. Still needs test for message exclusion deprecation and for requires workspace polling deprecation. * Add a message exclusion workflow test * Add a disable remote polling workflow test * Remove duplicated test --------- Co-authored-by: Mark Waite <[email protected]>
1 parent eede7cf commit 3ab523c

File tree

10 files changed

+306
-0
lines changed

10 files changed

+306
-0
lines changed

src/main/java/hudson/plugins/git/extensions/GitSCMExtension.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ public Revision decorateRevisionToBuild(GitSCM scm, AbstractBuild<?,?> build, Gi
161161
* @throws GitException on git error
162162
*/
163163
public void beforeCheckout(GitSCM scm, Run<?,?> build, GitClient git, TaskListener listener) throws IOException, InterruptedException, GitException {
164+
if (requiresWorkspaceForPolling() && build != null && build.getClass().getName().startsWith("org.jenkinsci.plugins.workflow.job.")) {
165+
listener.getLogger().println("DEPRECATED: The extension that requires a workspace for polling is deprecated for Pipeline jobs. " + "Use Pipeline-native SCM polling instead.");
166+
}
164167
if (build instanceof AbstractBuild<?,?> abstractBuild && listener instanceof BuildListener buildListener) {
165168
beforeCheckout(scm, abstractBuild, git, buildListener);
166169
}

src/main/java/hudson/plugins/git/extensions/impl/MessageExclusion.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import edu.umd.cs.findbugs.annotations.CheckForNull;
44
import hudson.Extension;
5+
import hudson.model.Run;
56
import hudson.model.TaskListener;
67
import hudson.plugins.git.GitChangeSet;
78
import hudson.plugins.git.GitException;
@@ -54,6 +55,16 @@ public Boolean isRevExcluded(GitSCM scm, GitClient git, GitChangeSet commit, Tas
5455
return null;
5556
}
5657

58+
/**
59+
* {@inheritDoc}
60+
*/
61+
@Override
62+
public void beforeCheckout(GitSCM scm, Run<?, ?> build, GitClient git, TaskListener listener) throws IOException, InterruptedException, GitException {
63+
if (build != null && build.getClass().getName().startsWith("org.jenkinsci.plugins.workflow.job.")) {
64+
listener.getLogger().println("DEPRECATED: Message exclusion during polling is deprecated for Pipeline jobs. " + "Use the Pipeline SCM trait instead.");
65+
}
66+
}
67+
5768
@Extension
5869
// No @Symbol annotation because message exclusion is done using a trait in Pipeline
5970
public static class DescriptorImpl extends GitSCMExtensionDescriptor {

src/main/java/hudson/plugins/git/extensions/impl/PreBuildMerge.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,16 @@ public void decorateMergeCommand(GitSCM scm, Run<?, ?> build, GitClient git, Tas
132132
cmd.setGitPluginFastForwardMode(options.getFastForwardMode());
133133
}
134134

135+
/**
136+
* {@inheritDoc}
137+
*/
138+
@Override
139+
public void beforeCheckout(GitSCM scm, Run<?, ?> build, GitClient git, TaskListener listener) throws IOException, InterruptedException, GitException {
140+
if (build != null && build.getClass().getName().startsWith("org.jenkinsci.plugins.workflow.job.")) {
141+
listener.getLogger().println("DEPRECATED: The 'Merge before build' extension is deprecated for Pipeline jobs. " + "Pipeline users should perform merges explicitly using shell steps (e.g. sh 'git merge').");
142+
}
143+
}
144+
135145
@Override
136146
public GitClientType getRequiredClient() {
137147
return GitClientType.GITCLI;

src/main/java/hudson/plugins/git/extensions/impl/RelativeTargetDirectory.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
import hudson.Extension;
55
import hudson.FilePath;
66
import hudson.model.Job;
7+
import hudson.model.Run;
78
import hudson.model.TaskListener;
89
import hudson.plugins.git.GitException;
910
import hudson.plugins.git.GitSCM;
1011
import hudson.plugins.git.Messages;
1112
import hudson.plugins.git.extensions.GitSCMExtension;
1213
import hudson.plugins.git.extensions.GitSCMExtensionDescriptor;
14+
import org.jenkinsci.plugins.gitclient.GitClient;
1315
import org.kohsuke.stapler.DataBoundConstructor;
1416

1517
import java.io.IOException;
@@ -33,6 +35,16 @@ public String getRelativeTargetDir() {
3335
return relativeTargetDir;
3436
}
3537

38+
/**
39+
* {@inheritDoc}
40+
*/
41+
@Override
42+
public void beforeCheckout(GitSCM scm, Run<?, ?> build, GitClient git, TaskListener listener) throws IOException, InterruptedException, GitException {
43+
if (build != null && build.getClass().getName().startsWith("org.jenkinsci.plugins.workflow.job.")) {
44+
listener.getLogger().println("DEPRECATED: Relative target directory is deprecated for Pipeline jobs. " + "Use the 'dir' step instead.");
45+
}
46+
}
47+
3648
@Override
3749
public FilePath getWorkingDirectory(GitSCM scm, Job<?, ?> context, FilePath workspace, EnvVars environment, TaskListener listener) throws IOException, InterruptedException, GitException {
3850
if (relativeTargetDir == null || relativeTargetDir.length() == 0 || relativeTargetDir.equals(".")) {

src/main/java/hudson/plugins/git/extensions/impl/WipeWorkspace.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ public WipeWorkspace() {
2626
*/
2727
@Override
2828
public void beforeCheckout(GitSCM scm, Run<?, ?> build, GitClient git, TaskListener listener) throws IOException, InterruptedException, GitException {
29+
if (build != null && build.getClass().getName().startsWith("org.jenkinsci.plugins.workflow.job.")) {
30+
listener.getLogger().println("DEPRECATED: The 'Wipe out repository & force clone' extension is deprecated for Pipeline jobs. " + "Pipeline users should use the deleteDir() step instead.");
31+
}
32+
2933
listener.getLogger().println("Wiping out workspace first.");
3034
git.getWorkTree().deleteContents();
3135
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package hudson.plugins.git.extensions.impl;
2+
3+
import jenkins.plugins.git.GitSampleRepoRule;
4+
import jenkins.plugins.git.junit.jupiter.WithGitSampleRepo;
5+
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
6+
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
7+
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
8+
import org.junit.jupiter.api.Test;
9+
import org.jvnet.hudson.test.JenkinsRule;
10+
import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
11+
12+
@WithJenkins
13+
@WithGitSampleRepo
14+
class DeprecatedPollingExtensionsWorkflowTest {
15+
16+
@Test
17+
void disableRemotePollTriggersDeprecatedWarning(
18+
JenkinsRule r,
19+
GitSampleRepoRule sampleRepo
20+
) throws Exception {
21+
22+
sampleRepo.init();
23+
24+
WorkflowJob job =
25+
r.jenkins.createProject(WorkflowJob.class,
26+
"disable-remote-poll-deprecated-warning");
27+
28+
job.setDefinition(new CpsFlowDefinition(
29+
"""
30+
node {
31+
checkout(
32+
scmGit(
33+
extensions: [[
34+
$class: 'DisableRemotePoll'
35+
]],
36+
userRemoteConfigs: [[url: '%s']]
37+
)
38+
)
39+
}
40+
""".formatted(sampleRepo.toString().replace("\\", "\\\\")),
41+
true
42+
));
43+
44+
WorkflowRun run = r.buildAndAssertSuccess(job);
45+
46+
r.waitForMessage(
47+
"DEPRECATED: The extension that requires a workspace for polling is deprecated for Pipeline jobs. "
48+
+ "Use Pipeline-native SCM polling instead.",
49+
run
50+
);
51+
}
52+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package hudson.plugins.git.extensions.impl;
2+
3+
import jenkins.plugins.git.GitSampleRepoRule;
4+
import jenkins.plugins.git.junit.jupiter.WithGitSampleRepo;
5+
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
6+
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
7+
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
8+
import org.junit.jupiter.api.Test;
9+
import org.jvnet.hudson.test.JenkinsRule;
10+
import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
11+
12+
@WithJenkins
13+
@WithGitSampleRepo
14+
class MessageExclusionWorkflowTest {
15+
16+
@Test
17+
void messageExclusionTriggersDeprecatedWarning(
18+
JenkinsRule r,
19+
GitSampleRepoRule sampleRepo
20+
) throws Exception {
21+
22+
sampleRepo.init();
23+
24+
WorkflowJob job =
25+
r.jenkins.createProject(WorkflowJob.class,
26+
"message-exclusion-deprecated-warning");
27+
28+
job.setDefinition(new CpsFlowDefinition(
29+
"""
30+
node {
31+
checkout(
32+
scmGit(
33+
extensions: [[
34+
$class: 'MessageExclusion',
35+
excludedMessage: 'excluded-message'
36+
]],
37+
userRemoteConfigs: [[url: '%s']]
38+
)
39+
)
40+
}
41+
""".formatted(sampleRepo.toString().replace("\\", "\\\\")),
42+
true
43+
));
44+
45+
WorkflowRun run = r.buildAndAssertSuccess(job);
46+
47+
r.waitForMessage(
48+
"DEPRECATED: Message exclusion during polling is deprecated for Pipeline jobs. "
49+
+ "Use the Pipeline SCM trait instead.",
50+
run
51+
);
52+
}
53+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package hudson.plugins.git.extensions.impl;
2+
3+
import jenkins.plugins.git.GitSampleRepoRule;
4+
import jenkins.plugins.git.junit.jupiter.WithGitSampleRepo;
5+
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
6+
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
7+
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
8+
import org.junit.jupiter.api.Test;
9+
import org.jvnet.hudson.test.JenkinsRule;
10+
import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
11+
12+
@WithJenkins
13+
@WithGitSampleRepo
14+
class PreBuildMergeWorkflowTest {
15+
16+
@Test
17+
void preBuildMergeTriggersDeprecatedWarning(
18+
JenkinsRule r,
19+
GitSampleRepoRule sampleRepo
20+
) throws Exception {
21+
22+
sampleRepo.init();
23+
24+
WorkflowJob job =
25+
r.jenkins.createProject(WorkflowJob.class,
26+
"pre-build-merge-deprecated-warning");
27+
28+
job.setDefinition(new CpsFlowDefinition(
29+
"""
30+
node {
31+
checkout(
32+
scmGit(
33+
extensions: [[
34+
$class: 'PreBuildMerge',
35+
options: [
36+
mergeRemote: 'origin',
37+
mergeTarget: 'master'
38+
]
39+
]],
40+
userRemoteConfigs: [[url: '%s']]
41+
)
42+
)
43+
}
44+
""".formatted(sampleRepo.toString().replace("\\", "\\\\")),
45+
true
46+
));
47+
48+
WorkflowRun run = r.buildAndAssertSuccess(job);
49+
50+
r.waitForMessage(
51+
"DEPRECATED: The 'Merge before build' extension is deprecated for Pipeline jobs. "
52+
+ "Pipeline users should perform merges explicitly using shell steps (e.g. sh 'git merge').",
53+
run
54+
);
55+
}
56+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package hudson.plugins.git.extensions.impl;
2+
3+
import jenkins.plugins.git.GitSampleRepoRule;
4+
import jenkins.plugins.git.junit.jupiter.WithGitSampleRepo;
5+
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
6+
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
7+
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
8+
import org.junit.jupiter.api.Test;
9+
import org.jvnet.hudson.test.JenkinsRule;
10+
import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
11+
12+
@WithJenkins
13+
@WithGitSampleRepo
14+
class RelativeTargetDirectoryWorkflowTest {
15+
16+
@Test
17+
void relativeTargetDirectoryTriggersDeprecatedWarning(
18+
JenkinsRule r,
19+
GitSampleRepoRule sampleRepo
20+
) throws Exception {
21+
22+
sampleRepo.init();
23+
24+
WorkflowJob job =
25+
r.jenkins.createProject(WorkflowJob.class,
26+
"relative-target-directory-deprecated-warning");
27+
28+
job.setDefinition(new CpsFlowDefinition(
29+
"""
30+
node {
31+
checkout(
32+
scmGit(
33+
extensions: [[
34+
$class: 'RelativeTargetDirectory',
35+
relativeTargetDir: 'subdir'
36+
]],
37+
userRemoteConfigs: [[url: '%s']]
38+
)
39+
)
40+
}
41+
""".formatted(sampleRepo.toString().replace("\\", "\\\\")),
42+
true
43+
));
44+
45+
WorkflowRun run = r.buildAndAssertSuccess(job);
46+
47+
r.waitForMessage(
48+
"DEPRECATED: Relative target directory is deprecated for Pipeline jobs. "
49+
+ "Use the 'dir' step instead.",
50+
run
51+
);
52+
}
53+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package hudson.plugins.git.extensions.impl;
2+
3+
import jenkins.plugins.git.GitSampleRepoRule;
4+
import jenkins.plugins.git.junit.jupiter.WithGitSampleRepo;
5+
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
6+
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
7+
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
8+
import org.junit.jupiter.api.Test;
9+
import org.jvnet.hudson.test.JenkinsRule;
10+
import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
11+
12+
@WithJenkins
13+
@WithGitSampleRepo
14+
class WipeWorkspaceWorkflowTest {
15+
16+
@Test
17+
void wipeWorkspaceTriggersDeprecatedWarning(
18+
JenkinsRule r,
19+
GitSampleRepoRule sampleRepo
20+
) throws Exception {
21+
22+
sampleRepo.init();
23+
24+
WorkflowJob job =
25+
r.jenkins.createProject(WorkflowJob.class,
26+
"wipe-workspace-deprecated-warning");
27+
28+
job.setDefinition(new CpsFlowDefinition(
29+
"""
30+
node {
31+
checkout(
32+
scmGit(
33+
extensions: [[
34+
$class: 'WipeWorkspace'
35+
]],
36+
userRemoteConfigs: [[url: '%s']]
37+
)
38+
)
39+
}
40+
""".formatted(sampleRepo.toString().replace("\\", "\\\\")),
41+
true
42+
));
43+
44+
WorkflowRun run = r.buildAndAssertSuccess(job);
45+
46+
r.waitForMessage(
47+
"DEPRECATED: The 'Wipe out repository & force clone' extension is deprecated for Pipeline jobs. "
48+
+ "Pipeline users should use the deleteDir() step instead.",
49+
run
50+
);
51+
}
52+
}

0 commit comments

Comments
 (0)