How to auto-run a GitLab CI job when at least one of the jobs in the previous stage succeeds?
Asked Answered
T

1

7

Given two stages, with two jobs in the first, and one job in the second stage:

stages:
  - a
  - b

foo:
    stage: a
    when: manual

faa:
    stage: a
    when: manual

bar:
    stage: b
    when: i_dont_know

I'd like to run the second stage when at least one job in the previous stage succeeds.

The docs, however, only show the following options for when:

  • on_success - Execute job only when all jobs in earlier stages succeed, or are considered successful because they have allow_failure: true.
  • on_failure - Execute job only when at least one job in an earlier stage fails.
  • always - Execute job regardless of the status of jobs in earlier stages.

Is there some trick to achieve my goal?

Trophy answered 26/1, 2021 at 8:31 Comment(8)
Does this answer your question? CI jobs spanning multiple stagesEddy
@Adam i don't think it does. Or am I missing something?Trophy
I misread the part about either of your stage a jobs finishing and kicking off stage b, but you can use the needs keyword to start a stage b job when a specific job from stage a finishes. So in the example I posted, there are two jobs in the build stage, but linux:test in the test stage can start when linux:build is done, but before mac:build is done (or vice versa). If a job needs more than one job, both previous jobs need to be completed before this job will start. Needs lets you start stages before previous stages fully complete, but it looks like it's an AND not OR.Eddy
So for your example, the bar job might look like ``` bar: stage: b needs: foo ``` With this, bar will start as soon as foo finishes, regardless of faa's state. Not exactly your use case, but perhaps it helps?Eddy
@Adam Yeah, it's not exactly what I initially had in mind, but I think it might help to solve my concrete problem nonetheless. Thanks!Trophy
You could use yaml anchor to define two jobs, one depending on A and one depending on B. But then you'd need other external DB or calling the Gitlab API to first check if the other job has already run as not to run them if both A and B were triggered.Heeheebiejeebies
@TobiasHermann Did you find a solution to this?Helban
@Helban No, not an exact solution to the question. Instead, I temporarily went with the approach suggested by Adam Marshall in the comment above, which was ok for my use case. In the meantime, things have changed and I don't need it anymore.Trophy
L
0

I think what you want would be a DAG implementation of you GitLab CI pipeline. That way it's possible to add dependencies between jobs in order to create a acyclic graph.

minimal example:

stages:
  - a
  - b

foo:
  stage: a
  when: manual
  allow_failure: true
  script:
    - echo "hello world"

faa:
  stage: a
  when: manual
  allow_failure: true
  script:
    - echo "hello world"

bar:
  stage: b
  needs:
    - job: foo
      optional: true
    - job: FAA
      optional: true
  script:
    - echo "hello world"

This way second stage would start its execution if any of the previous stages jobs would pass, but I think this might still not be what you exactly want.

So considering your pipeline execution would contain two jobs in stage A, the example provided by me would only run jobs from second stage if both dependent jobs from A succeed. If any of the jobs is omitted and not put into the pipeline this would still work, as the dependencies are optional, but - and this is the main point - if any dependencies are specified and the corresponding jobs are part of one pipeline execution the needs will make a logical AND so all dependencies need to be fulfilled before starting the job.

If you can guarantee that one job from stage A will always be part of your pipeline you could still add this one as dependency.

If your stage B does not even rely on the previous stage there is also the possibility to provide an empty needs array, which would be equal to "start this job right away - without any regard which stage comes first"

# this job would start at the same time as jobs in stage a
job-def:
  stage: b
  script:
    - echo "hello world"
  needs: []
Lachlan answered 4/10, 2022 at 18:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.