Skip to content

Commit

Permalink
Add support for build wrappers in promotions
Browse files Browse the repository at this point in the history
This commit adds support for build wrappers in the promotion processes.
The build wrappers can be configured in a new "Promotion Environment"
section of the promotion process configuration.

This is useful e.g. in order to be able to prepare an environment or inject
secrets for the promotion.

There are a number of issues calling for this support:
[FIXED JENKINS-23977]
[FIXED JENKINS-25526]
[FIXED JENKINS-43656]

For [JENKINS-14169] this change might provide a workaround by allowing
to inject environment vars for the promotion either from the
configuration or by injecting them from a file passed to the promotion process.
  • Loading branch information
Patrick Schlebusch committed Apr 25, 2019
1 parent d3e4161 commit cc5eb36
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 46 deletions.
68 changes: 38 additions & 30 deletions src/main/java/hudson/plugins/promoted_builds/Promotion.java
Expand Up @@ -166,8 +166,8 @@ public EnvVars getEnvironment(TaskListener listener) throws IOException, Interru

return e;
}


/**
* Get a user name of the person, who triggered the promotion.
* The method tries various sources like {@link UserIdCause} or {@link ManualCondition.Badge}.
Expand All @@ -189,7 +189,7 @@ public String getUserName() {
return nameFromUserIdCause;
}

//fallback to badge lookup for compatibility
//fallback to badge lookup for compatibility
for (PromotionBadge badget : getStatus().getBadges()) {
if (badget instanceof ManualCondition.Badge) {
final String nameFromBadge = ((ManualCondition.Badge) badget).getUserName();
Expand All @@ -200,14 +200,14 @@ public String getUserName() {
}
return Jenkins.ANONYMOUS.getName();
}


/**
* Gets ID of the {@link User}, who triggered the promotion.
* The method tries various sources like {@link UserIdCause} or {@link ManualCondition.Badge}.
* @return ID of the user who triggered the promotion.
* If the search fails, returns ID of {@link User#getUnknown()}.
* @since 2.22
* @since 2.22
*/
@Nonnull
public String getUserId() {
Expand All @@ -227,7 +227,7 @@ public String getUserId() {
return idFromUserIdCause;
}

//fallback to badge lookup for compatibility
//fallback to badge lookup for compatibility
for (PromotionBadge badget : getStatus().getBadges()) {
if (badget instanceof ManualCondition.Badge) {
final String idFromBadge = ((ManualCondition.Badge) badget).getUserId();
Expand All @@ -240,7 +240,7 @@ public String getUserId() {
}

public List<ParameterValue> getParameterValues(){
List<ParameterValue> values=new ArrayList<ParameterValue>();
List<ParameterValue> values=new ArrayList<ParameterValue>();
ParametersAction parametersAction=getParametersActions(this);
if (parametersAction!=null){
ManualCondition manualCondition=(ManualCondition) getProject().getPromotionCondition(ManualCondition.class.getName());
Expand All @@ -253,16 +253,16 @@ public List<ParameterValue> getParameterValues(){
}
return values;
}
//fallback to badge lookup for compatibility

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

/**
* Gets parameter definitions from the {@link ManualCondition}.
* @return List of parameter definitions to be presented.
Expand All @@ -275,7 +275,7 @@ public List<ParameterDefinition> getParameterDefinitionsWithValue(){
if (manualCondition == null) {
return definitions;
}

for (ParameterValue pvalue:getParameterValues()){
ParameterDefinition pdef=manualCondition.getParameterDefinition(pvalue.getName());
if (pdef == null) {
Expand All @@ -301,11 +301,11 @@ public void run() {

protected class RunnerImpl extends AbstractRunner {
final Promotion promotionRun;

RunnerImpl(final Promotion promotionRun) {
this.promotionRun = promotionRun;
}

@Override
protected Lease decideWorkspace(Node n, WorkspaceList wsl) throws InterruptedException, IOException {
if (getTarget() == null) {
Expand All @@ -321,7 +321,7 @@ protected Lease decideWorkspace(Node n, WorkspaceList wsl) throws InterruptedExc
return Lease.createDummyLease(
rootPath.child(getEnvironment(listener).expand(customWorkspace)));
}

TopLevelItem item = (TopLevelItem)getTarget().getProject();
FilePath workspace = n.getWorkspaceFor(item);
if (workspace == null) {
Expand Down Expand Up @@ -360,10 +360,11 @@ protected Result doRun(BuildListener listener) throws Exception {

if(!preBuild(listener,project.getBuildSteps()))
return Result.FAILURE;

try {
List<BuildWrapper> wrappers = new ArrayList<BuildWrapper>(project.getBuildWrappers().values());
List<ParameterValue> params=getParameterValues();

if (params!=null){
for(ParameterValue value : params) {
BuildWrapper wrapper=value.createBuildWrapper(Promotion.this);
Expand All @@ -375,20 +376,27 @@ protected Result doRun(BuildListener listener) throws Exception {
}
}
}


for( BuildWrapper w : wrappers ) {
Environment e = w.setUp(Promotion.this, launcher, listener);
if(e == null)
return Result.FAILURE;
buildEnvironments.add(e);
}

if(!build(listener,project.getBuildSteps(),target))
return Result.FAILURE;

return null;
} finally {
boolean failed = false;

for(int i = buildEnvironments.size()-1; i >= 0; i--) {
if (!buildEnvironments.get(i).tearDown(Promotion.this,listener)) {
failed=true;
}
}

if(failed)
return Result.FAILURE;
}
Expand Down Expand Up @@ -458,7 +466,7 @@ private boolean preBuild(BuildListener listener, List<BuildStep> steps) {
}
return true;
}

}

public static final PermissionGroup PERMISSIONS = new PermissionGroup(Promotion.class, Messages._Promotion_Permissions_Title());
Expand All @@ -480,9 +488,9 @@ public boolean equals(Object obj) {
final Promotion other = (Promotion) obj;
return this.getId().equals(other.getId());
}



/**
* Factory method for creating {@link ParametersAction}
* @param parameters
Expand Down Expand Up @@ -511,7 +519,7 @@ public static void buildParametersAction(@Nonnull List<Action> actions,
}

private static final Logger LOGGER = Logger.getLogger(Promotion.class.getName());

/**
* Action, which stores promotion parameters.
* This class allows defining custom parameters filtering logic, which is
Expand All @@ -520,26 +528,26 @@ public static void buildParametersAction(@Nonnull List<Action> actions,
*/
@Restricted(NoExternalUse.class)
public static class PromotionParametersAction extends ParametersAction {

private List<ParameterValue> unfilteredParameters;

private PromotionParametersAction(List<ParameterValue> params) {
// Pass the parameters upstairs
super(params);
super(params);
unfilteredParameters = params;
}

@Override
public List<ParameterValue> getParameters() {
return Collections.unmodifiableList(filter(unfilteredParameters));
}

private List<ParameterValue> filter(List<ParameterValue> params) {
// buildToBePromoted::getParameters() invokes the secured method, hence all
// parameters from the promoted build are safe.
return params;
}

public static PromotionParametersAction buildFor(
@Nonnull AbstractBuild<?, ?> buildToBePromoted,
@CheckForNull List<ParameterValue> promotionParams) {
Expand Down

0 comments on commit cc5eb36

Please sign in to comment.