<blockquote>
<p>Is there an 'UpstreamCause' equivalent to the example for 'UserIdCause' that would allow me to specify which upstream cause should trigger a specific stage?</p>
</blockquote>
<p>Unfortunately, not in native Declarative syntax.</p>
<p>As you can see <a href="https://github.com/jenkinsci/pipeline-model-definition-plugin/blob/c07035710d1996ff570f1cdb86d6a20d8a2702f7/pipeline-model-definition/src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/Utils.groovy#L277-L291" rel="nofollow noreferrer">from the source code</a>, UserIdCause is special-cased, but no other cause is:</p>
<pre><code>    static boolean shouldRunBeAllowed(Cause causeClass, String cause, String detail){
        if( causeClass instanceof Cause.UserIdCause &amp;&amp; Cause.UserIdCause.simpleName == cause){
            return detail == null || causeClass.userId == detail
        }else {
            return causeClass.class.simpleName.matches(&quot;(?i)\\.*${cause}.*&quot;)
        }
    }
</code></pre>
<p>So if you want to trigger conditionally based on which job triggered the build, you'll need to use Scripted syntax. For instance (I haven't tested this so no guarantees it will work without debugging):</p>
<pre><code>script {
  def myJob = 'put-your-job-name-here'
  def causes = currentBuild.rawBuild.getCauses()
  def triggeredByMyJob = causes.any { cause-&gt;
    cause.class.toString().contains(&quot;UpstreamCause&quot;)) &amp;&amp; cause.upstreamProject == myJob
  }

  if (triggeredByMyJob) {
    // put steps to execute when triggered by your job here
  } else {
    // put steps to execute when NOT triggered by your job here
  }
} 
</code></pre>
<p>However, there's potentially a much easier way, although it's not strictly what you asked for:  Give your downstream job a boolean parameter, for the sake of example let's call it <code>runMyStages</code>, and use a <code>when</code> clause to conditionally execute stages based on whether <code>runMyStages</code> is true or false.  Then in your upstream jobs, you can set that parameter in your build step: <code>build(job: 'downstream-job-name', parameters: [booleanParam('runMyStages', false)])</code>.</p>

CC BY-SA 4.0
2021-02-24T13:34:43.277Z
The second idea is interesting, but the way our jobs are currently structured I have the upstream triggers defined in the downstream job, rather than using a `build` step in the upstream jobs. I might try using the first approach at the start of my job and setting some environment variables based on each upstream cause found, so that I can look at those in a `when` for each stage.
c32hedge
CC BY-SA 4.0
2021-02-23T17:53:53.637Z
2021-02-23T17:53:53.637Z
jayhendren
<p>I have a job defined as a declarative pipeline that gets triggered by a number of different upstream jobs. Depending on which upstream job triggered my job, I don't necessarily need to run all of the stages in my pipeline, so I want to specify a list of triggers for each stage.</p>
<p>I was hoping to use a <code>when</code> clause and <code>triggeredBy</code> conditions to determine when each stage runs, but the <a href="https://www.jenkins.io/doc/book/pipeline/syntax/#declarative-pipeline" rel="nofollow noreferrer">documentation</a> isn't very detailed:</p>
<blockquote>
<p>triggeredBy</p>
<p>Execute the stage when the current build has been triggered by the param given. For example:</p>
<p>when { triggeredBy 'SCMTrigger' }</p>
<p>when { triggeredBy 'TimerTrigger' }</p>
<p>when { triggeredBy 'UpstreamCause' }</p>
<p>when { triggeredBy cause: &quot;UserIdCause&quot;, detail: &quot;vlinde&quot; }</p>
</blockquote>
<p>Is there an <code>'UpstreamCause'</code> equivalent to the example for <code>'UserIdCause'</code> that would allow me to specify <em>which</em> upstream cause should trigger a specific stage? If so, what is the exact syntax? Basically I want to do something like:</p>
<pre><code>when {
    anyOf {
        triggeredBy cause: 'UpstreamCause', detail: 'Job A'
        triggeredBy cause: 'UpstreamCause', detail: 'Job C'
    }
}
</code></pre>
<p>I'm also open to other approaches for accomplishing this.</p>

<jenkins-pipeline><jenkinsfile>
How can I add a when clause for a specific upstream trigger in a Jenkins declarative pipeline?
c32hedge
# How can I add a when clause for a specific upstream trigger in a Jenkins declarative pipeline?

(Asked by: username_0 on 2021-02-21)

I have a job defined as a declarative pipeline that gets triggered by a number of different upstream jobs. Depending on which upstream job triggered my job, I don't necessarily need to run all of the stages in my pipeline, so I want to specify a list of triggers for each stage.
I was hoping to use a when clause and triggeredBy conditions to determine when each stage runs, but the documentation isn't very detailed:

triggeredBy
Execute the stage when the current build has been triggered by the param given. For example:
when { triggeredBy 'SCMTrigger' }
when { triggeredBy 'TimerTrigger' }
when { triggeredBy 'UpstreamCause' }
when { triggeredBy cause: "UserIdCause", detail: "vlinde" }

Is there an 'UpstreamCause' equivalent to the example for 'UserIdCause' that would allow me to specify which upstream cause should trigger a specific stage? If so, what is the exact syntax? Basically I want to do something like:
when {
    anyOf {
        triggeredBy cause: 'UpstreamCause', detail: 'Job A'
        triggeredBy cause: 'UpstreamCause', detail: 'Job C'
    }
}

I'm also open to other approaches for accomplishing this.

**Tags:** jenkins-pipeline, jenkinsfile


---

## 1 answers

### Answer by username_1 on 2021-02-23. Score: 1

Is there an 'UpstreamCause' equivalent to the example for 'UserIdCause' that would allow me to specify which upstream cause should trigger a specific stage?

Unfortunately, not in native Declarative syntax.
As you can see from the source code, UserIdCause is special-cased, but no other cause is:
    static boolean shouldRunBeAllowed(Cause causeClass, String cause, String detail){
        if( causeClass instanceof Cause.UserIdCause && Cause.UserIdCause.simpleName == cause){
            return detail == null || causeClass.userId == detail
        }else {
            return causeClass.class.simpleName.matches("(?i)\\.*${cause}.*")
        }
    }

So if you want to trigger conditionally based on which job triggered the build, you'll need to use Scripted syntax. For instance (I haven't tested this so no guarantees it will work without debugging):
script {
  def myJob = 'put-your-job-name-here'
  def causes = currentBuild.rawBuild.getCauses()
  def triggeredByMyJob = causes.any { cause->
    cause.class.toString().contains("UpstreamCause")) && cause.upstreamProject == myJob
  }

  if (triggeredByMyJob) {
    // put steps to execute when triggered by your job here
  } else {
    // put steps to execute when NOT triggered by your job here
  }
} 

However, there's potentially a much easier way, although it's not strictly what you asked for:  Give your downstream job a boolean parameter, for the sake of example let's call it runMyStages, and use a when clause to conditionally execute stages based on whether runMyStages is true or false.  Then in your upstream jobs, you can set that parameter in your build step: build(job: 'downstream-job-name', parameters: [booleanParam('runMyStages', false)]).

> **Comments:**
> **username_0**: The second idea is interesting, but the way our jobs are currently structured I have the upstream triggers defined in the downstream job, rather than using a `build` step in the upstream jobs. I might try using the first approach at the start of my job and setting some environment variables based on each upstream cause found, so that I can look at those in a `when` for each stage.  

---

