GitLab CI/CD建置

GitLab CI/CD建置,自動化並減少人為失誤

一個良好的系統開發,勢必會有持續性的整合與部屬(CI/CD),如果可以達到自動化,並且少失誤問題,所帶來的效果是非常大的

因此需要學習如何操作並建置CI/CD

環境

  1. GitLab
  2. GitLab Runner
  3. Runner 環境底下Nuget、.Net Sdk、Build Tool for Visual Studio
  4. Windows Server
  5. IIS
  6. PowerShell

步驟

  1. 註冊Runner
  2. 啟用PowerShell Remote
  3. 編寫指令檔.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

資料參考來源

  1. yy-programer
  2. 維基百科
  3. 使用 Gitlab CI/CD 實現自動化釋出站點到 IIS