From de867d7594621acbd159f79e1d3a59c78e3d1f2f Mon Sep 17 00:00:00 2001 From: allancth Date: Sun, 29 Jan 2023 20:33:28 +0800 Subject: [PATCH] Add `includeBuildNumberInTargetPath` configuration parameter (#169) * Add parameter appendSrcNumberToTarget * Fix field name for appendSrcNumberToTarget * Unit test for parameter appendSrcNumberToTarget * Make help visible in freestyle project * Change parameter name to includeBuildNumberInTargetPath + update unit test * Update parameter name --------- Co-authored-by: Mark Waite --- README.adoc | 1 + .../plugins/copyartifact/CopyArtifact.java | 12 ++++++ .../copyartifact/CopyArtifact/config.jelly | 3 ++ .../CopyArtifact/config_de.properties | 4 +- .../CopyArtifact/config_ja.properties | 4 +- .../help-includeBuildNumberInTargetPath.html | 7 ++++ src/main/webapp/help-flatten-optional.html | 19 ++++++--- .../copyartifact/CopyArtifactTest.java | 42 ++++++++++++++++++- .../testutils/CopyArtifactUtil.java | 10 ++++- 9 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 src/main/resources/hudson/plugins/copyartifact/CopyArtifact/help-includeBuildNumberInTargetPath.html diff --git a/README.adoc b/README.adoc index 239816c8..ef1b6b60 100644 --- a/README.adoc +++ b/README.adoc @@ -65,6 +65,7 @@ using those artifacts. false for default if the parameter isn't specified (Snippet Generator defaults this to true and specifies the parameter). |resultVariableSuffix |boolean |useless for pipelines +|includeBuildNumberInTargetPath |boolean |Include source build number in target path. |=== * selectors + diff --git a/src/main/java/hudson/plugins/copyartifact/CopyArtifact.java b/src/main/java/hudson/plugins/copyartifact/CopyArtifact.java index 05153383..bede53c8 100644 --- a/src/main/java/hudson/plugins/copyartifact/CopyArtifact.java +++ b/src/main/java/hudson/plugins/copyartifact/CopyArtifact.java @@ -133,6 +133,7 @@ public class CopyArtifact extends Builder implements SimpleBuildStep { private String project; private String parameters; private String filter, target; + private boolean includeBuildNumberInTargetPath; private String excludes; private /*almost final*/ BuildSelector selector; @Deprecated private transient Boolean stable; @@ -201,6 +202,7 @@ public CopyArtifact(String projectName) { setOptional(false); setFingerprintArtifacts(false); setResultVariableSuffix(null); + setIncludeBuildNumberInTargetPath(false); } @DataBoundSetter @@ -233,6 +235,11 @@ public void setFlatten(boolean flatten) { this.flatten = flatten ? Boolean.TRUE : null; } + @DataBoundSetter + public void setIncludeBuildNumberInTargetPath(final boolean includeBuildNumberInTargetPath) { + this.includeBuildNumberInTargetPath = includeBuildNumberInTargetPath; + } + @DataBoundSetter public void setOptional(boolean optional) { this.optional = optional ? Boolean.TRUE : null; @@ -364,6 +371,10 @@ public String getResultVariableSuffix() { return resultVariableSuffix; } + public boolean getIncludeBuildNumberInTargetPath() { + return this.includeBuildNumberInTargetPath; + } + private boolean upgradeIfNecessary(AbstractProject job) throws IOException { if (isUpgradeNeeded()) { Jenkins jenkins = Jenkins.getInstanceOrNull(); @@ -501,6 +512,7 @@ public void perform(@NonNull Run build, @NonNull FilePath workspace, @NonN if (target.length() > 0) { targetDir = new FilePath(targetDir, env.expand(target)); } + if (this.includeBuildNumberInTargetPath) targetDir = new FilePath(targetDir, String.valueOf(src.getNumber())); expandedFilter = env.expand(filter); if (expandedFilter.trim().length() == 0) { expandedFilter = "**"; diff --git a/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/config.jelly b/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/config.jelly index c2748378..33087d7b 100644 --- a/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/config.jelly +++ b/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/config.jelly @@ -48,6 +48,9 @@ THE SOFTWARE. + + + diff --git a/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/config_de.properties b/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/config_de.properties index d70095ac..9853b6d4 100644 --- a/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/config_de.properties +++ b/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/config_de.properties @@ -4,4 +4,6 @@ Artifacts\ to\ copy=Zu kopierende Artefakte Target\ directory=Zielverzeichnis Flatten\ directories=Verzeichnisse reduzieren Fingerprint\ Artifacts=Fingerabdr\u00fccke von Artefakten erstellen -Optional=Optional \ No newline at end of file +Optional=Optional +Fingerprint\ Artifacts= +Include\ Build\ Number= \ No newline at end of file diff --git a/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/config_ja.properties b/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/config_ja.properties index 4bf5f750..1d9959f5 100644 --- a/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/config_ja.properties +++ b/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/config_ja.properties @@ -4,4 +4,6 @@ Artifacts\ to\ copy=\u30B3\u30D4\u30FC\u3059\u308B\u6210\u679C\u7269 Artifacts\ not\ to\ copy=\u30b3\u30d4\u30fc\u3057\u306a\u3044\u6210\u679c\u7269 Target\ directory=\u30B3\u30D4\u30FC\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA Flatten\ directories=\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u69CB\u9020\u3092\u7121\u8996 -Optional=\u30AA\u30D7\u30B7\u30E7\u30F3 \ No newline at end of file +Optional=\u30AA\u30D7\u30B7\u30E7\u30F3 +Fingerprint\ Artifacts= +Include\ Build\ Number= \ No newline at end of file diff --git a/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/help-includeBuildNumberInTargetPath.html b/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/help-includeBuildNumberInTargetPath.html new file mode 100644 index 00000000..2f0c35af --- /dev/null +++ b/src/main/resources/hudson/plugins/copyartifact/CopyArtifact/help-includeBuildNumberInTargetPath.html @@ -0,0 +1,7 @@ +
+ Include build number in target path. Default is false. +

+ When true, the build number of the source project will be included in the target path. + This is particularly useful when the selector is specific and the value is a permalink, e.g. lastSuccessfulBuild. +

+
diff --git a/src/main/webapp/help-flatten-optional.html b/src/main/webapp/help-flatten-optional.html index 0035bc32..537407be 100644 --- a/src/main/webapp/help-flatten-optional.html +++ b/src/main/webapp/help-flatten-optional.html @@ -1,14 +1,23 @@
- Select "Flatten directories" to ignore the directory structure of the artifacts +

+ Select "Flatten directories" to ignore the directory structure of the artifacts in the source project and copy all matching artifacts directly into the specified target directory. By default the artifacts are copied in the same directory structure as the source project. -

- Select "Optional" to allow this build to continue even if no build is found +

+

+ Select "Optional" to allow this build to continue even if no build is found matching the "Which build" condition selected above, the build's workspace does not exist or is inaccessible, or no artifacts are found matching the specified pattern. By default this build step fails the build if no artifacts are copied. -

- Select "Fingerprint Artifacts" to automatically fingerprint all artifacts +

+

+ Select "Fingerprint Artifacts" to automatically fingerprint all artifacts that are copied as part of this build step. +

+

+ Select "Include Build Number" to include the source build number in the target path. + When true, the build number of the source project will be included in the target path. + This is particularly useful when the selector is specific and the value is a permalink, e.g. lastSuccessfulBuild. +

diff --git a/src/test/java/hudson/plugins/copyartifact/CopyArtifactTest.java b/src/test/java/hudson/plugins/copyartifact/CopyArtifactTest.java index 9d7697e0..717786f8 100644 --- a/src/test/java/hudson/plugins/copyartifact/CopyArtifactTest.java +++ b/src/test/java/hudson/plugins/copyartifact/CopyArtifactTest.java @@ -2249,7 +2249,47 @@ public void testIsValidVariableName() throws Exception { assertFalse(CopyArtifact.isValidVariableName(" ")); assertFalse(CopyArtifact.isValidVariableName("=/?!\"")); } - + + @Test + public void testIncludeBuildNumberToTargetPath() throws Exception { + final Builder failureBuilder = new FailureBuilder(); + final FreeStyleProject srcProject = createArtifactProject("SRC-PROJECT"); + + srcProject.getBuildersList().add(failureBuilder); + final FreeStyleBuild build1 = srcProject.scheduleBuild2(0).get(); + rule.assertBuildStatus(Result.FAILURE, build1); + + srcProject.getBuildersList().remove(failureBuilder); + final FreeStyleBuild build2 = srcProject.scheduleBuild2(0).get(); + rule.assertBuildStatus(Result.SUCCESS, build2); + + srcProject.getBuildersList().add(failureBuilder); + final FreeStyleBuild build3 = srcProject.scheduleBuild2(0).get(); + rule.assertBuildStatus(Result.FAILURE, build3); + + { + FreeStyleProject p = rule.createFreeStyleProject(); + p.getBuildersList().add(CopyArtifactUtil.createCopyArtifact( + srcProject.getFullName(), + null, // parameters + new SpecificBuildSelector("lastSuccessfulBuild"), + "", // filter + "", // excludes + "", // target + false, // flatten + false, // optional + true, // fingerprintArtifacts + "", // resultVariableSuffix + true // includeBuildNumberInTargetPath + )); + rule.assertBuildStatusSuccess(p.scheduleBuild2(0)); + + assertFalse(new FilePath(p.getWorkspace(), "1").exists()); + assertTrue(new FilePath(p.getWorkspace(), "2").exists()); + assertFalse(new FilePath(p.getWorkspace(), "3").exists()); + } + } + @Test public void testResultVariableSuffix() throws Exception { FreeStyleProject srcProject = createArtifactProject("SRC-PROJECT1"); diff --git a/src/test/java/hudson/plugins/copyartifact/testutils/CopyArtifactUtil.java b/src/test/java/hudson/plugins/copyartifact/testutils/CopyArtifactUtil.java index 91e82683..d4a7a95a 100644 --- a/src/test/java/hudson/plugins/copyartifact/testutils/CopyArtifactUtil.java +++ b/src/test/java/hudson/plugins/copyartifact/testutils/CopyArtifactUtil.java @@ -48,9 +48,14 @@ public static CopyArtifact createCopyArtifact(String projectName, String paramet boolean flatten, boolean optional, boolean fingerprintArtifacts) { return createCopyArtifact(projectName, parameters, selector, filter, excludes, target, flatten, optional, fingerprintArtifacts, null); } - + + public static CopyArtifact createCopyArtifact(String projectName, String parameters, BuildSelector selector, String filter, String excludes, String target, + boolean flatten, boolean optional, boolean fingerprintArtifacts, String resultVariableSuffix) { + return createCopyArtifact(projectName, parameters, selector, filter, excludes, target, flatten, optional, fingerprintArtifacts, resultVariableSuffix, false); + } + public static CopyArtifact createCopyArtifact(String projectName, String parameters, BuildSelector selector, String filter, String excludes, String target, - boolean flatten, boolean optional, boolean fingerprintArtifacts, String resultVariableSuffix) { + boolean flatten, boolean optional, boolean fingerprintArtifacts, String resultVariableSuffix, boolean includeBuildNumberInTargetPath) { CopyArtifact copyArtifact = new CopyArtifact(projectName); copyArtifact.setParameters(parameters); copyArtifact.setSelector(selector); @@ -61,6 +66,7 @@ public static CopyArtifact createCopyArtifact(String projectName, String paramet copyArtifact.setOptional(optional); copyArtifact.setFingerprintArtifacts(fingerprintArtifacts); copyArtifact.setResultVariableSuffix(resultVariableSuffix); + copyArtifact.setIncludeBuildNumberInTargetPath(includeBuildNumberInTargetPath); return copyArtifact; } }