Answers: <p>FWIW, the trigger you referenced originates from Gitlab repository events, not from a GitlabCI execution.</p>
  
  <p>The only possibility (that crosses my mind) of triggering a jenkins job from inside a GitlabCI execution is by having a (custom?) <a href="https://docs.gitlab.com/ce/ci/yaml/README.html#script" rel="nofollow noreferrer">script</a> invoked as part of the GitlabCI execution which remotely activates a <a href="https://wiki.jenkins.io/display/JENKINS/Parameterized+Trigger+Plugin" rel="nofollow noreferrer">Parameterized Trigger Plugin</a> configured for your jenkins job, via a properly-crafted POST request which would include the desired parameters.</p>
  
  <p>See also <a href="https://stackoverflow.com/questions/20359810/how-to-trigger-jenkins-builds-remotely-and-to-pass-parameters">https://stackoverflow.com/questions/20359810/how-to-trigger-jenkins-builds-remotely-and-to-pass-parameters</a>.</p>
  
Answers: CC BY-SA 3.0
Answers: 2018-03-01T10:04:09.980Z
Answers: that's what I thought also...the question is now how to make gitlab-ci aware of the success/failure of the job triggered via `api`; think this is ready ootb only for the trigger that originates from gitlab repo events as you say;
Answers: pkaramol
Answers: CC BY-SA 3.0
Answers: 2018-03-01T13:48:42.910Z
Answers: Hm, that would be fully managing the jenkins job, not just triggering it... Maybe using [GitLab Runner](https://docs.gitlab.com/runner/) locally to run a custom script which triggers the jenkins job and also monitors its status until completion reporting back the result?
Answers: Dan Cornilescu
Answers: CC BY-SA 3.0
Answers: 2018-02-28T19:44:21.057Z
Answers: 2018-02-28T19:44:21.057Z
Answers: Dan Cornilescu
Answers: <p>Here's the way I do it: no plugin required, just triggering Jenkins <code>api</code> from gitlab-ci.</p>
  
  <h2>Gitlab-CI</h2>
  
  <p>I will assume you have a gitlab-ci runner installed and configured.</p>
  
  <p>First, you need to have a <code>.gitlab-ci.yml</code> file in your project having a basic structure such as:</p>
  
  <pre><code>stages:
  - my-jenkins-trigger
  variables:
   MY_VARIABLE: "EVERYTHING_IS_AWESOME"
  
  my-jenkins-trigger-job:
   stage: my-jenkins-trigger
   script: curl -i -X POST --user JENKINS_USER:JENKINS_TOKEN JENKINS_JOB_URL/buildWithParameters?MY_JENK_PARAM=${MY_VARIABLE}
  </code></pre>
  
  <p>In the above, I also assume </p>
  
  <ul>
  <li>You have a Jenkins job somewhere at URL <code>JENKINS_JOB_URL</code></li>
  <li>this Jenkins job has a build parameter called <code>MY_VARIABLE</code></li>
  <li><code>JENKINS_USER</code>, <code>JENKINS_TOKEN</code> are defined [*]</li>
  </ul>
  
  <h2>That simple?</h2>
  
  <p>Well yes, but no...</p>
  
  <p>That is the rough structure. That script will merely trigger a Jenkins job and forget about it. You need to work a little more to monitor the job and feed its status back in Gitlab-CI, manage security and possibly get some commit info from gitlab to inject into your job.</p>
  
  <h2>Monitoring</h2>
  
  <p>In order to have a proper monitoring, I recommand to write a full <em>trigger + monitor + return value</em> script [** ] (in whatever language available or you're familiar with).</p>
  
  <p>Just start by triggering the job as I stated above.</p>
  
  <p>Then, run a <code>while</code> loop (don't forget to put it to <code>sleep</code> [***]) on</p>
  
  <pre><code>curl --silent --user JENKINS_USER:JENKINS_TOKEN JENKINS_JOB_URL/lastBuild/api/json | grep result\":null &gt; /dev/null
  </code></pre>
  
  <p>until the result of this command is not <code>0</code>.</p>
  
  <p>Once the Jenkins job is finished, you would probably want to fetch the job's console in Gitlab</p>
  
  <pre><code>curl -i -X POST --user JENKINS_USER:JENKINS_TOKEN JENKINS_JOB_URL/lastBuild/consoleText
  </code></pre>
  
  <p>Finally you may <code>curl</code> once more on <code>JENKINS_JOB_URL/lastBuild/api/json</code> but this time you <code>grep</code> it on <code>UNSTABLE</code>, <code>SUCCESS</code> or <code>FAILURE</code>.</p>
  
  <h2>Discussion</h2>
  
  <p>By following the guidelines above, you can fully orchestrate Jenkins jobs from Gitlab-CI. I've posted a <a href="https://stackoverflow.com/questions/37429453/gitlab-ci-vs-jenkins/52855927#52855927">long discussion</a> on why and when should you do this.</p>
  
  <p>I hope this will help you.</p>
  
  <hr>
  
  <p>[*] Your Gitlab project Settings > CI/CD > Secret vaiables<br>
  [** ] Of course I mean by that to <strong>craft</strong> a script nicely with params, functions, nice variable names, meaningful logs... You name it.<br>
  [***] I found a <code>sleep</code> of 20 seconds worked for me</p>
  
Answers: CC BY-SA 4.0
Answers: 2020-07-07T13:07:55.133Z
Answers: Can you post a complete example that includes monitoring?
Answers: jimkont
Answers: CC BY-SA 4.0
Answers: 2020-07-07T13:12:37.900Z
Answers: It's a while loop, and i could not know your functional. I didn't write out a full example on purpose. I think it would be great if you could do your own!
Answers: avi.elkharrat
Answers: CC BY-SA 4.0
Answers: 2021-10-28T09:10:57.110Z
Answers: been searching for the "monitoring" parts, I thought it's simple as waiting for the response :D Thanks for sharing this!
Answers: mochadwi
Answers: CC BY-SA 4.0
Answers: 2023-03-14T08:34:19.047Z
Answers: Thanks for the explanation. I just wanted to add (something probably obvious) to "until the result of this command is not 0" - you may want to implement a timeout here.
Answers: Matthias W.
Answers: CC BY-SA 4.0
Answers: 2018-11-02T11:39:51.297Z
Answers: 2018-11-02T11:39:51.297Z
Answers: avi.elkharrat
Answers: <p>I use a similar setup as <a href="https://devops.stackexchange.com/a/5313/35579">this answer</a>.</p>
  <p>Difference is <strong>I cannot poll the latest job because it may refer to a job I didn't start</strong>. So instead I get the queue ID from the response headers when triggering a job, and match that with the queue ID of most recent job runs.</p>
  <p>I did this in Python because it makes things a bit easier, but it could also be done using sh.</p>
  <p>GitLab CI config:</p>
  <pre class="lang-yaml prettyprint-override"><code>Test:
    stage: test
    script:
      - run_jenkins_job.py
        --docker-image &quot;${CI_REGISTRY_IMAGE}&quot;
        --display-name &quot;Test ${CI_COMMIT_REF_SLUG}&quot;
  </code></pre>
  <p>run_jenkins_job.py:</p>
  <pre class="lang-py prettyprint-override"><code>#!/usr/bin/env python3
  import argparse
  import sys
  import time
  
  import requests
  
  JENKINS_JOB_URL = &quot;https://jenkins.example.org/job/MYJOB&quot;
  JOB_BUILD_TOKEN = &quot;MYJOBTOKEN&quot;
  
  api_req = requests.Session()
  api_req.headers.update(
      {
          &quot;Authorization&quot;: &quot;Basic BASIC_USER_AUTH&quot;,
          &quot;Content-Type&quot;: &quot;application/x-www-form-urlencoded&quot;,
      }
  )
  
  
  def main():
      parser = argparse.ArgumentParser(description=&quot;Run a GitLab MR job on Jenkins and poll for the result.&quot;)
      parser.add_argument(&quot;--docker-image&quot;, required=True, type=str)
      parser.add_argument(&quot;--display-name&quot;, required=True, type=str)
      args = parser.parse_args(sys.argv[1:])
  
      queue_id = schedule_build(args)
      exit_code = poll_build(queue_id)
      sys.exit(exit_code)
  
  
  def schedule_build(args: argparse.Namespace) -&gt; int:
      response = api_req.post(
          f&quot;{JENKINS_JOB_URL}/buildWithParameters?token={JOB_BUILD_TOKEN}&quot;,
          data={
              &quot;docker_image&quot;: args.docker_image,
              &quot;display_name&quot;: args.display_name,
          },
      )
      response.raise_for_status()
      location_header_value = response.headers[&quot;Location&quot;]
      # Example location header: &quot;https://jenkins.example.org/queue/item/123/&quot;
      return int(location_header_value.rstrip(&quot;/&quot;).split(&quot;/&quot;)[-1])
  
  
  def poll_build(queue_id: int) -&gt; int:
      job_url_shown = False
  
      for _ in range(300):
          time.sleep(15)
          response = api_req.get(f&quot;{JENKINS_JOB_URL}/api/json?tree=builds[result,queueId,url]&quot;)
          response.raise_for_status()
  
          for build in response.json()[&quot;builds&quot;]:
              if build[&quot;queueId&quot;] != queue_id:
                  continue
              elif build[&quot;result&quot;] is None:
                  if not job_url_shown:
                      # Scheduled job first appeared; show URL.
                      print(f&quot;\nRunning: {build['url']}\n&quot;)
                      job_url_shown = True
                  print(&quot;.&quot;, end=&quot;&quot;, flush=True)
              else:
                  if build[&quot;result&quot;] == &quot;SUCCESS&quot;:
                      return 0
                  else:
                      return 1
  
  
  if __name__ == &quot;__main__&quot;:
      main()
  </code></pre>
  
Answers: CC BY-SA 4.0
Answers: 2022-06-05T10:33:10.260Z
Answers: 2022-06-05T10:33:10.260Z
Answers: Blaise
Answers: <p>If you want to keep it simple, try the generic webhook trigger plugin.</p>
  
  <p><a href="https://plugins.jenkins.io/generic-webhook-trigger" rel="nofollow noreferrer">https://plugins.jenkins.io/generic-webhook-trigger</a></p>
  
  <p>You can trigger a build by sending an http POST using a JSON body or URL parameters.</p>
  
  <p><a href="https://i.sstatic.net/e5Zod.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/e5Zod.png" alt="generic-webhook-trigger"></a></p>
  
  <p>Parse the JSON request</p>
  
  <pre><code>def req = readJSON text: payload
  </code></pre>
  
  <p>Now you can use it in your pipeline assuming you had a deploy function.</p>
  
  <pre><code>deploy(req.environment, req.branch)
  </code></pre>
  
  <p>I must agree with @Tensibai. Two CI/CD systems on the surface does seem overly complex. You might want to consider sticking with one if possible.</p>
  
Answers: CC BY-SA 3.0
Answers: 2018-03-01T19:10:53.827Z
Answers: 2018-03-01T19:10:53.827Z
Answers: casey vega
Body: <p>There is supposed to be a <a href="https://docs.gitlab.com/ee/integration/jenkins.html" rel="noreferrer">way</a> to trigger a Jenkins job via GitlabCi, using the respective plugin.</p>
  
  <p>My question is whether there is a way:</p>
  
  <p>a) to trigger a parameterized Jenkins job</p>
  
  <p>b) to pass parameters when triggering the job</p>
  
Comments: CC BY-SA 3.0
Comments: 2018-02-28T23:33:17.160Z
Comments: What are the parameters you want to pass? What action causes a trigger?
Comments: casey vega
Comments: CC BY-SA 3.0
Comments: 2018-03-01T09:00:02.410Z
Comments: At some point I want a `gitlab-ci` job to invoke jenkins to perform a deployment on an orchestrator (`Rancher`). The parameters will be the name of the environment and the repo-branch from which the checkout of the code will be performed (so that the images to be deployed are built)
Comments: pkaramol
Comments: CC BY-SA 3.0
Comments: 2018-03-01T15:15:51.453Z
Comments: Why do you want to chain two CI systems ? I can't really understand it as gitlab-ci can directly trigger deployments on k8s clusters,so adding jenkins in the middle sounds more adding complexity than helping the situation.
Comments: Tensibai
Tags: <jenkins><continuous-integration><gitlab>
Title: Trigger Jenkins job from Gitlab CI with parameters
UserDisplayName: pkaramol
ThreadText: # Trigger Jenkins job from Gitlab CI with parameters
  
  (Asked by: username_0 on 2018-02-25)
  
  There is supposed to be a [way](https://docs.gitlab.com/ee/integration/jenkins.html) to trigger a Jenkins job via GitlabCi, using the respective plugin.
  
  My question is whether there is a way:
  
  a) to trigger a parameterized Jenkins job
  
  b) to pass parameters when triggering the job
  
  **Tags:** jenkins, continuous-integration, gitlab
  
  > **Comments:**
  > **username_1**: What are the parameters you want to pass? What action causes a trigger?  
  > **username_0**: At some point I want a `gitlab-ci` job to invoke jenkins to perform a deployment on an orchestrator (`Rancher`). The parameters will be the name of the environment and the repo-branch from which the checkout of the code will be performed (so that the images to be deployed are built)  
  > **username_2**: Why do you want to chain two CI systems ? I can't really understand it as gitlab-ci can directly trigger deployments on k8s clusters,so adding jenkins in the middle sounds more adding complexity than helping the situation.  
  
  ---
  
  ## 4 answers
  
  ### Answer by username_4 on 2018-11-02. Score: 11
  
  Here's the way I do it: no plugin required, just triggering Jenkins `api` from gitlab-ci.
  
  ## Gitlab-CI
  
  I will assume you have a gitlab-ci runner installed and configured.
  
  First, you need to have a `.gitlab-ci.yml` file in your project having a basic structure such as:
  
  ```
  stages:
  - my-jenkins-trigger
  variables:
   MY_VARIABLE: "EVERYTHING_IS_AWESOME"
  
  my-jenkins-trigger-job:
   stage: my-jenkins-trigger
   script: curl -i -X POST --user JENKINS_USER:JENKINS_TOKEN JENKINS_JOB_URL/buildWithParameters?MY_JENK_PARAM=${MY_VARIABLE}
  
  ```
  
  In the above, I also assume
  
  * You have a Jenkins job somewhere at URL `JENKINS_JOB_URL`
  * this Jenkins job has a build parameter called `MY_VARIABLE`
  * `JENKINS_USER`, `JENKINS_TOKEN` are defined [\*]
  
  ## That simple?
  
  Well yes, but no...
  
  That is the rough structure. That script will merely trigger a Jenkins job and forget about it. You need to work a little more to monitor the job and feed its status back in Gitlab-CI, manage security and possibly get some commit info from gitlab to inject into your job.
  
  ## Monitoring
  
  In order to have a proper monitoring, I recommand to write a full *trigger + monitor + return value* script [\*\* ] (in whatever language available or you're familiar with).
  
  Just start by triggering the job as I stated above.
  
  Then, run a `while` loop (don't forget to put it to `sleep` [\*\*\*]) on
  
  ```
  curl --silent --user JENKINS_USER:JENKINS_TOKEN JENKINS_JOB_URL/lastBuild/api/json | grep result\":null > /dev/null
  
  ```
  
  until the result of this command is not `0`.
  
  Once the Jenkins job is finished, you would probably want to fetch the job's console in Gitlab
  
  ```
  curl -i -X POST --user JENKINS_USER:JENKINS_TOKEN JENKINS_JOB_URL/lastBuild/consoleText
  
  ```
  
  Finally you may `curl` once more on `JENKINS_JOB_URL/lastBuild/api/json` but this time you `grep` it on `UNSTABLE`, `SUCCESS` or `FAILURE`.
  
  ## Discussion
  
  By following the guidelines above, you can fully orchestrate Jenkins jobs from Gitlab-CI. I've posted a [long discussion](https://stackoverflow.com/questions/37429453/gitlab-ci-vs-jenkins/52855927#52855927) on why and when should you do this.
  
  I hope this will help you.
  
  ---
  
  [\*] Your Gitlab project Settings > CI/CD > Secret vaiables  
  [\*\* ] Of course I mean by that to **craft** a script nicely with params, functions, nice variable names, meaningful logs... You name it.  
  [\*\*\*] I found a `sleep` of 20 seconds worked for me
  
  > **Comments:**
  > **username_5**: Can you post a complete example that includes monitoring?  
  > **username_4**: It's a while loop, and i could not know your functional. I didn't write out a full example on purpose. I think it would be great if you could do your own!  
  > **username_6**: been searching for the "monitoring" parts, I thought it's simple as waiting for the response :D Thanks for sharing this!  
  > **username_7**: Thanks for the explanation. I just wanted to add (something probably obvious) to "until the result of this command is not 0" - you may want to implement a timeout here.  
  
  ---
  
  ### Answer by username_3 on 2018-02-28. Score: 3
  
  FWIW, the trigger you referenced originates from Gitlab repository events, not from a GitlabCI execution.
  
  The only possibility (that crosses my mind) of triggering a jenkins job from inside a GitlabCI execution is by having a (custom?) [script](https://docs.gitlab.com/ce/ci/yaml/README.html#script) invoked as part of the GitlabCI execution which remotely activates a [Parameterized Trigger Plugin](https://wiki.jenkins.io/display/JENKINS/Parameterized+Trigger+Plugin) configured for your jenkins job, via a properly-crafted POST request which would include the desired parameters.
  
  See also <https://stackoverflow.com/questions/20359810/how-to-trigger-jenkins-builds-remotely-and-to-pass-parameters>.
  
  > **Comments:**
  > **username_0**: that's what I thought also...the question is now how to make gitlab-ci aware of the success/failure of the job triggered via `api`; think this is ready ootb only for the trigger that originates from gitlab repo events as you say;  
  > **username_3**: Hm, that would be fully managing the jenkins job, not just triggering it... Maybe using [GitLab Runner](https://docs.gitlab.com/runner/) locally to run a custom script which triggers the jenkins job and also monitors its status until completion reporting back the result?  
  
  ---
  
  ### Answer by username_8 on 2022-06-05. Score: 0
  
  I use a similar setup as [this answer](https://devops.stackexchange.com/a/5313/35579).
  
  Difference is **I cannot poll the latest job because it may refer to a job I didn't start**. So instead I get the queue ID from the response headers when triggering a job, and match that with the queue ID of most recent job runs.
  
  I did this in Python because it makes things a bit easier, but it could also be done using sh.
  
  GitLab CI config:
  
  ```yaml
  Test:
    stage: test
    script:
      - run_jenkins_job.py
        --docker-image "${CI_REGISTRY_IMAGE}"
        --display-name "Test ${CI_COMMIT_REF_SLUG}"
  
  ```
  
  run\_jenkins\_job.py:
  
  ```py
  #!/usr/bin/env python3
  import argparse
  import sys
  import time
  
  import requests
  
  JENKINS_JOB_URL = "https://jenkins.example.org/job/MYJOB"
  JOB_BUILD_TOKEN = "MYJOBTOKEN"
  
  api_req = requests.Session()
  api_req.headers.update(
      {
          "Authorization": "Basic BASIC_USER_AUTH",
          "Content-Type": "application/x-www-form-urlencoded",
      }
  )
  
  def main():
      parser = argparse.ArgumentParser(description="Run a GitLab MR job on Jenkins and poll for the result.")
      parser.add_argument("--docker-image", required=True, type=str)
      parser.add_argument("--display-name", required=True, type=str)
      args = parser.parse_args(sys.argv[1:])
  
      queue_id = schedule_build(args)
      exit_code = poll_build(queue_id)
      sys.exit(exit_code)
  
  def schedule_build(args: argparse.Namespace) -> int:
      response = api_req.post(
          f"{JENKINS_JOB_URL}/buildWithParameters?token={JOB_BUILD_TOKEN}",
          data={
              "docker_image": args.docker_image,
              "display_name": args.display_name,
          },
      )
      response.raise_for_status()
      location_header_value = response.headers["Location"]
      # Example location header: "https://jenkins.example.org/queue/item/123/"
      return int(location_header_value.rstrip("/").split("/")[-1])
  
  def poll_build(queue_id: int) -> int:
      job_url_shown = False
  
      for _ in range(300):
          time.sleep(15)
          response = api_req.get(f"{JENKINS_JOB_URL}/api/json?tree=builds[result,queueId,url]")
          response.raise_for_status()
  
          for build in response.json()["builds"]:
              if build["queueId"] != queue_id:
                  continue
              elif build["result"] is None:
                  if not job_url_shown:
                      # Scheduled job first appeared; show URL.
                      print(f"\nRunning: {build['url']}\n")
                      job_url_shown = True
                  print(".", end="", flush=True)
              else:
                  if build["result"] == "SUCCESS":
                      return 0
                  else:
                      return 1
  
  if __name__ == "__main__":
      main()
  
  ```
  
  
  ---
  
  ### Answer by username_1 on 2018-03-01. Score: 0
  
  If you want to keep it simple, try the generic webhook trigger plugin.
  
  <https://plugins.jenkins.io/generic-webhook-trigger>
  
  You can trigger a build by sending an http POST using a JSON body or URL parameters.
  
  [![generic-webhook-trigger](https://i.sstatic.net/e5Zod.png)](https://i.sstatic.net/e5Zod.png)
  
  Parse the JSON request
  
  ```
  def req = readJSON text: payload
  
  ```
  
  Now you can use it in your pipeline assuming you had a deploy function.
  
  ```
  deploy(req.environment, req.branch)
  
  ```
  
  I must agree with @username_2. Two CI/CD systems on the surface does seem overly complex. You might want to consider sticking with one if possible.
  
  
  ---
  
  