Skip to content
Permalink
Browse files

Merge pull request #17 from amuniz/JENKINS-34996

[JENKINS-34996] Release parameters visibility
  • Loading branch information...
oleg-nenashev committed Sep 28, 2016
2 parents 3a0e033 + 9d17b55 commit ab68ac9ce267e658ff1662253a3726a7d040a509
25 pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.481</version>
<version>2.9</version>
</parent>
<artifactId>release</artifactId>
<packaging>hpi</packaging>
@@ -13,17 +13,12 @@
<description>Adds the ability to wrap your job with pre- and post- build steps which are only executed when a manual release build is triggered.</description>
<url>http://wiki.jenkins-ci.org/display/JENKINS/Release+Plugin</url>

<build>
<plugins>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<goals>deploy</goals>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jenkins.version>1.609.3</jenkins.version>
<java.level>6</java.level>
<!-- TODO: fix findbugs warnings and remove this -->
<findbugs.failOnError>false</findbugs.failOnError>
</properties>

<scm>
<connection>scm:git:git://github.com/jenkinsci/release-plugin.git</connection>
@@ -43,6 +38,7 @@
<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>maven-plugin</artifactId>
<version>2.13</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
@@ -56,6 +52,11 @@
<version>2.0</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>matrix-project</artifactId>
<version>1.7</version>
</dependency>
</dependencies>


@@ -163,10 +163,7 @@ public String getId() {
}
});
}

/**
* @stapler-constructor
*/

public ReleaseWrapper() {
}

@@ -222,10 +219,7 @@ public void setPreBuildSteps(List<BuildStep> preBuildSteps) {
public List<BuildStep> getPreMatrixBuildSteps() {
return preMatrixBuildSteps;
}

/**
* @param preBuildSteps The preMatrixBuildSteps to set.
*/

public void setPreMatrixBuildSteps(List<BuildStep> preMatrixBuildSteps) {
this.preMatrixBuildSteps = preMatrixBuildSteps;
}
@@ -236,10 +230,7 @@ public void setPreMatrixBuildSteps(List<BuildStep> preMatrixBuildSteps) {
public List<BuildStep> getPostBuildSteps() {
return postBuildSteps;
}

/**
* @param postBuildSteps The postBuildSteps to set.
*/

public void setPostBuildSteps(List<BuildStep> postSuccessBuildSteps) {
this.postBuildSteps = postSuccessBuildSteps;
}
@@ -600,6 +591,9 @@ public void setDevelopmentVersion(String developmentVersion) {
/**
* Gets the {@link ParameterDefinition} of the given name, including
* the ones from the build parameters, if any.
*
* @param name The parameter name
* @return the parameter definition with the given name
*/
public ParameterDefinition getParameterDefinition(String name) {
ParametersDefinitionProperty buildParamsDefProp = (ParametersDefinitionProperty) project.getProperty(ParametersDefinitionProperty.class);
@@ -708,7 +702,7 @@ public void doSubmit(StaplerRequest req, StaplerResponse resp) throws IOExceptio
// schedule release build
if (!project.scheduleBuild(0, new Cause.UserCause(),
new ReleaseBuildBadgeAction(),
new ParametersAction(paramValues))) {
new SafeParametersAction(paramValues))) {
// TODO redirect to error page?
}

@@ -750,9 +744,6 @@ public ReleaseAggregator(MatrixBuild build, Launcher launcher, BuildListener lis
this.isNotRelease = build.getAction(ReleaseBuildBadgeAction.class) == null;
}

/**
* @param preBuildSteps The preMatrixBuildSteps to set.
*/
public void setPreMatrixBuildSteps(List<BuildStep> preMatrixBuildSteps) {
this.preMatrixBuildSteps = preMatrixBuildSteps;
}
@@ -0,0 +1,69 @@
package hudson.plugins.release;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;

import hudson.EnvVars;
import hudson.Extension;
import hudson.model.EnvironmentContributor;
import hudson.model.ParameterValue;
import hudson.model.ParametersAction;
import hudson.model.Run;
import hudson.model.TaskListener;

@Restricted(NoExternalUse.class)
public class SafeParametersAction extends ParametersAction {

private final List<ParameterValue> parameters;

/**
* At this point the list of parameter values is guaranteed to be safe, which is
* parameter defined either at top level or release wrapper level.
*/
SafeParametersAction(List<ParameterValue> parameters) {
this.parameters = parameters;
}

/**
* Returns all parameters allowed by the job (defined as regular job parameters) and
* the parameters allowed by release-specific parameters definition.
*/
@Override
public List<ParameterValue> getParameters() {
return Collections.unmodifiableList(parameters);
}

/**
* Returns the parameter if defined as a regular parameters or it is a release-specific parameter defined
* by the release wrapper.
*/
@Override
public ParameterValue getParameter(String name) {
for (ParameterValue p : parameters) {
if (p == null) continue;
if (p.getName().equals(name)) {
return p;
}
}
return null;
}

@Extension
public static final class SafeParametersActionEnvironmentContributor extends EnvironmentContributor {

@Override
public void buildEnvironmentFor(Run r, EnvVars envs, TaskListener listener) throws IOException, InterruptedException {
SafeParametersAction action = r.getAction(SafeParametersAction.class);
if (action != null) {
for(ParameterValue p : action.getParameters()) {
envs.put(p.getName(), String.valueOf(p.getValue()));
}
}
}
}

}
@@ -61,7 +61,7 @@ public RecentReleasesPortlet(String name) {
/**
* Get the release version from this run
* @param run Must be a release run - i.e. have a ReleaseBuildBadgeAction
* @return
* @return the release version as specified in {@link ReleaseBuildBadgeAction#getReleaseVersion()}
*/
public String getReleaseVersion(Run run) {
ReleaseBuildBadgeAction rbb = run.getAction(ReleaseBuildBadgeAction.class);
@@ -28,13 +28,14 @@
This belongs to a build view.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<l:layout norefresh="true">
<st:include it="${it.project}" page="sidepanel.jelly" />
<l:main-panel>
<table width="100%">
<tr><td>
<f:form method="post" action="submit">
<f:form method="post" action="submit" name="release-action-form">
<j:if test="${it.overrideBuildParameters and !it.buildParameterDefinitions.isEmpty()}">
<f:section title="${%Override build parameters}">
<j:forEach var="buildParameterDefinition" items="${it.buildParameterDefinitions}">
@@ -3,6 +3,7 @@
This belongs to a build view.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">

<j:if test="${it.releaseVersion != null}">
@@ -22,7 +22,7 @@
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-->

<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define"
xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form"
xmlns:p="/lib/hudson/project">
@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->

<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<f:entry title="${%Name}">
<f:textbox name="portlet.name" field="name"/>
@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->

<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:dp="/hudson/plugins/view/dashboard" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<table class="sortable pane bigtable" id="projectStatus">
<tr><td class="pane-header" colspan="5">${it.displayName}</td></tr>
@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->

<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:dp="/hudson/plugins/view/dashboard" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<dp:decorate portlet="${it}" width="2">
<j:set var="recentReleases" value="${it.getRecentReleases(5)}"/>
@@ -1,3 +1,4 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core">
<div>
Build was a release build
@@ -1,2 +1,3 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core">
</j:jelly>
@@ -1,3 +1,4 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core">
<div>
Not a release build
@@ -1,6 +1,7 @@
<!--
This view is used to render the plugin list page.
-->
<?jelly escape-by-default='true'?>
<div>
This plugin allows you to configure pre and post build actions that are executed
when a release build is manually triggered.
@@ -89,7 +89,7 @@ public void testEnableReleaseUsingWebPage() throws Exception
HtmlPage page = j.createWebClient().goTo("job/test/");
// Internationalisation not needed because the URL doesn't change between languages
// see getUrlName() in ReleaseAction
List<Object> nodes = page.selectNodes("//a[contains(@href, '/test/release')]");
List<?> nodes = page.getByXPath("//a[contains(@href, '/test/release')]");
assertThat("Require 2 href links", nodes.size(), is(2));
}

@@ -23,7 +23,7 @@

@Before
public void createJob() throws Exception {
job = j.createMatrixProject("foo");
job = j.createProject(MatrixProject.class, "foo");
}

@After
@@ -0,0 +1,101 @@
package hudson.plugins.release;

import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.util.Arrays;

import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.MockBuilder;

import com.gargoylesoftware.htmlunit.html.HtmlForm;

import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
import hudson.model.FreeStyleProject;
import hudson.model.Job;
import hudson.model.ParameterDefinition;
import hudson.model.ParametersDefinitionProperty;
import hudson.model.Result;
import hudson.model.StringParameterDefinition;
import hudson.tasks.BuildStep;

public class TestReleasePluginParameters {

@Rule
public JenkinsRule j = new JenkinsRule();

@Test
@Issue("JENKINS-34996")
public void testReleaseParameters() throws Exception {
FreeStyleProject prj = j.createProject(FreeStyleProject.class, "foo");
ReleaseWrapper releaseWrapper = new ReleaseWrapper();
// Parameter in release specific builder
releaseWrapper.setParameterDefinitions(Arrays.asList(new ParameterDefinition [] {
new StringParameterDefinition("TEST", "test value") }));

CheckerBuildStep checkerBuildStep = new CheckerBuildStep();
releaseWrapper.setPostSuccessfulBuildSteps(Arrays.asList(new BuildStep [] { checkerBuildStep }));
prj.getBuildWrappersList().add(releaseWrapper);

scheduleReleaseBuild(prj);

j.waitUntilNoActivity();
assertTrue("Build finishes", prj.getLastBuild() != null);

assertTrue("The parameter must be visible as environment variable", checkerBuildStep.value != null);
assertTrue("The parameter value must match", checkerBuildStep.value.equals("test value"));
j.assertBuildStatus(Result.SUCCESS, prj.getLastBuild());
}

@Test
@Issue("JENKINS-34996") // This test worked before the fix, added just as a verification
public void testJobParameters() throws Exception {
FreeStyleProject prj = j.createProject(FreeStyleProject.class, "foo");
// Parameter at top level (job)
prj.addProperty(new ParametersDefinitionProperty(new StringParameterDefinition("TEST","test value")));

ReleaseWrapper releaseWrapper = new ReleaseWrapper();
CheckerBuildStep checkerBuildStep = new CheckerBuildStep();
releaseWrapper.setPostSuccessfulBuildSteps(Arrays.asList(new BuildStep [] { checkerBuildStep }));
prj.getBuildWrappersList().add(releaseWrapper);

scheduleReleaseBuild(prj);

j.waitUntilNoActivity();

assertTrue("The parameter must be visible as environment variable", checkerBuildStep.value != null);
assertTrue("The parameter value must match", checkerBuildStep.value.equals("test value"));
j.assertBuildStatus(Result.SUCCESS, prj.getLastBuild());
}

public static class CheckerBuildStep extends MockBuilder {

public String value;

public CheckerBuildStep() {
super(Result.SUCCESS);
}

@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener)
throws InterruptedException, IOException {
value = build.getEnvironment(listener).get("TEST");
return true;
}
}

/**
* The release build must be scheduled from UI as all the parameters logic is tied
* to {@link ReleaseWrapper.ReleaseAction#doSubmit(org.kohsuke.stapler.StaplerRequest, org.kohsuke.stapler.StaplerResponse)}.
*/
private void scheduleReleaseBuild(Job<?, ?> job) throws Exception {
HtmlForm releaseForm = j.createWebClient().getPage(job, "release").getFormByName("release-action-form");
j.submit(releaseForm);
}

}

0 comments on commit ab68ac9

Please sign in to comment.
You can’t perform that action at this time.