-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is a new pipeline step that extends BuildTriggerStep from jenkinsci/pipeline-build-step-plugin#112 in order to add a new build action EiffelActivityDataAction to the downstream build. This build action will supplement Eiffel activity data that will override corresponding data fields in the EiffelActivityTriggeredEvent when the downstream build enters the build queue. Unfortunately, in order to add a new action to triggered builds, the step execution of BuildTriggerStep had to be modified, which meant that a number of project files had to be copied with slight modifications to ensure that there is no interference when running with both jenkinsci/eiffel-broadcaster-plugin and jenkinsci/pipeline-build-step-plugin. Also, to ensure the underlying build trigger functionality inherited by the buildWithEiffel step, a regression test suite has been added, containing all the BuildTriggerStep tests. These tests have been updated to use buildWithEiffel and the suite itself is excluded from normal testing to reduce execution time. Currently, buildWithEiffel step only supports activity name.
- Loading branch information
Showing
30 changed files
with
2,003 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
72 changes: 72 additions & 0 deletions
72
...main/java/com/axis/jenkins/plugins/eiffel/eiffelbroadcaster/EiffelActivityDataAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/** | ||
The MIT License | ||
Copyright 2024 Axis Communications AB. | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
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. | ||
*/ | ||
|
||
package com.axis.jenkins.plugins.eiffel.eiffelbroadcaster; | ||
|
||
import com.axis.jenkins.plugins.eiffel.eiffelbroadcaster.eiffel.EiffelActivityTriggeredEvent; | ||
import com.axis.jenkins.plugins.eiffel.eiffelbroadcaster.pipeline.build.BuildWithEiffelStep; | ||
import edu.umd.cs.findbugs.annotations.CheckForNull; | ||
import edu.umd.cs.findbugs.annotations.NonNull; | ||
import hudson.model.Action; | ||
|
||
/** | ||
* An {@link Action} for storing the data fields of {@link EiffelActivityTriggeredEvent.Data} for Eiffel activity event | ||
* {@link EiffelActivityTriggeredEvent} ActT, that enables the option of setting custom data when the event fires | ||
* as a build enters a waiting state in the build queue. Currently, only name field is supported. | ||
* | ||
* This action is instantiated when a {@link BuildWithEiffelStep} step is executed and will always contain | ||
* a name. | ||
*/ | ||
public class EiffelActivityDataAction implements Action { | ||
|
||
/** The activity name of the Eiffel activity event {@link EiffelActivityTriggeredEvent} ActT*/ | ||
private final String name; | ||
|
||
public EiffelActivityDataAction(@NonNull String name) { | ||
this.name=name; | ||
} | ||
|
||
@CheckForNull | ||
public String getName() { | ||
return name; | ||
} | ||
|
||
@CheckForNull | ||
@Override | ||
public String getIconFileName() { | ||
return null; | ||
} | ||
|
||
@CheckForNull | ||
@Override | ||
public String getDisplayName() { | ||
return null; | ||
} | ||
|
||
@CheckForNull | ||
@Override | ||
public String getUrlName() { | ||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
...m/axis/jenkins/plugins/eiffel/eiffelbroadcaster/pipeline/build/BuildWithEiffelAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// The following code is copied from https://github.com/jenkinsci/pipeline-build-step-plugin | ||
|
||
package com.axis.jenkins.plugins.eiffel.eiffelbroadcaster.pipeline.build; | ||
|
||
import edu.umd.cs.findbugs.annotations.CheckForNull; | ||
import hudson.model.Action; | ||
import hudson.model.Actionable; | ||
import hudson.model.InvisibleAction; | ||
import hudson.model.Queue; | ||
import hudson.model.queue.FoldableAction; | ||
import org.jenkinsci.plugins.workflow.steps.StepContext; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
@SuppressWarnings("SynchronizeOnNonFinalField") | ||
class BuildWithEiffelAction extends InvisibleAction implements FoldableAction { | ||
|
||
private static final Logger LOGGER = Logger.getLogger(BuildWithEiffelAction.class.getName()); | ||
|
||
@Deprecated | ||
private StepContext context; | ||
|
||
@Deprecated | ||
private Boolean propagate; | ||
|
||
/** Record of one upstream build step. */ | ||
static class Trigger { | ||
|
||
final StepContext context; | ||
|
||
final boolean propagate; | ||
final boolean waitForStart; | ||
|
||
/** Record of cancellation cause passed to {@link BuildWithEiffelStepExecution#stop}, if any. */ | ||
@CheckForNull | ||
Throwable interruption; | ||
|
||
Trigger(StepContext context, boolean propagate, boolean waitForStart) { | ||
this.context = context; | ||
this.propagate = propagate; | ||
this.waitForStart = waitForStart; | ||
} | ||
|
||
} | ||
|
||
private /* final */ List<BuildWithEiffelAction.Trigger> triggers; | ||
|
||
BuildWithEiffelAction(StepContext context, boolean propagate, boolean waitForStart) { | ||
triggers = new ArrayList<>(); | ||
triggers.add(new BuildWithEiffelAction.Trigger(context, propagate, waitForStart)); | ||
} | ||
|
||
private Object readResolve() { | ||
if (triggers == null) { | ||
triggers = new ArrayList<>(); | ||
triggers.add(new BuildWithEiffelAction.Trigger(context, propagate != null ? propagate : /* old serialized record */ true, false)); | ||
context = null; | ||
propagate = null; | ||
} | ||
return this; | ||
} | ||
|
||
static Iterable<BuildWithEiffelAction.Trigger> triggersFor(Actionable actionable) { | ||
List<BuildWithEiffelAction.Trigger> triggers = new ArrayList<>(); | ||
for (BuildWithEiffelAction action : actionable.getActions(BuildWithEiffelAction.class)) { | ||
synchronized (action.triggers) { | ||
triggers.addAll(action.triggers); | ||
} | ||
} | ||
return triggers; | ||
} | ||
|
||
@Override public void foldIntoExisting(Queue.Item item, Queue.Task owner, List<Action> otherActions) { | ||
// there may be >1 upstream builds (or other unrelated causes) for a single downstream build | ||
BuildWithEiffelAction existing = item.getAction(BuildWithEiffelAction.class); | ||
if (existing == null) { | ||
item.addAction(this); | ||
} else { | ||
synchronized (existing.triggers) { | ||
existing.triggers.addAll(triggers); | ||
} | ||
} | ||
LOGGER.log(Level.FINE, "coalescing actions for {0}", item); | ||
} | ||
|
||
} |
74 changes: 74 additions & 0 deletions
74
...lugins/eiffel/eiffelbroadcaster/pipeline/build/BuildWithEiffelDownstreamFailureCause.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
* The MIT License | ||
* | ||
* Copyright 2019 CloudBees, Inc. | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* 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. | ||
*/ | ||
|
||
// The following code is copied from https://github.com/jenkinsci/pipeline-build-step-plugin | ||
|
||
package com.axis.jenkins.plugins.eiffel.eiffelbroadcaster.pipeline.build; | ||
|
||
import edu.umd.cs.findbugs.annotations.CheckForNull; | ||
import hudson.console.ModelHyperlinkNote; | ||
import hudson.model.Run; | ||
import hudson.model.TaskListener; | ||
import jenkins.model.CauseOfInterruption; | ||
|
||
/** | ||
* Indicates that an upstream build failed because of a downstream build’s status. | ||
*/ | ||
public final class BuildWithEiffelDownstreamFailureCause extends CauseOfInterruption { | ||
|
||
private static final long serialVersionUID = 1; | ||
|
||
private final String id; | ||
|
||
BuildWithEiffelDownstreamFailureCause(Run<?, ?> downstream) { | ||
id = downstream.getExternalizableId(); | ||
} | ||
|
||
public @CheckForNull Run<?, ?> getDownstreamBuild() { | ||
return Run.fromExternalizableId(id); | ||
} | ||
|
||
@Override public void print(TaskListener listener) { | ||
String description; | ||
Run<?, ?> downstream = getDownstreamBuild(); | ||
if (downstream != null) { | ||
// encodeTo(Run) calls getDisplayName, which does not include the project name. | ||
description = ModelHyperlinkNote.encodeTo("/" + downstream.getUrl(), downstream.getFullDisplayName()) + " completed with status " + downstream.getResult() + " (propagate: false to ignore)"; | ||
} else { | ||
description = "Downstream build was not stable (propagate: false to ignore)"; | ||
} | ||
listener.getLogger().println(description); | ||
} | ||
|
||
@Override public String getShortDescription() { | ||
Run<?, ?> downstream = getDownstreamBuild(); | ||
if (downstream != null) { | ||
return downstream.getFullDisplayName() + " completed with status " + downstream.getResult() + " (propagate: false to ignore)"; | ||
} else { | ||
return "Downstream build was not stable (propagate: false to ignore)"; | ||
} | ||
} | ||
|
||
} | ||
|
25 changes: 25 additions & 0 deletions
25
...jenkins/plugins/eiffel/eiffelbroadcaster/pipeline/build/BuildWithEiffelQueueListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// The following code is copied from https://github.com/jenkinsci/pipeline-build-step-plugin | ||
|
||
package com.axis.jenkins.plugins.eiffel.eiffelbroadcaster.pipeline.build; | ||
|
||
import hudson.AbortException; | ||
import hudson.Extension; | ||
import hudson.model.Queue; | ||
import hudson.model.queue.QueueListener; | ||
|
||
/** | ||
* @author Vivek Pandey | ||
*/ | ||
@Extension | ||
public class BuildWithEiffelQueueListener extends QueueListener { | ||
@Override | ||
public void onLeft(Queue.LeftItem li) { | ||
if(li.isCancelled()){ | ||
for (BuildWithEiffelAction.Trigger trigger : BuildWithEiffelAction.triggersFor(li)) { | ||
trigger.context.onFailure(new AbortException("Build of " + li.task.getFullDisplayName() + " was cancelled")); | ||
} | ||
} | ||
} | ||
|
||
|
||
} |
Oops, something went wrong.