GitLab CI:手动或仅在主分支时运行构建作业

58

是否可以有一个gitlab-ci文件,其中定义了以下要求的构建作业:

  • 手动执行时执行 或
  • 由主分支推送执行

我想到了这样的东西,但这是错误的:

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

我唯一的解决办法是同时拥有两个工作,一个用于主推送,另一个则手动输入。但缺点是,在GitLab中会变得混乱。

6个回答

79

我也没有找到一次性完成这个任务的方法,不得不使用yaml锚点并将其拆分为两个独立的块:

我也无法在一个块中实现此操作,必须使用YAML锚点,并将其拆分为两个独立的块:

.deploy_common:
# common config HERE

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

deploy_manual:
  extends: .deploy_common
  when: manual

GitLab 12.3版本起,可以使用规则(rules)来实现“全部”。

deploy:
  rules:
    - if: '$CI_COMMIT_REF_NAME == "master"'
    - when: manual

5
据我理解,在“规则”下没有直接规则“- when: manual”,如果我错了,请纠正我,但是从文档和https://gitlab.com/gitlab-org/gitlab/-/issues/27863可以得知,“when: manual”操作必须直接位于作业名称下方,或者(自12.3版本以来)位于“if”规则下方。 - CyberMew
7
这些规则对我产生了奇怪的次要“阻塞”管道。 - HeikoG
3
@HeikoG 我认为它们并不“奇怪”,而是预期的。如果出现与规则(例如分支名称)不匹配的操作(提交、PR / MR等),仍然可以通过被阻止的管道在该精确操作上触发管道。 - prohit

17

使用GitLab 11.3中的extends配置参数可以更轻松地定义两个作业。它是使用YAML锚点的一种替代方案,更加灵活易读:

.deploy_common:
  # common config

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

deploy_manual:
  extends: .deploy_common
  when: manual

13

我自己也遇到了这个问题,最终找到了解决办法(或者说是为我的需求找到了可行的版本):

build_jar:
  stage: build
  script:
    - echo "build jar"
  artifacts:
    paths:
      - jar/path/*.jar
  only:
    variables:
    - $CI_PIPELINE_SOURCE == "web"
    - $CI_COMMIT_REF_NAME == "master"
变量块下的条件是OR逻辑,所以当它在主分支上或从Web(在我的情况下可与'manual'互换)启动时运行作业。这不像'when:manual'一样暂停管道,但我也不希望它这样做。
这里是文档:https://docs.gitlab.com/ee/ci/yaml/#only-and-except-complexhttps://docs.gitlab.com/ee/ci/variables/ 希望这能有所帮助!

3
我认为这个方法行不通:在GitLab 11.6.8中,我尝试创建一个非“master”命名的分支,但这份工作在Web UI上看不到,只有当命名为"master"时才会出现。因此,我猜测$ CI_PIPELINE_SOURCE == "web"不足以使该工作在Web UI中可见。 - Gabriel Devillers

10

我不得不使用这个方法来避免生成额外的“被阻止”的管道。

- 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

5
目前无法做到你想要的确切事情。虽然使用一个带有only: master的工作和另一个带有when: manual的工作可能提供一种替代方法。如果将它们放在同一个阶段中,应该不会那么令人困惑。你还可以使用一些特殊的yaml功能,例如锚点来保持DRY

1

在下面添加第二个if语句后,这对我很有效。 在此之前,我只能构建main或PR。

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"'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接