56

Is it possible to have a gitlab-ci file wheres a build job defined with the following requirements:

  • get executed when manual OR
  • get executed by master push

I thought of something like this, but this is poorly false:

build_jar:
stage: build
script:
  - echo "build jar"
artifacts:
  paths:
    - jar/path/*.jar
only:
  - master
when: manual

Only solution for me is to have two jobs, one for the master push and one a manual input. But the disadvantage is, that in gitlab it becomes confusingly

toni_maccaroni
  • 563
  • 1
  • 4
  • 6

6 Answers6

76

I also did not find a way to do this in one block and had to use yaml anchors and split into two separate blocks:

.deploy_common:
# common config HERE

deploy_master_CD:
  extends: .deploy_common
  only:
    refs:
      - master

deploy_manual:
  extends: .deploy_common
  when: manual

OR all in one since GitLab 12.3 using rules

deploy:
  rules:
    - if: '$CI_COMMIT_REF_NAME == "master"'
    - when: manual
lukmdo
  • 7,489
  • 5
  • 30
  • 23
  • 5
    From my understanding there is no direct rule `- when: manual` under `rules`, correct me if I am wrong, but from the documentation and https://gitlab.com/gitlab-org/gitlab/-/issues/27863, the `when: manual` action has to be either directly under the job name, or (since 12.3) under a `if` rule. – CyberMew Jun 04 '20 at 18:38
  • 6
    these rules produced weird secondary "blocked" pipelines for me. – HeikoG Mar 01 '21 at 17:07
  • 2
    @HeikoG I don't think they are "weird" but expected. Given an action (commit, PR/MR, ...) is pushed that does **not** match the rules (e.g. branch name), there is still the option to trigger the pipeline on that exact action via the blocked pipeline. – prohit Dec 16 '21 at 16:53
16

Defining two jobs become easier with the extends configuration parameter in GitLab 11.3. It is an alternative to using YAML anchors and is a little more flexible and readable:

.deploy_common:
  # common config

deploy_master_CD:
  extends: .deploy_common
  only:
    refs:
      - master

deploy_manual:
  extends: .deploy_common
  when: manual
mrts
  • 16,697
  • 8
  • 89
  • 72
13

Had this problem myself, finally figured it out (or figured out a workable version for my needs, anyway):

build_jar:
  stage: build
  script:
    - echo "build jar"
  artifacts:
    paths:
      - jar/path/*.jar
  only:
    variables:
    - $CI_PIPELINE_SOURCE == "web"
    - $CI_COMMIT_REF_NAME == "master"

The conditions under the variables block are OR'd together, so this runs the job when it is either on master branch, or started from the web (interchangeable with 'manual', in my case). This doesn't pause the pipeline like 'when:manual' does, but I didn't want it to do that anyway.

Here are the docs: https://docs.gitlab.com/ee/ci/yaml/#only-and-except-complex and https://docs.gitlab.com/ee/ci/variables/

Hopefully this helps!

timlyo
  • 2,086
  • 1
  • 23
  • 35
Drew Tabor
  • 131
  • 1
  • 2
  • 3
    I think this does not work: In gitlab 11.6.8 I tried to create a branch not named "master" and the job was not visible in the web UI, but it became visible for a branch named "master". So I guess `$CI_PIPELINE_SOURCE == "web"` is not sufficient to make the job visible inside the web UI. – Gabriel Devillers Feb 01 '19 at 11:10
10

I had to use this to avoid additional "blocked" pipelines to be spawned.

- if: '$CI_MERGE_REQUEST_EVENT_TYPE == "detached"' # Avoid spawning of additional pipelines
  when: never
- if: '$CI_MERGE_REQUEST_ID != ""' # Force manual deploy if master was pushed without a MR
  when: manual
  allow_failure: true # to avoid blocked state for the whole pipeline
- if: '$CI_COMMIT_REF_SLUG == "master"' # Auto deploy on master
  when: on_success
- when: manual # Manually deploy on all other branches
  allow_failure: true # to avoid blocked state for the whole pipeline
HeikoG
  • 861
  • 10
  • 11
5

The exact thing you want is not possible at the moment. Though the 2 jobs (one with only: master and the other with when: manual should provide an alternative.

If you put them in the same stage it shouldn't be that confusing I guess.

You could also use some special yaml features like anchors to stay DRY.

Stefan van Gastel
  • 4,330
  • 23
  • 25
1

Adding the second if: line below worked for me. Prior to that, I could only build main or PRs.

workflow:
  rules:
    - if: '$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH || $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_JOB_MANUAL == "true"'
    - if: '$CI_PIPELINE_SOURCE == "web" || $CI_JOB_MANUAL == "true"'
MarkHu
  • 1,694
  • 16
  • 29