CauseAction is a foldable action, meaning that if two CauseActions are present in the build they should be folded into one CauseAction object containing both Cause objects. I had a similar issue in the Gerrit Trigger plugin where my code assumed that there would only be one GerritCause of the build, but needed to make changes to that in order to handle multiple causes in the plugin. So if two CauseActions aren't folded into each other correctly I would consider that a bug in core, and IMHO plugins needs to handle that there could be several causes of a build.
Robert Sandell Software Tools Engineer - SW Environment and Product Configuration Sony Mobile Communications > -----Original Message----- > From: [email protected] [mailto:jenkinsci- > [email protected]] On Behalf Of Jason Wagner > Sent: den 17 december 2012 04:15 > To: Jenkins Developers > Subject: How to handle multiple CauseActions on a single build. > > 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!
