();
24 |
25 | private static final Logger LOGGER = Logger.getLogger(EnvironmentVarSetter.class.getName());
26 |
27 | public static final String buildDisplayNameVar = "BUILD_DISPLAY_NAME";
28 |
29 | public EnvironmentVarSetter(@CheckForNull String key, @CheckForNull String value, @CheckForNull PrintStream logger) {
30 | log = logger;
31 | envVars.put(key, value);
32 | }
33 |
34 | public static void setVar(AbstractBuild build, String key, String value, PrintStream logger) {
35 | EnvironmentVarSetter action = build.getAction(EnvironmentVarSetter.class);
36 | if (action == null) {
37 | action = new EnvironmentVarSetter(key, value, logger);
38 | build.addAction(action);
39 | } else {
40 | action.setVar(key, value);
41 | }
42 | }
43 |
44 | public void setVar(@CheckForNull String key, @CheckForNull String value) {
45 | if (StringUtils.isBlank(key)) {
46 | throw new IllegalArgumentException("key shouldn't be null or empty.");
47 | }
48 | if (StringUtils.isBlank(value)) {
49 | throw new IllegalArgumentException("value shouldn't be null or empty.");
50 | }
51 |
52 | if (envVars.containsKey(key)) {
53 | if (!envVars.get(key).equals(value)) {
54 | log("Variable with name '%s' already exists, current value: '%s', new value: '%s'",
55 | key, envVars.get(key), value);
56 | }
57 | } else {
58 | log("Create new variable %s=%s", key, value);
59 | }
60 |
61 | envVars.put(key, value);
62 | }
63 |
64 | public String getVar(String key) {
65 | if (envVars.containsKey(key)) {
66 | log("Get var: %s=%s", key, envVars.get(key));
67 | return envVars.get(key);
68 | } else {
69 | log("Var '%s' doesn't exist", key);
70 | return "";
71 | }
72 | }
73 |
74 | private void log(String format, Object... args) {
75 | if (log == null && !LOGGER.isLoggable(Level.FINE)) { // not loggable
76 | return;
77 | }
78 |
79 | String message = format.formatted(args);
80 | LOGGER.fine(message);
81 | if (log != null) {
82 | log.println(message);
83 | }
84 | }
85 |
86 | @Override
87 | public void buildEnvVars(AbstractBuild, ?> abstractBuild, EnvVars envVars) {
88 | envVars.putAll(this.envVars);
89 | }
90 |
91 | @Override
92 | public String getIconFileName() {
93 | return null;
94 | }
95 |
96 | @Override
97 | public String getDisplayName() {
98 | return null;
99 | }
100 |
101 | @Override
102 | public String getUrlName() {
103 | return null;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/buildnamesetter/BuildNameSetter.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.buildnamesetter;
2 |
3 | import static org.apache.commons.lang.BooleanUtils.toBooleanDefaultIfNull;
4 |
5 | import java.io.IOException;
6 |
7 | import hudson.Extension;
8 | import hudson.Launcher;
9 | import hudson.matrix.MatrixAggregatable;
10 | import hudson.matrix.MatrixAggregator;
11 | import hudson.matrix.MatrixBuild;
12 | import hudson.model.AbstractBuild;
13 | import hudson.model.AbstractProject;
14 | import hudson.model.BuildListener;
15 | import hudson.tasks.BuildWrapper;
16 | import hudson.tasks.BuildWrapperDescriptor;
17 | import org.kohsuke.stapler.DataBoundConstructor;
18 | import org.kohsuke.stapler.DataBoundSetter;
19 |
20 | /**
21 | * Sets the build name at two configurable points during the build.
22 | *
23 | * Once early on in the build, and another time later on.
24 | *
25 | * @author Kohsuke Kawaguchi
26 | */
27 | public class BuildNameSetter extends BuildWrapper implements MatrixAggregatable {
28 |
29 | private String template;
30 | private String descriptionTemplate;
31 | private Boolean runAtStart = true;
32 | private Boolean runAtEnd = true;
33 |
34 | @DataBoundConstructor
35 | public BuildNameSetter(String template, Boolean runAtStart, Boolean runAtEnd) {
36 | // attribute is named differently than parameter that must be backwards compatible
37 | this.template = template;
38 | this.runAtStart = toBooleanDefaultIfNull(runAtStart, true);
39 | this.runAtEnd = toBooleanDefaultIfNull(runAtEnd, true);
40 | }
41 |
42 | @DataBoundSetter
43 | public void setDescriptionTemplate(String descriptionTemplate) {
44 | this.descriptionTemplate = descriptionTemplate;
45 | }
46 |
47 | public String getDescriptionTemplate() {
48 | return descriptionTemplate;
49 | }
50 |
51 | @DataBoundSetter
52 | public void setTemplate(String template) {
53 | this.template = template;
54 | }
55 |
56 | public String getTemplate() {
57 | return template;
58 | }
59 |
60 | public Boolean getRunAtStart() {
61 | return runAtStart;
62 | }
63 |
64 | public Boolean getRunAtEnd() {
65 | return runAtEnd;
66 | }
67 |
68 | protected Object readResolve() {
69 | if (runAtStart == null) {
70 | runAtStart = true;
71 | }
72 | if (runAtEnd == null) {
73 | runAtEnd = true;
74 | }
75 | return this;
76 | }
77 |
78 | @Override
79 | public Environment setUp(AbstractBuild build, Launcher launcher, BuildListener listener) {
80 |
81 | Executor executor = new Executor(build, listener);
82 |
83 | if (runAtStart) {
84 | executor.setName(template);
85 | executor.setDescription(descriptionTemplate);
86 | }
87 |
88 | return new Environment() {
89 | @Override
90 | public boolean tearDown(AbstractBuild build, BuildListener listener) {
91 | if (runAtEnd) {
92 | executor.setName(template);
93 | executor.setDescription(descriptionTemplate);
94 | }
95 | return true;
96 | }
97 | };
98 | }
99 |
100 |
101 | // support for matrix project
102 | public MatrixAggregator createAggregator(MatrixBuild build, Launcher launcher, BuildListener listener) {
103 |
104 | Executor executor = new Executor(build, listener);
105 |
106 | return new MatrixAggregator(build, launcher, listener) {
107 | @Override
108 | public boolean startBuild() throws InterruptedException, IOException {
109 | executor.setName(template);
110 | executor.setDescription(descriptionTemplate);
111 |
112 | return super.startBuild();
113 | }
114 |
115 | @Override
116 | public boolean endBuild() throws InterruptedException, IOException {
117 | executor.setName(template);
118 | executor.setDescription(descriptionTemplate);
119 |
120 | return super.endBuild();
121 | }
122 | };
123 | }
124 |
125 | @Extension
126 | public static class DescriptorImpl extends BuildWrapperDescriptor {
127 | @Override
128 | public boolean isApplicable(AbstractProject, ?> item) {
129 | return true;
130 | }
131 |
132 | @Override
133 | public String getDisplayName() {
134 | return "Set Build Name";
135 | }
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/buildnamesetter/Executor.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.buildnamesetter;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 |
6 | import hudson.FilePath;
7 | import hudson.model.AbstractBuild;
8 | import hudson.model.Run;
9 | import hudson.model.TaskListener;
10 | import org.apache.commons.lang.StringUtils;
11 | import org.jenkinsci.plugins.EnvironmentVarSetter;
12 | import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException;
13 | import org.jenkinsci.plugins.tokenmacro.TokenMacro;
14 |
15 | /**
16 | * @author Damian Szczepanik (damianszczepanik@github)
17 | */
18 | public class Executor {
19 |
20 | private final Run run;
21 | private final TaskListener listener;
22 |
23 | public Executor(Run run, TaskListener listener) {
24 | this.run = run;
25 | this.listener = listener;
26 | }
27 |
28 | public void setName(String nameTemplate) {
29 | try {
30 | String name = evaluateMacro(nameTemplate);
31 | listener.getLogger().println("New run name is '" + name + "'");
32 | run.setDisplayName(name);
33 | setVariable(nameTemplate);
34 | } catch (IOException e) {
35 | listener.error(e.getMessage());
36 | } catch (MacroEvaluationException e) {
37 | // should be marked as failure but then many configuration
38 | // that work with older version of the plugin will fail
39 | listener.getLogger().println("Failed to evaluate name macro:" + e.toString());
40 | }
41 | }
42 |
43 | public void setDescription(String descriptionTemplate) {
44 | // skip when the description is not provided (because plugin was updated but configuration not)
45 | if (StringUtils.isEmpty(descriptionTemplate)) {
46 | return;
47 | }
48 |
49 | try {
50 | String description = evaluateMacro(descriptionTemplate);
51 | listener.getLogger().println("New run description is '" + description + "'");
52 | run.setDescription(description);
53 | } catch (IOException e) {
54 | listener.error(e.getMessage());
55 | } catch (MacroEvaluationException e) {
56 | // should be marked as failure but then many configuration
57 | // that work with older version of the plugin will fail
58 | listener.getLogger().println("Failed to evaluate description macro:" + e.toString());
59 | }
60 | }
61 |
62 | public void setVariable(String nameTemplate) throws MacroEvaluationException {
63 | if (run instanceof AbstractBuild abstractBuild) {
64 | EnvironmentVarSetter.setVar(abstractBuild, EnvironmentVarSetter.buildDisplayNameVar,
65 | evaluateMacro(nameTemplate), listener.getLogger());
66 | }
67 | }
68 |
69 | public String evaluateMacro(String template) throws MacroEvaluationException {
70 | try {
71 | File workspace = run.getRootDir();
72 | return TokenMacro.expandAll(run, new FilePath(workspace), listener, template);
73 | } catch (InterruptedException | IOException e) {
74 | throw new IllegalArgumentException(e);
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/buildnameupdater/BuildNameUpdater.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.buildnameupdater;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileReader;
6 | import java.io.IOException;
7 | import java.nio.charset.StandardCharsets;
8 | import java.util.logging.Level;
9 | import java.util.logging.Logger;
10 |
11 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
12 | import hudson.Extension;
13 | import hudson.FilePath;
14 | import hudson.Launcher;
15 | import hudson.model.AbstractBuild;
16 | import hudson.model.AbstractProject;
17 | import hudson.model.BuildListener;
18 | import hudson.remoting.VirtualChannel;
19 | import hudson.tasks.BuildStepDescriptor;
20 | import hudson.tasks.Builder;
21 | import hudson.util.FormValidation;
22 | import jenkins.MasterToSlaveFileCallable;
23 | import org.apache.commons.lang.StringUtils;
24 | import org.jenkinsci.plugins.buildnamesetter.Executor;
25 | import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException;
26 | import org.jenkinsci.plugins.tokenmacro.TokenMacro;
27 | import org.kohsuke.stapler.DataBoundConstructor;
28 | import org.kohsuke.stapler.QueryParameter;
29 |
30 | /**
31 | * This plugin replace the build name with the first line from a file on a slave.
32 | *
33 | * @author Lev Mishin
34 | */
35 | public class BuildNameUpdater extends Builder {
36 |
37 | private final String buildName;
38 | private final String macroTemplate;
39 | private final boolean fromFile;
40 | private final boolean fromMacro;
41 | private final boolean macroFirst;
42 |
43 | private static final Logger LOGGER = Logger.getLogger(BuildNameUpdater.class.getName());
44 |
45 | // Fields in config.jelly must match the parameter names in the "DataBoundConstructor"
46 | @DataBoundConstructor
47 | public BuildNameUpdater(boolean fromFile, String buildName, boolean fromMacro, String macroTemplate, boolean macroFirst) {
48 | this.buildName = buildName;
49 | this.macroTemplate = macroTemplate;
50 | this.fromFile = fromFile;
51 | this.fromMacro = fromMacro;
52 | this.macroFirst = macroFirst;
53 | }
54 |
55 | @SuppressWarnings("unused")
56 | public boolean getFromFile() {
57 | return fromFile;
58 | }
59 |
60 | @SuppressWarnings("unused")
61 | public boolean getMacroFirst() {
62 | return macroFirst;
63 | }
64 |
65 | @SuppressWarnings("unused")
66 | public boolean getFromMacro() {
67 | return fromMacro;
68 | }
69 |
70 | @SuppressWarnings("unused")
71 | public String getBuildName() {
72 | return buildName;
73 | }
74 |
75 | @SuppressWarnings("unused")
76 | public String getMacroTemplate() {
77 | return macroTemplate;
78 | }
79 |
80 | @Override
81 | public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) {
82 | String buildNameToSet = "";
83 |
84 | if (fromFile) {
85 | buildNameToSet = readFromFile(build, listener, buildName);
86 | }
87 |
88 | if (fromMacro) {
89 | String evaluatedMacro = getFromMacro(build, listener, macroTemplate);
90 |
91 | listener.getLogger().println("Evaluated macro: '" + evaluatedMacro + "'");
92 |
93 | buildNameToSet = macroFirst ? evaluatedMacro + buildNameToSet : buildNameToSet + evaluatedMacro;
94 | }
95 |
96 | if (StringUtils.isNotBlank(buildNameToSet)) {
97 | Executor executor = new Executor(build, listener);
98 | executor.setName(buildNameToSet);
99 | }
100 |
101 | return true;
102 | }
103 |
104 | private String getFromMacro(AbstractBuild build, BuildListener listener, String macro) {
105 | String result = null;
106 | try {
107 | result = TokenMacro.expandAll(build, listener, macro);
108 | } catch (MacroEvaluationException e) {
109 | listener.getLogger().println("Failed to evaluate macro '" + macro + "'");
110 | LOGGER.log(Level.WARNING, "Failed to evaluate macro '" + macro + "': ", e);
111 | } catch (IOException e) {
112 | LOGGER.log(Level.WARNING, "Exception was thrown during macro evaluation: ", e);
113 | } catch (InterruptedException e) {
114 | LOGGER.log(Level.WARNING, "Macro evaluation was interrupted: ", e);
115 | listener.getLogger().println("Macro evaluating failed with:");
116 | }
117 | LOGGER.log(Level.INFO, "Macro evaluated: '" + result + "'");
118 | return result;
119 | }
120 |
121 | private String readFromFile(AbstractBuild build, BuildListener listener, String filePath) {
122 | String version = "";
123 |
124 | if (StringUtils.isBlank(filePath)) {
125 | listener.getLogger().println("File path is empty.");
126 | return "";
127 | }
128 |
129 | FilePath workspace = build.getWorkspace();
130 | if (workspace == null) {
131 | listener.getLogger().println("Workspace is empty.");
132 | return "";
133 | }
134 | FilePath fp = new FilePath(workspace, filePath);
135 |
136 | listener.getLogger().println("Getting version from file: " + fp);
137 |
138 | try {
139 | version = fp.act(new FileCallable());
140 | } catch (IOException e) {
141 | LOGGER.log(Level.WARNING, "Failed to read file: ", e);
142 | } catch (InterruptedException e) {
143 | LOGGER.log(Level.WARNING, "Getting name from file was interrupted: ", e);
144 | }
145 |
146 | listener.getLogger().println("Loaded version is " + version);
147 | return StringUtils.defaultString(version);
148 | }
149 |
150 | @Override
151 | public DescriptorImpl getDescriptor() {
152 | return (DescriptorImpl) super.getDescriptor();
153 | }
154 |
155 | private static class FileCallable extends MasterToSlaveFileCallable {
156 | private static final long serialVersionUID = 1L;
157 |
158 | @Override
159 | public String invoke(File file, VirtualChannel channel) throws IOException {
160 | if (file.getAbsoluteFile().exists()) {
161 | LOGGER.log(Level.INFO, "File is found, reading...");
162 | try (BufferedReader br = new BufferedReader(
163 | new FileReader(file.getAbsoluteFile(), StandardCharsets.UTF_8))) {
164 | return br.readLine();
165 | }
166 | } else {
167 | LOGGER.log(Level.WARNING, "File was not found.");
168 | return "";
169 | }
170 | }
171 | }
172 |
173 | @Extension // This indicates to Jenkins that this is an implementation of an extension point.
174 | public static final class DescriptorImpl extends BuildStepDescriptor {
175 | public DescriptorImpl() {
176 | load();
177 | }
178 |
179 | @SuppressWarnings("unused")
180 | public FormValidation doCheckName(@QueryParameter String value) {
181 | if (value.isEmpty())
182 | return FormValidation.error("Please set a file path");
183 | return FormValidation.ok();
184 | }
185 |
186 | public boolean isApplicable(Class extends AbstractProject> jobType) {
187 | return true;
188 | }
189 |
190 | public String getDisplayName() {
191 | return "Update build name";
192 | }
193 | }
194 | }
195 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/pipeline/BuildDescriptionStep.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.pipeline;
2 |
3 | import hudson.Extension;
4 | import hudson.FilePath;
5 | import hudson.Launcher;
6 | import hudson.model.AbstractProject;
7 | import hudson.model.Run;
8 | import hudson.model.TaskListener;
9 | import hudson.tasks.BuildStepDescriptor;
10 | import hudson.tasks.Builder;
11 | import jenkins.tasks.SimpleBuildStep;
12 | import org.jenkinsci.Symbol;
13 | import org.jenkinsci.plugins.buildnamesetter.Executor;
14 | import org.kohsuke.stapler.DataBoundConstructor;
15 |
16 | /**
17 | * @author Damian Szczepanik (damianszczepanik@github)
18 | */
19 | public class BuildDescriptionStep extends Builder implements SimpleBuildStep {
20 |
21 | private final String descriptionTemplate;
22 |
23 | @DataBoundConstructor
24 | public BuildDescriptionStep(String descriptionTemplate) {
25 | this.descriptionTemplate = descriptionTemplate;
26 | }
27 |
28 | public String getDescriptionTemplate() {
29 | return descriptionTemplate;
30 | }
31 |
32 | @Override
33 | public void perform(Run run, FilePath workspace, Launcher launcher, TaskListener listener) {
34 | Executor executor = new Executor(run, listener);
35 | executor.setDescription(descriptionTemplate);
36 | }
37 |
38 | @Symbol("buildDescription")
39 | @Extension
40 | public static class DescriptorImpl extends BuildStepDescriptor {
41 |
42 | @Override
43 | public String getDisplayName() {
44 | return "Changes build description";
45 | }
46 |
47 | @Override
48 | public boolean isApplicable(Class extends AbstractProject> t) {
49 | return true;
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/pipeline/BuildNameStep.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.pipeline;
2 |
3 | import hudson.Extension;
4 | import hudson.FilePath;
5 | import hudson.Launcher;
6 | import hudson.model.AbstractProject;
7 | import hudson.model.Run;
8 | import hudson.model.TaskListener;
9 | import hudson.tasks.BuildStepDescriptor;
10 | import hudson.tasks.Builder;
11 | import jenkins.tasks.SimpleBuildStep;
12 | import org.jenkinsci.Symbol;
13 | import org.jenkinsci.plugins.buildnamesetter.Executor;
14 | import org.kohsuke.stapler.DataBoundConstructor;
15 |
16 | /**
17 | * @author Damian Szczepanik (damianszczepanik@github)
18 | */
19 | public class BuildNameStep extends Builder implements SimpleBuildStep {
20 |
21 | private final String nameTemplate;
22 |
23 | @DataBoundConstructor
24 | public BuildNameStep(String nameTemplate) {
25 | this.nameTemplate = nameTemplate;
26 | }
27 |
28 | public String getNameTemplate() {
29 | return nameTemplate;
30 | }
31 |
32 | @Override
33 | public void perform(Run run, FilePath workspace, Launcher launcher, TaskListener listener) {
34 | Executor executor = new Executor(run, listener);
35 | executor.setName(nameTemplate);
36 | }
37 |
38 | @Symbol("buildName")
39 | @Extension
40 | public static class DescriptorImpl extends BuildStepDescriptor {
41 |
42 | @Override
43 | public String getDisplayName() {
44 | return "Changes build name";
45 | }
46 |
47 | @Override
48 | public boolean isApplicable(Class extends AbstractProject> t) {
49 | return true;
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/src/main/resources/index.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 | This plug-in sets the display name and description of a build to something other than #1, #2, #3, ...
4 |
5 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/buildnamesetter/BuildNameSetter/config.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/buildnamesetter/BuildNameSetter/help-template.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 | Normally, builds are named by their sequential numbers, but you can change that here by
4 | setting what name new build gets. This field can contain the following macros:
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/buildnamesetter/BuildNameSetter/help.html:
--------------------------------------------------------------------------------
1 |
2 | Normally, builds are named by their sequential numbers, but you can change name and description to something
3 | more meaningful to you in the context of this job.
4 |
5 |
6 | The update actually happens twice during the build; once right after the check out, and once before the build is
7 | completed. So depending on the macro you use, you might not see the complete value until your build completes.
8 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/buildnameupdater/BuildNameUpdater/config.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/buildnameupdater/BuildNameUpdater/help-buildName.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 | This field could contain relative path to the file
4 | with build name from the build workspace.
5 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/buildnameupdater/BuildNameUpdater/help-macroFirst.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 | Normally build name consists of [file content]+[macro],
4 |
5 | this option reverses the order i.e. [macro]+[file content].
6 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/buildnameupdater/BuildNameUpdater/help-macroTemplate.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 | This field can contain the following macros:
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/buildnameupdater/BuildNameUpdater/help.html:
--------------------------------------------------------------------------------
1 |
2 | This plugin updates build name and description during the build process. Values to set could be stored in a file
3 | in the build workspace or in an environment variable.
4 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/pipeline/BuildDescriptionStep/config.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/pipeline/BuildDescriptionStep/help.html:
--------------------------------------------------------------------------------
1 |
2 | Normally, build description is empty, but it can be changed by
3 | setting what name new build gets. This field can contain
4 |
macros.
5 |
6 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/pipeline/BuildNameStep/config.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/pipeline/BuildNameStep/help.html:
--------------------------------------------------------------------------------
1 |
2 | Normally, builds are named by their sequential numbers, but you can change that here by
3 | setting what name new build gets. This field can contain
4 |
macros.
5 |
6 |
--------------------------------------------------------------------------------
/src/test/java/org/jenkinsci/plugins/buildnamesetter/BuildNameSetterTest.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.buildnamesetter;
2 |
3 | import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
4 | import static org.junit.jupiter.api.Assertions.assertEquals;
5 |
6 | import hudson.EnvVars;
7 | import hudson.model.FreeStyleBuild;
8 | import hudson.model.FreeStyleProject;
9 | import hudson.model.Result;
10 | import hudson.model.TaskListener;
11 | import org.jenkinsci.plugins.EnvironmentVarSetter;
12 | import org.junit.jupiter.api.Test;
13 | import org.jvnet.hudson.test.Issue;
14 | import org.jvnet.hudson.test.JenkinsRule;
15 | import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
16 |
17 | @WithJenkins
18 | class BuildNameSetterTest {
19 |
20 | @Test
21 | void shouldExpand_BUILD_NUMBER_macro(JenkinsRule jenkins) throws Exception {
22 | FreeStyleProject fooProj = jenkins.createFreeStyleProject("foo");
23 | fooProj.getBuildWrappersList().add(getDefaultSetter("a_#${BUILD_NUMBER}"));
24 |
25 | FreeStyleBuild fooBuild = fooProj.scheduleBuild2(0).get();
26 | assertDisplayName(fooBuild, "a_#1");
27 | }
28 |
29 | @Test
30 | void shouldExpand_JOB_NAME_full_env_macro(JenkinsRule jenkins) throws Exception {
31 | FreeStyleProject barProj = jenkins.createFreeStyleProject("bar");
32 | barProj.getBuildWrappersList().add(getDefaultSetter("b_${ENV,var=\"JOB_NAME\"}"));
33 |
34 | FreeStyleBuild barBuild = barProj.scheduleBuild2(0).get();
35 | assertDisplayName(barBuild, "b_bar");
36 | }
37 |
38 | @Issue("13347")
39 | @Test
40 | void shouldExpand_JOB_NAME_macro(JenkinsRule jenkins) throws Exception {
41 | FreeStyleProject barProj = jenkins.createFreeStyleProject("bar");
42 | barProj.getBuildWrappersList().add(getDefaultSetter("c_${JOB_NAME}"));
43 |
44 | FreeStyleBuild barBuild = barProj.scheduleBuild2(0).get();
45 | assertDisplayName(barBuild, "c_bar");
46 | }
47 |
48 | @Issue("13347")
49 | @Test
50 | void shouldExpand_JOB_NAME_macro_twice(JenkinsRule jenkins) throws Exception {
51 | FreeStyleProject barProj = jenkins.createFreeStyleProject("bar");
52 | barProj.getBuildWrappersList().add(getDefaultSetter("c_${JOB_NAME}_d_${JOB_NAME}"));
53 |
54 | FreeStyleBuild barBuild = barProj.scheduleBuild2(0).get();
55 | assertDisplayName(barBuild, "c_bar_d_bar");
56 | }
57 |
58 | @Issue("13347")
59 | @Test
60 | void shouldExpand_NODE_NAME_macro_and_JOB_NAME_full_env_macro(JenkinsRule jenkins) throws Exception {
61 | FreeStyleProject fooProj = jenkins.createFreeStyleProject("foo");
62 | fooProj.getBuildWrappersList().add(getDefaultSetter("d_${NODE_NAME}_${ENV,var=\"JOB_NAME\"}"));
63 |
64 | FreeStyleBuild fooBuild = fooProj.scheduleBuild2(0).get();
65 | assertDisplayName(fooBuild, "d_built-in_foo");
66 | }
67 |
68 | @Issue("34181")
69 | @Test
70 | void shouldUse_default_config_values_if_null(JenkinsRule jenkins) throws Exception {
71 | FreeStyleProject fooProj = jenkins.createFreeStyleProject("foo");
72 | fooProj.getBuildWrappersList().add(new BuildNameSetter("${ENV,var=\"JOB_NAME\"}", null, null));
73 |
74 | FreeStyleBuild fooBuild = fooProj.scheduleBuild2(0).get();
75 | assertDisplayName(fooBuild, "foo");
76 | }
77 |
78 | private static void assertDisplayName(FreeStyleBuild build, String expectedName) {
79 | assertEquals(Result.SUCCESS, build.getResult());
80 | assertEquals(expectedName, build.getDisplayName());
81 | EnvironmentVarSetter action = build.getAction(EnvironmentVarSetter.class);
82 | assertEquals(expectedName, action.getVar(EnvironmentVarSetter.buildDisplayNameVar));
83 | EnvVars envVars = assertDoesNotThrow(
84 | () -> build.getEnvironment(TaskListener.NULL),
85 | "Exception was thrown during getting build environment");
86 | assertEquals(expectedName, envVars.get(EnvironmentVarSetter.buildDisplayNameVar));
87 | }
88 |
89 | private static BuildNameSetter getDefaultSetter(String template) {
90 | return new BuildNameSetter(template, true, true);
91 | }
92 | }
93 |
--------------------------------------------------------------------------------