CI/CD
- 持續集成CI(盡快發現錯誤、減少集成問題,避免復雜問題)
- 合並開發人員正在開發編寫的所有代碼的一種做法
- 一天內進行多次合並和提交代碼
- 從存儲庫或生產環境中進行構建和自動化測試,以確保沒有集成問題並及早發現任何問題
- 持續交付CD(每次更改都可發布,降低每次發布風險,更加頻繁交付價值,快速頻繁客戶反饋)
- 通常可以通過將更改自動推送到發布系統來隨時將軟件發布到生產環境中
- 持續部署會更進一步,並自動將更改推送到生產中
代碼版本管理 - Gitlab
- 代碼審查
- 問題跟蹤
- 動態訂閱
- 易於擴展
- 項目wiki
- 多角色項目管理
- 項目代碼在線預覽
- CI工具集成
Gitlab內置持續集成
持續集成CI
- 集成團隊中每個開發人員提交的代碼到代碼存儲庫中
- 開發人員在Merge或者Pull請求中合並拉取新代碼
- 在提交或者合並更改到代碼存儲庫之前,會觸發構建,測試和新代碼驗證的管道
- CI可在開發周期的早先發現並減少錯誤
持續交付CD
- 可通過結構化的部署管道確保將經過CI驗證的代碼交付給應用程序
- CD可將通過驗證的代碼更快的部署到應用程序
Gitlab CI/CD工作原理
- 將代碼托管到Gitlab
- 在項目根目錄創建ci文件 .gitlab-ci.yml,在文件中指定構建、測試和部署腳本
- Gitlab將檢測到它並使用名為GItLab Runner的工具運行腳本
- 腳本被分組作業,他們共同組成了一個管道
GitLab 對比Jenkins
1、分支的可配置型
- 使用GitLab CI,新創建的分支無需任何進一步配置即可立即使用CI管道中已定義作業。
- Jenkins 2 基於Gitlab的多分支流水線可以實現,相對配置來說Gitlab更加方便。
2、定時構建
- 使用Jenkins可以立即使用,可以再應執行作業或管道的那一刻已cron語法定義
- GitLab CI沒有此功能,只能通過調用WebAPI去調用cronjob觸發作業和管道
3、拉取請求支持
- Jenkins沒有與源代碼管理系統進一步集成,需要管理員自行寫代碼或者插件實現
- GitLab與其CI平台緊密集成,可以方便查看每個打開和關閉拉動請求的運行和完成管道。
4、權限管理
- 由於GitLab與GitLabCI的深度整合,權限可以統一管理
- 由於Jenkins沒有內置的存儲庫管理器,因此權限無法做合並。
5、存儲庫交互
- GitLab CI是Git存儲庫管理器GitLab的固定組件,因此在CI/CD流程和存儲庫功能之間提供了良好的交互
- Jenkins與存儲庫管理器是松散耦合的,因此在選擇版本控制系統時非常靈活。
6、插件管理
- 擴展Jenkins的本機功能是通過插件完成的,插件的維護、保護和升級成本很高。
- GitLab是開放式的,任何人都可以直接向代碼庫貢獻更改,一旦合並,它將自動測試並維護每個更改。
安裝GitLab
https://about.gitlab.com/install/#centos-8
GitLab Runner(最好與GitLab版本一直,避免版本差異化)
介紹:GitLab Runner,go語言編寫,類似Jenkins的Agent,執行CI持續集成,構建任務的腳本
特點
- 作業運行控制:同時執行多個作業
- 作業運行環境:(Docker、Shell、K8s執行器)
- 在本地、使用Docker並通過SSH執行作業
- 使用Docker容器在不同的雲和容器化管理程序上自動縮放
- 連接到遠程的SSH服務器
- 支持Bash、Windows Batch和Windows Powershell
- 允許自定義作業運行環境
- 自動重新加載配置,無需重啟
- 易於安裝、可作為Linux,MacOS和Windows的服務
GitLab Runner類型與狀態
- 類型
- shared共享類型,運行整個平台項目的作業(Gitlab)
- group項目組類型,運行特定Group下的所有項目作業(group)
- specific項目類型,運行指定的項目作業(project)
- 狀態
- locked:鎖定狀態,無法運行項目作業
- paused:暫定狀態,暫時不會接受新的作業
.gitlab-ci.yml配置文件示例
before_script:
- echo "before-script"
variables:
- DOMAIN: example.com
stages:
- build
- test
- codescan
- deploy
build:
before_script:
- echo "before-script in job"
stage: build
script:
- echo "123"
- echo "456"
- echo "$DOMAIN"
after_script:
- echo "after script in buildjob"
unittest:
stage: test
script:
- echo "run test"
deploy:
stage: deploy
script:
- echo "hello deploy"
- sleep 2;
codescan:
stage: codescan
script:
- echo "codescan"
- sleep 5;
after_script:
- echo "after-script"
before_script
before_script失敗導致整個作業失敗,其他作業將不再執行,作業失敗不會影響after_script運行。
after_script
在每個作業(包括失敗的作業)之后運行的命令
stages
用於定義作業可以使用的階段,並確實全局且順序的。
.pre&.post
.pre始終是整個管道的第一個運行階段,.post始終是整個管道的最后一個運行階段,順序無法更改,如果僅包含.pre或.post階段作業,則不會創建管道。
codescan:
stage: .pre
tags:
- build
only:
- master
script:
- echo "codescan"
stage
如果同意階段有多個任務,是並行執行的,數量可以通過修改runner配置文件中的concurrent的數量來決定。
tags
用於從允許運行該項目的所有Runner中選擇特定的Runner(對應的標簽-Tags)
allow_failure允許失敗
默認值為false,啟用后,如果作業失敗,該作業將在用戶界面中顯示橙色警告,但是pipeline不會被阻塞。
when-控制作業運行
- on_success 前面階段中的所有作業都成功時才執行作業,默認值。
- on_failure 當前面階段出現失敗時執行
- always 總是執行
- manual 手動執行作業
- delayed 延遲執行作業
when: delayed
start_in: '30'
retry - 重試
當作業失敗並配置了retry,將再次處理該作業,直到達到retry關鍵字指定的次數
# 這里when失敗的類型有很多種,具體用到可以再查。
retry:
max: 2
when:
- script_failure
timeout - 超時
作業級別的超時可以超過項目級別超時,但不能超過Runner特定的超時
timeout: 3h 30m
parallel - 並行作業
- 配置要並行運行的作業實例數,此值必須>=2並且<=50
- 將創建N個並行運行的同一作業實例,他們從job_name1/N到job_name N/N依次命名
parallel: 5
only&except(過時了。。后續都建議使用rules)
job:
only:
# 只允許已issue-開頭的分支
- /^issue-.*$/
except:
# 排除fff分支
- fff
rules - 構建規則
- rules允許按順序評估單個規則,知道匹配並為作業動態提供屬性
- rules不能與only/except組合使用
可用的規則
- if(如果條件匹配)
- changes (指定文件發生變化)
- exists (指定文件存在)
rules-if-條件匹配
- 如果DOMAIN的值匹配,則需要手動運行
- 不匹配on_success.
- 條件判斷從上到下,匹配即停止
- 多條件匹配可以使用&& ||.
variables:
DOMAIN: example.com
codescan:
stage: codescan
tags:
- build
script:
- echo "code scan"
- sleep 5;
rules:
- if: '$DOMAIN == "example.com"'
when: manual
- if: '$DOMAIN == "xxx.com"'
when: delayed
start_in: '5'
- when: on_success
changes
build:
script:
- echo "xxx"
rules:
- changes:
- Dockerfile
when: manual
- when: on_failure
exists
build:
script:
- echo "xxx"
rules:
- exists:
- Dockerfile
when: manual
- when: on_failure
allow_failure
build:
script:
- echo "xxx"
rules:
- if: '$DOMAIN == "xxx.com"'
when: manual
alow_failure: true
workflow,是否創建Pipeline
workflow:
rules:
- if: '$DOMAIN == "example.com"'
when: always
- when: never
cache - 緩存
- 存儲編譯項目所需的運行時依賴項,指定項目工作空間中需要在job之間緩存的文件或目錄
- 全局cache定義在job之外,針對所有job生效,job中cache優先於全局
- 在job build中定義緩存,將會緩存target目錄下的所有.jar文件
- 擋在全局定義了cache: paths會被job中覆蓋,一下實例將緩存target目錄。
- 由於緩存是再job之間共享的,如果不同的job使用不同的路徑就出現了緩存覆蓋的問題,通過設置不同的cache:key來解決該問題。不同的cache:key會為每個job分配一個獨立的cache
######
build:
script: test
cache:
paths:
- target/*.jar
######
cache:
paths:
- my/files
build:
script: echo "hello"
cache:
key: build
# key: ${CI_COMMIT_REF_SLUG} # 按照分支設置緩存
paths:
- target/
######