The fact that Copy Artifacts fails 50% of the time when running from a
manual trigger in the Build Pipeline Plugin has been driving me crazy,
so in good open source denizen style I am trying to fix it.  Turns out
there's a larger underlying problem that I need some advice on.

When the job is manually triggered in the Build Pipeline plugin there
are two causes-- the upstream job and the user who triggered the run.
In BuildPipelineView.triggerBuild(), AbstractProject.scheduleBuild is
ultimately called with a cause of Cause.UpstreamCause, but also with a
CauseAction(new MyUserIdCause()) in the Actions passed to it.  Copy
Artifact uses Run.getCauses() which uses
Run.getAction(CauseAction.class).  GetAction returns only the first
action, so if the CauseAction with UpstreamCause comes first, it
works.  Otherwise it fails to copy.

Various solutions:

1 -- As suggested on JENKINS-14656, put both causes under the same
CauseAction.  The problem is that one of the Causes is created by
AbstractProject.scheduleBuild and there's no way to inject the
MyUserIdCause.  AbstractProject could be extended to allow a
Collection of Causes easily enough.

2-- Change Copy artifact to use Run.getActions(CauseAction.class) and
iterate over the contained actions, itself, until it finds an
UpstreamCause.

3-- Change Run.getCauses() to call Run.getActions(CauseAction.class)
and merge them all.

Questions:

Seems like some things implicitly assume that there is only ever one
CauseAction.  Is this a valid constraint?  If so, then #1 makes sense
and there should be guards against multiple CauseActions.

If multiple CauseActions are allowed, should convenience functions
like getCauses() merge them into one view?  If so, then #3 makes
sense, otherwise #2.

Any ramifications of any of these approaches?


Thanks!

Reply via email to