Gitlab CI流水线 - 仅在特定条件下继续到下一个阶段

13

我正在尝试构建一个由4个作业组成的Gitlab流水线。我所拥有的阶段是:

stages:
- compare
- build
- test
- deploy

比较阶段正在从另一台服务器的API中提取数据,将其与上一次成功管道运行时相同的数据(作为工件可用)进行比较,然后进行比较。如果有任何差异,我希望管道进入下一个阶段;如果没有差异,则希望正常退出。
我已经使它正常工作,但是如果没有差异,则不会正常退出,而是失败并标记管道为失败,以下是具体实现。

enter image description here

这是我 .gitlab-ci.yaml 中重要的代码(已删除某些标识信息)

Get_inventory_dump:
  stage: compare  
  only:
    - schedules
  script: 
    - 'curl -k --output "previous-inventory.json" --header "PRIVATE-TOKEN: $user_token" "https://url/to/get/artifact/from/last/successful/run"'
    - python3 auto_config_scripts/dump_device_inventory_api_to_json.py -p $pass -o /inventory.json -u https://url/for/inventory/dump -y
    - /usr/bin/cmp previous-inventory.json inventory.json && echo "No Change in inventory since last successful run" && exit 1 || echo "Inventory has changed since last run, continue" && exit 0
  artifacts:
    when: on_success
    expire_in: 4 weeks
    paths:
     - inventory.json

Generate_icinga_config:
  stage: build
  only:
    - schedules
  when: on_success
  script: 

一切都表现得如我所预期的那样,但我觉得有更好的方法来完成这个任务。

如果比较相同,是否有一种方法可以跳过管道的下一个阶段,但仍然使管道完成为“通过”而不是“失败”?

3个回答

6
我能想到两种解决方案。不幸的是,它们都有些令人困惑的用户界面行为,或者你需要调整所有作业。
onlychanges这样的作业属性仅涉及git存储库的状态或文件(请参见https://docs.gitlab.com/ee/ci/yaml/),因此在此处无用,因为该文件仅在CI期间创建并且不是存储库的一部分。
解决方案1:您可以将allow_failure: true添加到第一个作业中。尽管作业失败,但这将标记管道为成功,并且后续作业将不会执行,因为第一个作业未成功。缺点是,在调查管道时,此作业将显示感叹号而不是绿色勾号。
解决方案2:如果没有更改,则删除inventory.json文件而不是使第一个作业失败。当文件不存在时,所有后续作业直接以退出代码0终止。请注意,这仅适用于将inventory.json标记为工件的情况。

感谢您的建议。我更喜欢解决方案2,因为即使第二、第三、第四个作业没有任何事情要做,我的管道也会始终通过。 我尝试删除inventory.json文件,但这样就无法将其作为工件提供,并因此破坏了未来的运行,所以我稍微调整了您的方法。如果它发现有差异,它会触发一个名为continue的文件,该文件可用作工件。如果文件存在,则我的下一个作业将运行一些命令;如果不存在,则什么也不做,但是会正常退出。不确定这是否容易理解,因此我将在自己的问题中附上示例代码。 - Martin W

6

根据Fzgregor的建议,这是我解决问题的方法:

如果存在差异并且我希望第二阶段实际上执行一些工作,我创建了一个名为“continue”的文件,并将其作为artifact提供。

第二阶段将查找该文件并使用IF语句来决定是否应执行某些操作或仅正常退出。

Get_inventory_dump:
  stage: compare  
  only:
    - schedules
  script: 
    - 'curl -k --output "previous-inventory.json" --header "PRIVATE-TOKEN: $user_token" "https://url/to/get/artifact/from/last/successful/run"'
    - python3 auto_config_scripts/dump_device_inventory_api_to_json.py -p $pass -o /inventory.json -u https://url/for/inventory/dump -y
    - /usr/bin/cmp previous-inventory.json inventory.json && echo "No Change in inventory since last successful run" || echo "Inventory has changed since last run, continue" && touch continue
  artifacts:
    when: on_success
    expire_in: 4 weeks
    paths:
     - inventory.json
     - continue

Generate_icinga_config:
  stage: build
  only:
    - schedules
  when: on_success
  script: 
    - if [[ -f continue ]]; then
        do some stuff;
      else
        echo "No Change in inventory, nothing to do";
      fi

这使我能够保留我的库存 artifact,同时让下一个阶段知道它是否需要做一些工作,或者只是不做任何工作并以代码0退出。

3
“Generate_icinga_config” 任务不应该有一个“dependency: Get_inventory_dump”吗? - Lei Yang

0

我有一个基本相似的结构,正在寻找基本上相同的解决方案。

当我使用allow_failure: true时,我的后续作业确实会执行。

如果我使用一个戳文件,所有后续作业也会执行,占用队列、运行者等资源,尽管它们不是必需的。

我希望有一个更简单的解决方案,但我认为我将不得不使用生成的yaml文件。这似乎是将决策等动态信息注入到管道中的唯一方法。


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