Skip to content

Commit

Permalink
Merge remote-tracking branch 'cvarjao/JENKINS-8962'
Browse files Browse the repository at this point in the history
Conflicts:
	src/main/java/hudson/plugins/promoted_builds/Promotion.java
  • Loading branch information
ndeloof committed Oct 15, 2013
2 parents 770c7bb + 30a3214 commit 4f62ff6
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 66 deletions.
142 changes: 116 additions & 26 deletions src/main/java/hudson/plugins/promoted_builds/Promotion.java
Expand Up @@ -2,17 +2,21 @@

import hudson.EnvVars;
import hudson.console.HyperlinkNote;
import hudson.model.Action;
import hudson.model.BuildListener;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Node;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.Cause.UserCause;
import hudson.model.Environment;
import hudson.model.Node;
import hudson.model.ParameterDefinition;
import hudson.model.ParametersAction;
import hudson.model.ParameterValue;
import hudson.model.Result;
import hudson.model.TaskListener;
import hudson.model.TopLevelItem;
import hudson.plugins.promoted_builds.conditions.ManualCondition.ManualApproval;
import hudson.model.Run;
import hudson.plugins.promoted_builds.conditions.ManualCondition;
import hudson.security.Permission;
import hudson.security.PermissionGroup;
import hudson.security.PermissionScope;
Expand All @@ -21,14 +25,18 @@
import hudson.tasks.BuildStep;
import hudson.tasks.BuildWrapper;
import hudson.tasks.BuildTrigger;

import jenkins.model.Jenkins;

import org.kohsuke.stapler.export.Exported;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import org.kohsuke.stapler.export.Exported;

/**
* Records a promotion process.
Expand Down Expand Up @@ -104,6 +112,58 @@ public EnvVars getEnvironment(TaskListener listener) throws IOException, Interru

return e;
}


/**
*
* @return user's name who triggered the promotion, or 'anonymous'
*/
public String getUserName(){
UserCause userClause=getCause(UserCause.class);
if (userClause!=null && userClause.getUserName()!=null){
return userClause.getUserName();
}

//fallback to badge lookup for compatibility
for (PromotionBadge badget:getStatus().getBadges()){
if (badget instanceof ManualCondition.Badge){
return ((ManualCondition.Badge) badget).getUserName();
}
}
return "anonymous";
}

public List<ParameterValue> getParameterValues(){
List<ParameterValue> values=new ArrayList<ParameterValue>();
ParametersAction parametersAction=getParametersActions(this);
if (parametersAction!=null){
ManualCondition manualCondition=(ManualCondition) getProject().getPromotionCondition(ManualCondition.class.getName());
for (ParameterValue pvalue:parametersAction.getParameters()){
if (manualCondition.getParameterDefinition(pvalue.getName())!=null){

This comment has been minimized.

Copy link
@gcummings

gcummings Oct 22, 2013

Causes nullPointerException if the promotion is not a manual promotion, need null check on manualCondition ?
java.lang.NullPointerException
at hudson.plugins.promoted_builds.Promotion.getParameterValues(Promotion.java:142)

Created JENKINS-20166

values.add(pvalue);
}
}
return values;
}

//fallback to badge lookup for compatibility
for (PromotionBadge badget:getStatus().getBadges()){
if (badget instanceof ManualCondition.Badge){
return ((ManualCondition.Badge) badget).getParameterValues();
}
}
return Collections.emptyList();
}

public List<ParameterDefinition> getParameterDefinitionsWithValue(){
List<ParameterDefinition> definitions=new ArrayList<ParameterDefinition>();
ManualCondition manualCondition=(ManualCondition) getProject().getPromotionCondition(ManualCondition.class.getName());
for (ParameterValue pvalue:getParameterValues()){
ParameterDefinition pdef=manualCondition.getParameterDefinition(pvalue.getName());
definitions.add(pdef.copyWithDefaultValue(pvalue));
}
return definitions;
}

public void run() {
getStatus().addPromotionAttempt(this);
Expand Down Expand Up @@ -143,25 +203,19 @@ protected Result doRun(BuildListener listener) throws Exception {
return Result.FAILURE;

try {
PromotionTargetAction targetAction = getAction(PromotionTargetAction.class);
AbstractBuild<?, ?> build = targetAction.resolve();
// TODO why would it ever be true that build != target?
List<ManualApproval> approvals = build.getActions(ManualApproval.class);
for(ManualApproval approval : approvals) {
List<ParameterValue> params = approval.badge.getParameterValues();

for(ParameterValue value : params) {
BuildWrapper wrapper = value.createBuildWrapper(Promotion.this);
if(wrapper != null) {
Environment e = wrapper.setUp(Promotion.this, launcher, listener);

if(e==null)
return Result.FAILURE;

buildEnvironments.add(e);
}
}
}
List<ParameterValue> params=getParameterValues();

if (params!=null){
for(ParameterValue value : params) {
BuildWrapper wrapper=value.createBuildWrapper(Promotion.this);
if (wrapper!=null){
Environment e = wrapper.setUp(Promotion.this, launcher, listener);
if(e==null)
return Result.FAILURE;
buildEnvironments.add(e);
}
}
}

if(!build(listener,project.getBuildSteps(),target))
return Result.FAILURE;
Expand Down Expand Up @@ -250,5 +304,41 @@ private boolean preBuild(BuildListener listener, List<BuildStep> steps) {
public int compareTo(Promotion that) {
return that.getId().compareTo( this.getId() );
}

/**
* Factory method for creating {@link ParametersAction}
* @param parameters
* @return
*/
public static ParametersAction createParametersAction(List<ParameterValue> parameters){
return new ParametersAction(parameters);
}
public static ParametersAction getParametersActions(Promotion build){
return build.getAction(ParametersAction.class);
}

/**
* Combine the target build parameters with the promotion build parameters
* @param actions
* @param build
* @param promotionParams
*/
public static void buildParametersAction(List<Action> actions, AbstractBuild<?, ?> build, List<ParameterValue> promotionParams) {
List<ParameterValue> params=new ArrayList<ParameterValue>();

//Add the target build parameters first, if the same parameter is not being provided bu the promotion build
List<ParametersAction> parameters = build.getActions(ParametersAction.class);
for(ParametersAction paramAction:parameters){
for (ParameterValue pvalue:paramAction.getParameters()){
if (!promotionParams.contains(pvalue)){
params.add(pvalue);
}
}
}

//Add all the promotion build parameters
params.addAll(promotionParams);

// Create list of actions to pass to scheduled build
actions.add(new ParametersAction(params));
}
}
31 changes: 21 additions & 10 deletions src/main/java/hudson/plugins/promoted_builds/PromotionProcess.java
Expand Up @@ -8,8 +8,9 @@
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.AutoCompletionCandidates;
import hudson.model.ParameterValue;
import hudson.model.Cause;
import hudson.model.Cause.LegacyCodeCause;
import hudson.model.Cause.UserCause;
import hudson.model.DependencyGraph;
import hudson.model.Describable;
import hudson.model.Descriptor;
Expand All @@ -28,6 +29,7 @@
import hudson.model.Saveable;
import hudson.model.labels.LabelAtom;
import hudson.model.labels.LabelExpression;
import hudson.plugins.promoted_builds.conditions.ManualCondition.ManualApproval;
import hudson.tasks.BuildStep;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Builder;
Expand Down Expand Up @@ -314,7 +316,7 @@ public Future<Promotion> considerPromotion2(AbstractBuild<?,?> build) throws IOE
return null; // not this time

LOGGER.fine("Promotion condition of "+build+" is met: "+qualification);
Future<Promotion> f = promote2(build, new LegacyCodeCause(), qualification); // TODO: define promotion cause
Future<Promotion> f = promote2(build, new UserCause(), qualification); // TODO: define promotion cause
if (f==null)
LOGGER.warning(build+" qualifies for a promotion but the queueing failed.");
return f;
Expand Down Expand Up @@ -363,7 +365,7 @@ public boolean scheduleBuild() {
}

public boolean scheduleBuild(AbstractBuild<?,?> build) {
return scheduleBuild(build,new LegacyCodeCause());
return scheduleBuild(build,new UserCause());
}

/**
Expand All @@ -374,21 +376,30 @@ public boolean scheduleBuild(AbstractBuild<?,?> build, Cause cause) {
return scheduleBuild2(build,cause)!=null;
}

public Future<Promotion> scheduleBuild2(AbstractBuild<?,?> build, Cause cause) {
public Future<Promotion> scheduleBuild2(AbstractBuild<?,?> build, Cause cause, List<ParameterValue> params) {
assert build.getProject()==getOwner();

// Get the parameters, if any, used in the target build and make these
// available as part of the promotion steps
List<ParametersAction> parameters = build.getActions(ParametersAction.class);

// Create list of actions to pass to scheduled build
List<Action> actions = new ArrayList<Action>();
actions.addAll(parameters);
Promotion.buildParametersAction(actions, build, params);

actions.add(new PromotionTargetAction(build));

// remember what build we are promoting
return super.scheduleBuild2(0, cause, actions.toArray(new Action[actions.size()]));
}

public Future<Promotion> scheduleBuild2(AbstractBuild<?,?> build, Cause cause) {
List<ParameterValue> params=new ArrayList<ParameterValue>();
List<ManualApproval> approvals = build.getActions(ManualApproval.class);
if (approvals!=null){
for(ManualApproval approval : approvals) {
params.addAll(approval.badge.getParameterValues());
}
}

// remember what build we are promoting
return scheduleBuild2(build, cause, params);
}

public boolean isInQueue(AbstractBuild<?,?> build) {
for (Item item : Hudson.getInstance().getQueue().getItems(this))
Expand Down
44 changes: 43 additions & 1 deletion src/main/java/hudson/plugins/promoted_builds/Status.java
Expand Up @@ -5,8 +5,14 @@
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Cause.UserCause;
import hudson.model.ParameterDefinition;
import hudson.model.ParameterValue;
import hudson.model.Result;
import hudson.plugins.promoted_builds.conditions.ManualCondition;
import hudson.util.Iterators;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

Expand Down Expand Up @@ -75,6 +81,9 @@ public String getName() {
* Gets the parent {@link Status} that owns this object.
*/
public PromotedBuildAction getParent() {
if (parent==null){
parent=getTarget().getAction(PromotedBuildAction.class);
}
return parent;
}

Expand Down Expand Up @@ -286,13 +295,46 @@ public Promotion getPromotionBuild(int number) {
return p.getBuildByNumber(number);
}

public boolean isManuallyApproved(){
ManualCondition manualCondition=(ManualCondition) getProcess().getPromotionCondition(ManualCondition.class.getName());
return manualCondition!=null;
}
/**
* Schedules a new build.
*/
public void doBuild(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
if(!getTarget().hasPermission(Promotion.PROMOTE))
return;
Future<Promotion> f = getProcess().scheduleBuild2(getTarget(), new UserCause());


JSONObject formData = req.getSubmittedForm();

List<ParameterValue> paramValues=null;
if (formData!=null){
paramValues = new ArrayList<ParameterValue>();
ManualCondition manualCondition=(ManualCondition) getProcess().getPromotionCondition(ManualCondition.class.getName());
if (manualCondition!=null){
List<ParameterDefinition> parameterDefinitions=manualCondition.getParameterDefinitions();
if (parameterDefinitions != null && !parameterDefinitions.isEmpty()) {
JSONArray a = JSONArray.fromObject(formData.get("parameter"));

for (Object o : a) {
JSONObject jo = (JSONObject) o;
String name = jo.getString("name");

ParameterDefinition d = manualCondition.getParameterDefinition(name);
if (d==null)
throw new IllegalArgumentException("No such parameter definition: " + name);

paramValues.add(d.createValue(req, jo));
}
}
}
}
if (paramValues==null){
paramValues = new ArrayList<ParameterValue>();
}
Future<Promotion> f = getProcess().scheduleBuild2(getTarget(), new UserCause(), paramValues);
if (f==null)
LOGGER.warning("Failing to schedule the promotion of "+getTarget());
// TODO: we need better visual feed back so that the user knows that the build happened.
Expand Down
Expand Up @@ -13,6 +13,7 @@
import hudson.plugins.promoted_builds.PromotionBadge;
import hudson.plugins.promoted_builds.PromotionCondition;
import hudson.plugins.promoted_builds.PromotionConditionDescriptor;
import hudson.plugins.promoted_builds.Promotion;
import hudson.plugins.promoted_builds.PromotionProcess;
import java.io.IOException;
import java.util.ArrayList;
Expand Down Expand Up @@ -212,9 +213,12 @@ public List<ParameterValue> getParameterValues() {

@Override
public void buildEnvVars(AbstractBuild<?, ?> build, EnvVars env) {
for (ParameterValue value : getParameterValues()) {
value.buildEnvVars(build, env);
}
List<ParameterValue> params=((Promotion)build).getParameterValues();
if (params!=null){
for(ParameterValue value : params) {
value.buildEnvVars(build, env);
}
}
}
}

Expand Down

0 comments on commit 4f62ff6

Please sign in to comment.