簡體   English   中英

如何讓 Gitlab CI 管道始終運行某些作業而僅在合並請求上運行其他作業?

[英]How to have a Gitlab CI Pipeline run some jobs always and other jobs only on merge-requests?

TL/DR:我的目標是擁有一個 Gitlab (CE-12.4.2) 管道,該管道僅在合並請求和其他作業上執行某些作業(在合並請求和所有正常推送上)。 .gitlab-ci.yml必須如何做到這一點?

我的用例:我有一個運行大量作業(測試、驗證、dep、構建、文檔...)的大型管道。 現在我添加了一個暫存環境(使用 kubernetes)並讓管道構建一個新映像並將其部署在暫存環境中。 這使我可以立即打開更改后的(網絡)應用程序並查看更改的行為和外觀,而無需在本地檢查它們。 現在構建一個映像並將其部署到登台對於每次推送來說都需要大量資源,所以我只希望部署在有人創建合並請求供我審查時進行登台。

一個非常簡單的例子:

install:
  script: ...

test:
  script: ...

build-image:
  script: ...
  only: [merge_requests]

deploy-staging:
  script: ...
  only: [merge_requests]

對於所有正常推送,應執行作業installtest

對於合並請求,應執行作業installtestbuild-imagedeploy-staging

我嘗試過的: Gitlab 具有此功能, only: [merge_requests]在作業上,這導致該作業僅在為合並請求執行管道時執行。 聽起來正是我正在尋找的東西,但有一個很大的收獲。 一旦該屬性應用於管道中的一個作業,該管道中沒有該屬性的所有其他作業將在合並請求中執行時從管道中刪除。 起初這對我來說似乎是一個錯誤,但實際上是記錄在案的行為

In the above example, the pipeline contains only a test job. Since the build and deploy jobs don’t have the only: [merge_requests] parameter, they will not run in the merge request.

為了將所有其他作業重新引入合並請求的管道,我only: [merge_requests]應用於所有其他作業。 這種方法的問題在於,現在這些常規作業不再為正常的 git-push 執行。 而且我無法將這些常規作業重新引入管道以進行正常推送,因為 Gitlab 不支持only: [always]或類似的東西。

現在我也注意到only的語法是棄用的候選者,應該更喜歡rules語法,所以我看了一下。 這種方法存在多個問題:

  • 使用rules檢測是否為合並請求執行管道的唯一方法是評估與合並請求相關的變量,例如$CI_MERGE_REQUEST_ID 不幸的是,這些變量僅在以下情況下存在only: [merge_requests]被使用,這將重新引入上述問題。
  • 規則只允許有條件地應用其他屬性,所以我仍然必須使用onlyexceptwhen屬性來實際從管道中刪除或添加作業。 不幸的是 Gitlab 不支持類似only: [never]when: never的任何東西,所以我無法實際刪除或添加作業。

我還嘗試讓作業依賴於另一個使用needdependencies屬性的屬性,這似乎對作業是否包含在管道中沒有影響。

我拼命嘗試的最后一件事是始終包括所有作業,並將它們標記為何when: manual手動通過按下按鈕手動觸發。 這有點工作,但非常乏味,因為部署到登台是一個多作業過程,每項作業都需要相當長的時間才能完成。 所以我會看到一個合並請求,按下第一個作業的按鈕,等待 5 分鍾,按下下一個按鈕,再次等待 5 分鍾,然后才能使用暫存。 對於許多小的合並請求,這會占用我很多時間並且不是一個有效的解決方案。 我也不能只將這些作業中的第一個標記為手動,因為 Gitlab 將跳過該作業並無序執行后面的作業(同樣,在處理手動觸發的作業時, needsdependencies似乎對此沒有影響)。

我有點困惑的是,在網上搜索后,我發現沒有人有同樣的問題。 要么我是唯一的 Gitlab 用戶,它只想為合並請求執行一些作業而不排除所有其他作業(這似乎極不可能),要么我錯過了一些明顯的東西(這似乎更有可能)。 我錯過了什么還是 Gitlab 真的不支持這個用例?

以前的答案

但有一個問題。 此示例在創建 MR 后為每次推送啟動兩個管道。 一個only: [branch] ,一個only: [merge_requests]

檢查上一個GitLab 13.8 (2021 年 1 月)是否有幫助:

同時使用分支和 MR 管道而不重復

以前不可能先為分支運行管道,然后在創建 MR 時切換到合並請求管道

因此,對於某些配置,如果合並請求已在分支上打開,則推送到分支可能會導致重復的管道:分支上的一個管道和合並請求的另一個管道。

現在,您可以在 CI 配置中使用新的$CI_OPEN_MERGE_REQUESTS預定義環境變量在正確的時間從分支管道切換到 MR 管道,並防止冗余管道。

https://about.gitlab.com/images/13_8/yaml_example_avoid_duplicate_pipelines.png -- 使用分支和 MR 管道而不重復

請參閱文檔問題

可以向 MR 管道添加一些作業。 我從這里得到了例子: https : //docs.gitlab.com/ee/ci/merge_request_pipelines/index.html# exclude-certain-jobs

總體思路:您only: [branch, merge_requests]定義only: [branch, merge_requests]為每個作業,並且部署作業only: [merge_requests]重寫它。

.only-default: &only-default
  only:
    - branches
    - merge_requests

build:
  stage: build
  tags:
    - build
  <<: *only-default
  script:
    - echo build

deploy mr:
  stage: deploy
  tags:
    - build
  only:
    - merge_requests
  script:
    - echo "deploy on MR"

但有一個問題。 此示例在創建 MR 后為每次推送啟動兩個管道。 一個only: [branch] ,一個only: [merge_requests] 這是only: [merge_requests]工作,它在每次 MR 更改時啟動作業。 新提交絕對是一個變化。

似乎沒有解決方案可以僅針對某些事件啟動管道 - 例如 MR 創建。

但我認為一些解決方法是可行的:

  1. 每個管道都存在部署暫存作業
  2. 作業腳本檢查是否為當前分支創建了 MR
  3. 如果創建了 MR,則為此 MR 設置腳本標簽,例如“已部署分期”
  4. 如果這個標簽已經存在,或者沒有創建MR,那就什么都不做。

GitLab API、curl 和 jq 可以幫助解決這個問題。 如果我有空閑時間,我一定會嘗試寫它:)。

我有同樣的問題。

GitLab 文檔中所述,您必須配置整個管道以在合並請求管道中運行。

這可以通過在 .gitlab-ci.yml 之上添加以下內容來實現。

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'

希望我能幫上忙!

以下對我有用。 這個想法是通過workflow關鍵字為所有 CI 作業定義一個默認值。 然后對於您只想在 MR 上運行的 CI 作業,定義一個單獨的運行(它會覆蓋該作業的workflow規則)。

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_PIPELINE_SOURCE == "push"

install:
  script: ...

test:
  script: ...

build-image:
  script: ...
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

deploy-staging:
  script: ...
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM