-
-
Notifications
You must be signed in to change notification settings - Fork 8.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JENKINS-23786] Permit the Shell plugin to set a build result as unstable via a return code #2563
[JENKINS-23786] Permit the Shell plugin to set a build result as unstable via a return code #2563
Conversation
The CommandInterpreter.join(Proc p) method is supposed to be an extension point to allow an UNSTABLE build result to be set, but it has no access to the Build object with which to do so. Add a getBuild() method that returns the build passed to perform(...). A better API would be a new join(...) with more arguments, but that'd break out of tree plugins that might already be using this for other purposes.
Currently a shell job has to make a HTTP call back to Jenkins to set its build result as unstable. This is slow, requires the slave to have access to the master's HTTP interface, and is fiddly. The alternative, the TextFinder plugin, is no better. Instead, allow a job to set the build result to unstable with a return value. Adds the Advanced parameter "unstableReturn" which, if non-zero, is the code the script must return to set the build as unstable.
@@ -73,7 +84,13 @@ public String getDisplayName() { | |||
|
|||
@Override | |||
public Builder newInstance(StaplerRequest req, JSONObject data) { | |||
return new BatchFile(data.getString("command")); | |||
final String unstableReturnStr = data.getString("unstableReturn"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this even using newInstance
? Should just be databinding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed (hopefully) in next commit
@@ -40,10 +40,17 @@ | |||
*/ | |||
public class BatchFile extends CommandInterpreter { | |||
@DataBoundConstructor | |||
public BatchFile(String command) { | |||
public BatchFile(String command, Integer unstableReturn) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use of @DataboundSetter
for new arguments would be preferable over adding new constructors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed (hopefully) in next commit
* Useful for {@link #join(Proc p)} for setting build results. | ||
* | ||
* @return The build being run, or null if outside perform(...) | ||
* @since 1.573 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored
@@ -97,6 +118,7 @@ public boolean perform(AbstractBuild<?,?> build, Launcher launcher, TaskListener | |||
Util.displayIOException(e, listener); | |||
e.printStackTrace(listener.fatalError(Messages.CommandInterpreter_CommandFailed())); | |||
} | |||
this.build = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be in the finally
block?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored in next commit
@DataBoundConstructor | ||
public Shell(String command) { | ||
public Shell(String command, Integer unstableReturn) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See BatchFile
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed (hopefully) in next commit
@@ -28,4 +28,10 @@ THE SOFTWARE. | |||
description="${%description(rootURL)}"> | |||
<f:textarea name="command" value="${instance.command}" class="fixed-width" /> | |||
</f:entry> | |||
<f:advanced> | |||
<f:entry title="errorlevel to set build unstable" | |||
description="${%unstableReturn_description(rootURL)}"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No argument needed as there's no placeholder in the localized string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added help section and fixed in next commit
@@ -28,4 +28,10 @@ THE SOFTWARE. | |||
description="${%description(rootURL)}"> | |||
<f:textarea name="command" value="${instance.command}" class="fixed-width" /> | |||
</f:entry> | |||
<f:advanced> | |||
<f:entry title="errorlevel to set build unstable" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unclear why this isn't just using databinding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed (hopefully) in next commit
<f:advanced> | ||
<f:entry title="errorlevel to set build unstable" | ||
description="${%unstableReturn_description(rootURL)}"> | ||
<f:number clazz="positive-number" name="unstableReturn" value="${instance.unstableReturn}" min="1" max="255" step="1" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these min/max values universal?
|
||
f.advanced() { | ||
|
||
f.entry(title:_("Return code to set build unstable"), description:_("If set, the script return code that will be interpreted as an unstable build result.")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this inline, when the BatchFile
equivalent is in the view's default locale resource file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed (hopefully) in next commit
f.advanced() { | ||
|
||
f.entry(title:_("Return code to set build unstable"), description:_("If set, the script return code that will be interpreted as an unstable build result.")) { | ||
f.number(name: "unstableReturn", value: instance?.unstableReturn, min:1, max:255, step:1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where's the 'positive number' part present in BatchFile
's form? Not needed? Then why is it present there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed (hopefully) in next commit
Hi Daniel, thanks for review. I think the next commit should fix all requests. I'm not sure why one of the tests failed. I don't think the changes are related to this test. I need assistance from someone more experienced to get more understanding. |
@stochmial Legitimate failure. FindBugs complained as follows:
|
public Builder newInstance(StaplerRequest req, JSONObject data) { | ||
return new BatchFile(data.getString("command")); | ||
public Builder newInstance(StaplerRequest req, JSONObject formData) { | ||
return req.bindJSON(BatchFile.class,formData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the FindBugs issue since req
is CheckForNull.
Still not clear to me why this is even overridden. Doesn't the default Descriptor#newInstance(…)
do the exact same thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course this annotation could soon be obsolete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're getting really close here. Only few minor issues left IMO.
<div> | ||
If set, the batch errorlevel result that will be interpreted as an unstable build result. | ||
In WinNT4 and beyond, the ERRORLEVEL is stored as a Long - that is, a four byte, signed integer; | ||
yielding maximum and minimum values of 2147483647 and -2147483648, respectively. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are all of these values actually used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested a simple batch file with a single line: 'exit /b -2147483648' and the errorlevel is set to '-2147483648'. It works on win7, etc. I think it's better not to limit the available range, although hardly used.
@@ -0,0 +1,5 @@ | |||
<div> | |||
If set, the batch errorlevel result that will be interpreted as an unstable build result. | |||
In WinNT4 and beyond, the ERRORLEVEL is stored as a Long - that is, a four byte, signed integer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WinNT4? Why not Windows NT 4? Is that a common identifier of some kind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree this help text should be corrected. Not sure how much detail is needed here. I thought this text to be rather a hint than the complete documentation. How about:
"If set, the batch errorlevel result that will be interpreted as an unstable build result. If the final errorlevel matches the value, the build results will be set to unstable and next steps will be continued. Supported values match the widest errorlevel range for Windows like systems. In Windows NT4 and beyond the ERRORLEVEL is stored as a four byte, signed integer, yielding maximum and minimum values of 2147483647 and -2147483648, respectively. Older versions of Windows use 2 bytes. DOS like systems use single byte, yelding errorlevels between 0-255 ."
@@ -0,0 +1,3 @@ | |||
<div> | |||
If set, the shell exit code that will be interpreted as an unstable build result. On Unix-like systems the value between 0-255. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Second sentence missing its verb.
Also, seems overly terse, could use an explanation what this means. E.g. not aborting the build if that's the result, but continuing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about:
“If set, the shell exit code that will be interpreted as an unstable build result. If the exit code matches the value, the build results will be set to 'unstable' and next steps will be continued. On Unix-like it is a value between 0-255.”
@@ -64,6 +66,13 @@ public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListene | |||
return perform(build,launcher,(TaskListener)listener); | |||
} | |||
|
|||
/** | |||
* Allow the user to define a result for "unstable". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not actually describing what this does.
Missing @since TODO
.
@@ -28,4 +28,9 @@ THE SOFTWARE. | |||
description="${%description(rootURL)}"> | |||
<f:textarea name="command" value="${instance.command}" class="fixed-width" /> | |||
</f:entry> | |||
<f:advanced> | |||
<f:entry title="${%Errorlevel to set build unstable}" field="unstableReturn" > | |||
<f:number name="unstableReturn" value="${instance.unstableReturn}" min="-2147483648" max="2147483647" step="1" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is name
needed here, doesn't field
take care of this?
|
||
f.advanced() { | ||
f.entry(title:_("Exit code to set build unstable"), field: "unstableReturn") { | ||
f.number(clazz:"positive-number", name: "unstableReturn", value: instance?.unstableReturn, min:1, max:255, step:1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Form validation allows 0...255, while this has the range of 1...255, why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a general question if we should allow users to define exit code zero as an unstable build? I think better not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's start with 'no' and open up if there's an actual need for it.
/** | ||
* Performs on-the-fly validation of the exit code. | ||
*/ | ||
public FormValidation doCheckUnstableReturn(@QueryParameter String value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Restricted(DoNotUse.class)
wouldn't be a bad idea.
I didn't point them out individually, but a whole bunch of
|
All requests should be corrected. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor messaging issues, but otherwise okay 👍
@jenkinsci/code-reviewers Please review.
@@ -81,3 +83,5 @@ Maven.NotMavenDirectory={0} doesn\u2019t look like a Maven directory | |||
Maven.NoExecutable=Couldn\u2019t find any executable in {0} | |||
|
|||
Shell.DisplayName=Execute shell | |||
Shell.invalid_exit_code_range=Invalid exit code value: {0}. Check help section |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing trailing period.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure, because no messages there have periods in the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BatchFile.invalid_exit_code_range
has, so one of these is wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, fixed by removing all trailing periods.
@@ -81,3 +83,5 @@ Maven.NotMavenDirectory={0} doesn\u2019t look like a Maven directory | |||
Maven.NoExecutable=Couldn\u2019t find any executable in {0} | |||
|
|||
Shell.DisplayName=Execute shell | |||
Shell.invalid_exit_code_range=Invalid exit code value: {0}. Check help section | |||
Shell.invalid_exit_code_zero=Exit code zero is not allowed to make build unstable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Form validation does not prevent users from saving the form. I expect the '0' value to actually be saved. So, strongly discouraged, with explanation that it's never going to be successful perhaps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed from error to warning and added explanation in help message.
Is there anything else needed to finish this? I.e. sqashing my commits? I would rather leave rigerc commits as they are and squash only mine. |
@stochmial In the current state, I would definitely squash when merging, so to retain @ringerc's commits, that would be useful. But please wait to do that until the reviews are finished. |
Noticed that I have not submitted the previous review :( redoing it |
@oleg: I still don't see your review. |
@@ -56,6 +65,20 @@ protected String getFileExtension() { | |||
return ".bat"; | |||
} | |||
|
|||
public final Integer getUnstableReturn() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add CheckForNull.
🐜
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
return FormValidation.warning(hudson.tasks.Messages.BatchFile_invalid_exit_code_zero()); | ||
} | ||
if (unstableReturn < Integer.MIN_VALUE || unstableReturn > Integer.MAX_VALUE) { | ||
return FormValidation.error(hudson.tasks.Messages.BatchFile_invalid_exit_code_range(unstableReturn)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does Batch really support so wide return code range?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested a simple batch file with a single line: 'exit /b -2147483648' and the errorlevel is set to '-2147483648'. It works on win7, etc. I think it's better not to limit the available range, although hardly used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed
@@ -94,6 +102,20 @@ protected String getFileExtension() { | |||
return ".sh"; | |||
} | |||
|
|||
public final Integer getUnstableReturn() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CheckForNull
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test implementation needs fix
} | ||
|
||
@Issue("JENKINS-23786") | ||
public void testUnstableReturn() throws Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🐛 No @Test
annotation. JUnit 4 is not actually running this test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also add "Unix" to the test name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did.
b = rule.assertBuildStatus(Result.SUCCESS, p.scheduleBuild2(0).get()); | ||
|
||
/* Creating unstable=0 produces unstable=null */ | ||
assertNull( createNewShell("",0).getUnstableReturn() ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe needs splitting to several tests (or needs some comments)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I split and refactored tests.
|
||
@Issue("JENKINS-23786") | ||
public void testUnstableReturn() throws Exception { | ||
if(Functions.isWindows()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🐜 Should be assumeThat
in order to mark the test as skipped instead of passed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
} | ||
|
||
@Issue("JENKINS-23786") | ||
public void testUnstableReturn() throws Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same. Missing Test annotation and no assumeThat()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -28,4 +28,9 @@ THE SOFTWARE. | |||
description="${%description(rootURL)}"> | |||
<f:textarea name="command" value="${instance.command}" class="fixed-width" /> | |||
</f:entry> | |||
<f:advanced> | |||
<f:entry title="${%Errorlevel to set build unstable}" field="unstableReturn" > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to use ERRORLEVEL then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed 'Errorlevel' and 'ErrorLevel' to 'ERRORLEVEL' in all messageas.
@stochmial Done, sorry for the delay |
I refactored tests and verified they are triggered. |
Looks good to me 👍 |
@daniel-beck Are you fine with the revised version? |
@oleg-nenashev Code looks good, haven't run it for a while though. If @stochmial could commit to fixing followup issues during the next few weeks that would be great. |
I am ready to fix issues. I also added push permissions to all participants |
I can see all check finished successfully but the status still says 'Some checks haven’t completed yet'. An error in CI process? |
I suppose it's just another glitch on the new CI instance. Not sure in which weekly release it will land |
I would like to squash these 18 commits, but there are two authors => it can be done only manually |
7b5b040
to
33c3cae
Compare
I squashed my commits |
Thanks! Could you also update the commit message? Just to add issue prefix in order to let the SCM <=> JIRA integration to mark the issue properly? |
refactor and fix remove duplication and fix FB errors fix integration tests consistency fixes consistency fixes changed error message to warning fix comment and warning message fix comment fix junit tests fix junit tests fix junit tests fix junit tests clean import a commit to trigger jenkins checks
33c3cae
to
359548e
Compare
Done |
@oleg-nenashev But… the commit message wasn't updated to be bot compatible? |
Haha, my bad since I have not checked the new commit message :( |
Thanks for pushing this through. It's been two years since I wrote that
first little patch but I stopped using Jenkins (stability/reliability
issues with Matrix plugin + EC2-plugin) and didn't have a chance to pursue
it. It's nice to see you did it better and got it in. I'm about to return
to Jenkins for another project so it'll be nice to have.
|
Thanks all for support |
Continuation of the pull request: #1325