gitlab ci:手动或仅在 master 时运行构建作业

Posted

技术标签:

【中文标题】gitlab ci:手动或仅在 master 时运行构建作业【英文标题】:gitlab ci: Run build job when manual or when master only 【发布时间】:2018-05-19 00:07:10 【问题描述】:

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

手动执行 或 被主推执行

我想过这样的事情,但这是很错误的:

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

对我来说唯一的解决方案是拥有两份工作,一份用于主推,一份用于手动输入。但缺点是,在gitlab中会变得比较混乱

【问题讨论】:

【参考方案1】:

我也没有找到一种方法在一个块中执行此操作,不得不使用 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 using rules 开始合二为一

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

【讨论】:

据我了解,rules 下没有直接规则- when: manual,如果我错了,请纠正我,但从文档和gitlab.com/gitlab-org/gitlab/-/issues/27863 来看,when: manual 操作必须是直接的在作业名称下,或(自 12.3 起)在 if 规则下。 这些规则为我产生了奇怪的二级“阻塞”管道。 @HeikoG 我认为它们并不“奇怪”,而是意料之中。鉴于推送的操作(提交、PR/MR、...) 匹配规则(例如分支名称),仍然可以选择通过管道阻塞。【参考方案2】:

使用 GitLab 11.3 中的 extends configuration parameter 可以更轻松地定义两个作业。它是使用 YAML 锚点的替代方案,并且更加灵活和可读:

.deploy_common:
  # common config

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

deploy_manual:
  extends: .deploy_common
  when: manual

【讨论】:

非常好,感谢您提出这个解决方案!现在应该是公认的答案!【参考方案3】:

我自己也遇到过这个问题,终于弄明白了(或者想出了一个适合我需要的可行版本):

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'd 在一起,所以当它在 master 分支上或从 web 启动时运行作业(在我的情况下可与“manual”互换)。这不会像 'when:manual' 那样暂停管道,但我不希望它这样做。

这里是文档:https://docs.gitlab.com/ee/ci/yaml/#only-and-except-complex 和 https://docs.gitlab.com/ee/ci/variables/

希望这会有所帮助!

【讨论】:

我认为这不起作用:在 gitlab 11.6.8 中,我尝试创建一个未命名为“master”的分支,并且该作业在 Web UI 中不可见,但对于名为“掌握”。所以我猜$CI_PIPELINE_SOURCE == "web" 不足以让工作在 Web UI 中可见。【参考方案4】:

目前无法获得您想要的确切内容。虽然这 2 个工作(一个使用 only: master 和另一个使用 when: manual 应该提供替代方案。

如果你把它们放在同一个阶段,我猜应该不会那么混乱。

你也可以使用一些special yaml features 像anchors 来保持DRY。

【讨论】:

【参考方案5】:

我不得不使用它来避免产生额外的“阻塞”管道。

- 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

【讨论】:

以上是关于gitlab ci:手动或仅在 master 时运行构建作业的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Gitlab CI 管道始终运行一些作业,而其他作业仅在合并请求上运行?

合并后将gitlab-ci.yml中的include-ref更改为master?

GitLab CI 手动启动作业(部署)

如何在 Gitlab CI 上修复 'Rugged::ReferenceError: revspec 'origin/master' not found'

如何使手动作业始终在 GitLab CI 上成功退出?

GitLab 仅手动而不是自动运行管道