GitLab CI/CD建置,自動化並減少人為失誤
一個良好的系統開發,勢必會有持續性的整合與部屬(CI/CD),如果可以達到自動化,並且少失誤問題,所帶來的效果是非常大的
因此需要學習如何操作並建置CI/CD
環境
- GitLab
- GitLab Runner
- Runner 環境底下Nuget、.Net Sdk、Build Tool for Visual Studio
- Windows Server
- IIS
- PowerShell
步驟
- 註冊Runner
- 啟用PowerShell Remote
- 編寫指令檔.yml
編寫指令檔yml
# 全域變數概念
variables:
PublishPath: TestCICD_publish\
WebSiteName: TestCICD
WebSitePath: D:\TestCICD
BackUpPath: D:\BackUp
StageIP: 192.168.23.107
ProdIP: 192.168.123.107
# StageAccount: GitLab 專案上的CI/CD 變數設定
# StagePassword:
# ProdAccount:
# ProdPassword:
# GitLab CI/CD 上需要出現的步驟
stages:
# 建置
- Build
# 測試
- Test
# 測試區發布
- StageDeploy
# 正式區發布
- ProdDeploy
# 執行步驟前的Script
before_script:
#encoding 參數之 Cmdlet 的預設編碼方式
- $PSDefaultParameterValues['*:Encoding'] = 'utf8'
# GitLab上的任務顯示才會出現中文,勿直接使用chcp 65001
- "[System.Console]::OutputEncoding = [System.Text.UTF8Encoding]::UTF8"
# 將路徑改到src 個人習慣
- cd src
# 採用net core dotnet restore
- dotnet restore
# 開發建置
Dev-Build:
# 使用建置步驟
stage: Build
# 使用Script
script:
# 採用net core dotnet build,指定專案TestCICD建置Release版
- dotnet build TestCICD -c Release
#允許觸發的分支
only:
- master
- stage
# 開發測試
Dev-Test:
# 使用測試步驟
stage: Test
# 使用Script
script:
# 採用net core dotnet test,指定專案UnitTest
- dotnet test UnitTest
dependencies:
- Dev-Build
#允許觸發的分支
only:
- master
- stage
Dev-Stage-Deploy:
# 使用部署步驟
stage: StageDeploy
# 使用Script
script:
# 採用net core dotnet publish,指定專案TestCICD Release版 FolderProfile發行檔 並指定輸出路徑
- dotnet publish TestCICD -c Release -p:PublishProfile=FolderProfile -o $env:PublishPath
# 建立連線Session
- $pw = convertto-securestring -AsPlainText -Force -String $env:StagePassword
- $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $env:StageAccount, $pw
- $session = New-PSSession -Credential $cred -ComputerName $env:StageIP1
# 遠端控制 IIS 站點停止
- Invoke-Command -Session $session -ScriptBlock { C:\Windows\System32\inetsrv\appcmd.exe stop site $args[0] } -Args $env:WebSiteName
# 遠端控制 IIS AppPoll停止
- Invoke-Command -Session $session -ScriptBlock { C:\Windows\System32\inetsrv\appcmd.exe stop apppool $args[0] } -Args $env:WebSiteName
# 宣告一個變數儲存當前時間,用作備份資料資料夾名稱
- $datetime = Get-Date -Format 'yyyy-MM-dd_HH-mm'
# 遠端控制 備份原有專案檔案
- Invoke-Command -Session $session -ScriptBlock { Copy-Item -Path $args[0] -Destination $args[1] -Recurse } -Args $env:WebSitePath, $env:BackUpPath\$datetime
# Git Runner端複製檔案到遠端部署位置 $env:PublishPath 加*代表資料夾內的所有檔案
- Copy-Item -Path $env:PublishPath* -Destination $env:WebSitePath -Recurse -force -ToSession $session
# 遠端控制 IIS AppPool啟動
- Invoke-Command -Session $session -ScriptBlock { C:\Windows\System32\inetsrv\appcmd.exe start apppool $args[0] } -Args $env:WebSiteName
# 遠端控制 IIS 站點啟動
- Invoke-Command -Session $session -ScriptBlock { C:\Windows\System32\inetsrv\appcmd.exe start site $args[0] } -Args $env:WebSiteName
#依賴某個步驟
dependencies:
- Dev-Test
#允許觸發的分支
only:
- stage
# 使用manual 才可在GitLab CI/CD上控制是否佈版
when: manual
Dev-Prod-Deploy:
# 使用部署步驟
stage: ProdDeploy
# 使用Script
script:
# 採用net core dotnet publish,指定專案TestCICD Release版 FolderProfile發行檔 並指定輸出路徑
- dotnet publish TestCICD -c Release -p:PublishProfile=FolderProfile -o $env:PublishPath
# 建立連線Session
- $pw = convertto-securestring -AsPlainText -Force -String $env:ProdPassword
- $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $env:ProdAccount, $pw
- $session = New-PSSession -Credential $cred -ComputerName $env:ProdIP1
# 遠端控制 IIS 站點停止
- Invoke-Command -Session $session -ScriptBlock { C:\Windows\System32\inetsrv\appcmd.exe stop site $args[0] } -Args $env:WebSiteName
# 遠端控制 IIS AppPoll停止
- Invoke-Command -Session $session -ScriptBlock { C:\Windows\System32\inetsrv\appcmd.exe stop apppool $args[0] } -Args $env:WebSiteName
# 宣告一個變數儲存當前時間,用作備份資料資料夾名稱
- $datetime = Get-Date -Format 'yyyy-MM-dd_HH-mm'
# 遠端控制 備份原有專案檔案
- Invoke-Command -Session $session -ScriptBlock { Copy-Item -Path $args[0] -Destination $args[1] -Recurse } -Args $env:WebSitePath, $env:BackUpPath\$datetime
# Git Runner端複製檔案到遠端部署位置 $env:PublishPath 加*代表資料夾內的所有檔案
- Copy-Item -Path $env:PublishPath* -Destination $env:WebSitePath -Recurse -force -ToSession $session
# 遠端控制 IIS AppPool啟動
- Invoke-Command -Session $session -ScriptBlock { C:\Windows\System32\inetsrv\appcmd.exe start apppool $args[0] } -Args $env:WebSiteName
# 遠端控制 IIS 站點啟動
- Invoke-Command -Session $session -ScriptBlock { C:\Windows\System32\inetsrv\appcmd.exe start site $args[0] } -Args $env:WebSiteName
#依賴某個步驟
dependencies:
- Dev-Test
#允許觸發的分支
only:
- master
# 使用manual 才可在GitLab CI/CD上控制是否佈版
when: manual
yml檔上的變數設定,在GitLab上先行設定,才會讀取到,帳密部分請避免直接寫在yml
建置成功畫面
單元測試成功畫面
發布成功畫面,注意!這裡有亂碼問題,主因: Runner上的編碼問題
即便在yml上編寫輸出為UTF8還是有不小機率出現亂碼
如此一來就可以完成CI/CD行為,減少日後部署上的失誤
提醒
NetCore在IIS上的部署建議單獨使用一個AppPool,以避免關閉時,連同其他系統也關閉
主因: NetCore無法釋放正在執行的dll,故需要先關閉AppPool後再關閉Site
資料參考來源