Skip to content
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

Bring PowerShell on par with BatchFile by supporting unstable builds #14

Merged
merged 1 commit into from
Oct 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions src/main/java/hudson/plugins/powershell/PowerShell.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
import hudson.tasks.Builder;
import hudson.tasks.CommandInterpreter;
import jenkins.model.Jenkins;
import javax.annotation.CheckForNull;
import org.apache.commons.lang.SystemUtils;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

import java.io.IOException;

Expand All @@ -23,15 +25,18 @@ public class PowerShell extends CommandInterpreter {
/** boolean switch setting -NoProfile */
private final boolean useProfile;

private Integer unstableReturn;

private final boolean stopOnError;

private transient TaskListener listener;

@DataBoundConstructor
public PowerShell(String command, boolean stopOnError, boolean useProfile) {
public PowerShell(String command, boolean stopOnError, boolean useProfile, Integer unstableReturn) {
super(command);
this.stopOnError = stopOnError;
this.useProfile = useProfile;
this.unstableReturn = unstableReturn;
}

@Override
Expand Down Expand Up @@ -61,7 +66,21 @@ protected String getFileExtension() {
return ".ps1";
}

@CheckForNull
public final Integer getUnstableReturn() {
return Integer.valueOf(0).equals(unstableReturn) ? null : unstableReturn;
}

@DataBoundSetter
public void setUnstableReturn(Integer unstableReturn) {
this.unstableReturn = unstableReturn;
}

@Override
protected boolean isErrorlevelForUnstableBuild(int exitCode) {
return this.unstableReturn != null && exitCode != 0 && this.unstableReturn.equals(exitCode);
}

public String[] buildCommandLine(FilePath script) {
String powerShellExecutable = null;
PowerShellInstallation installation = null;
Expand Down Expand Up @@ -158,7 +177,7 @@ public DescriptorImpl()
public String getHelpFile() {
return "/plugin/powershell/help.html";
}

@Override
public boolean isApplicable(Class<? extends AbstractProject> jobType) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,10 @@ THE SOFTWARE.
<f:checkbox default="true" />
</f:entry>

<f:advanced>
<f:entry title="${%ERRORLEVEL to set build unstable}" field="unstableReturn" >
<f:number value="${instance.unstableReturn}" min="-2147483648" max="2147483647" step="1" />
</f:entry>
</f:advanced>

</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div>
If set, the script exit code that will be interpreted as an unstable build result.
If the final exit code matches the value, the build results will be set to unstable.
The value 0 is ignored and does not make the build unstable to keep the default behaviour consistent.
</div>
46 changes: 41 additions & 5 deletions src/test/java/hudson/plugins/powershell/PowerShellTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class PowerShellTest {
@Test
public void testConfigRoundtrip() throws Exception {
FreeStyleProject p = r.createFreeStyleProject();
PowerShell orig = new PowerShell("script", true, true);
PowerShell orig = new PowerShell("script", true, true, null);
p.getBuildersList().add(orig);

JenkinsRule.WebClient webClient = r.createWebClient();
Expand All @@ -44,7 +44,7 @@ public void testBuildSuccess() throws Exception {
Assume.assumeTrue(isPowerShellAvailable());

FreeStyleProject project1 = r.createFreeStyleProject("project1");
project1.getBuildersList().add(new PowerShell("echo 'Hello World!'", true, true));
project1.getBuildersList().add(new PowerShell("echo 'Hello World!'", true, true, null));

QueueTaskFuture<FreeStyleBuild> freeStyleBuildQueueTaskFuture = project1.scheduleBuild2(0);
FreeStyleBuild build = freeStyleBuildQueueTaskFuture.get();
Expand All @@ -56,7 +56,7 @@ public void testBuildSuccess() throws Exception {
public void testBuildBadCommandFails() throws Exception {
Assume.assumeTrue(isPowerShellAvailable());
FreeStyleProject project1 = r.createFreeStyleProject("project1");
project1.getBuildersList().add(new PowerShell("wrong command", true, true));
project1.getBuildersList().add(new PowerShell("wrong command", true, true, null));

QueueTaskFuture<FreeStyleBuild> freeStyleBuildQueueTaskFuture = project1.scheduleBuild2(0);
FreeStyleBuild build = freeStyleBuildQueueTaskFuture.get();
Expand All @@ -68,7 +68,7 @@ public void testBuildBadCommandFails() throws Exception {
public void testBuildBadCommandsSucceeds() throws Exception {
Assume.assumeTrue(isPowerShellAvailable());
FreeStyleProject project1 = r.createFreeStyleProject("project1");
project1.getBuildersList().add(new PowerShell("wrong command", false, true));
project1.getBuildersList().add(new PowerShell("wrong command", false, true, null));

QueueTaskFuture<FreeStyleBuild> freeStyleBuildQueueTaskFuture = project1.scheduleBuild2(0);
FreeStyleBuild build = freeStyleBuildQueueTaskFuture.get();
Expand All @@ -81,7 +81,7 @@ public void testBuildAndDisableProject() throws Exception {
Assume.assumeTrue(isPowerShellAvailable());

FreeStyleProject project1 = r.createFreeStyleProject("project1");
project1.getBuildersList().add(new PowerShell("echo 'Hello World!'", true, true));
project1.getBuildersList().add(new PowerShell("echo 'Hello World!'", true, true, null));

QueueTaskFuture<FreeStyleBuild> freeStyleBuildQueueTaskFuture = project1.scheduleBuild2(0);
FreeStyleBuild build = freeStyleBuildQueueTaskFuture.get();
Expand All @@ -91,6 +91,42 @@ public void testBuildAndDisableProject() throws Exception {
project1.disable();
}

@Test
public void testBuildUnstableEnabledSucceeds() throws Exception {
Assume.assumeTrue(isPowerShellAvailable());
FreeStyleProject project1 = r.createFreeStyleProject("project1");
project1.getBuildersList().add(new PowerShell("exit 0", true, true, 123));

QueueTaskFuture<FreeStyleBuild> freeStyleBuildQueueTaskFuture = project1.scheduleBuild2(0);
FreeStyleBuild build = freeStyleBuildQueueTaskFuture.get();

r.assertBuildStatus(Result.SUCCESS, build);
}

@Test
public void testBuildUnstableEnabledBadCommandFails() throws Exception {
Assume.assumeTrue(isPowerShellAvailable());
FreeStyleProject project1 = r.createFreeStyleProject("project1");
project1.getBuildersList().add(new PowerShell("exit 1", true, true, 123));

QueueTaskFuture<FreeStyleBuild> freeStyleBuildQueueTaskFuture = project1.scheduleBuild2(0);
FreeStyleBuild build = freeStyleBuildQueueTaskFuture.get();

r.assertBuildStatus(Result.FAILURE, build);
}

@Test
public void testBuildUnstableEnabledBadCommandUnstableErrorCode() throws Exception {
Assume.assumeTrue(isPowerShellAvailable());
FreeStyleProject project1 = r.createFreeStyleProject("project1");
project1.getBuildersList().add(new PowerShell("exit 123", true, true, 123));

QueueTaskFuture<FreeStyleBuild> freeStyleBuildQueueTaskFuture = project1.scheduleBuild2(0);
FreeStyleBuild build = freeStyleBuildQueueTaskFuture.get();

r.assertBuildStatus(Result.UNSTABLE, build);
}

private boolean isPowerShellAvailable() {
return Stream.of(System.getenv("PATH").split(Pattern.quote(File.pathSeparator)))
.map(Paths::get)
Expand Down