[GitLab] 為.NET Core應用加上CI/CD,並使用zip檔部署的方式上Azure

為.NET Core應用加上CI/CD,並使用zip檔部署的方式上Azure

這次要在GitLab上加入流程,在檔案簽入版控時觸發CICD,並且完成build、Test,Deploy(Azure)

記錄下這次的流程以及所有踩到的雷


已備妥的環境

1.GitLab帳號,並且已有可運行的Runner

(如何加入Runner可參考前一篇文章 https://dotblogs.com.tw/Null/2020/04/07/114228

2.Azure帳號

3.一個可運行的.NetCore應用(包含Test Project,這邊用的是xUnit)

  • 我的專案名稱是 WebApplication
  • 測試專案是 WebApplication.Tests

CI

1.按照前一篇的步驟,專案已經放上版控,並且有一個.gitlab-ci.yml設定檔

2.調整yml,先完成CI的部分,接著會說明調整的內容

variables:
  BuildPath: .\WebApplication\bin\Debug\netcoreapp3.1

stages:
  - build

before_script:
  - chcp 65001

build_job:
  stage: build
  script:
    - dotnet build -c debug
  artifacts:
    when: always
    expire_in: 1 week
    paths:
      - '%BuildPath%'

3.宣告一個變數 BuildPath,內容是專案建置後產生的目錄

4.定義有一個步驟 build

5.有時command line遇到中文會變成亂碼,每個步驟執行前,加上 chcp 65001指定用UTF-8編碼,詳細可以參考黑大的這篇文章 https://blog.darkthread.net/blog/command-prompt-codepage/

6.接著開始定義 build 這個階段要做的事情

7.在.NET Core的好處就是很多的命令都包裝進了dotnet.exe裡面,從建置、發佈、測試以及打包package都可以用他來處理

8.這個步驟做的是指定用組態debug建置專案,dotnet build -c debug

9.artifacts,在建置完成後

  • 不論成功失敗(when: always)都把結果上傳回GitLab
  • 並且設定保存期限1週(expire_in)
  • 上傳的內容則是從 paths 指定路徑(這邊有用到變數,使用變數的方式會依照runner執行的模式不同而已,這邊使用的是windows batch的方式,相關補充在後面)
  • 針對artifacts的相關內容可參考 https://docs.gitlab.com/ee/ci/yaml/#artifacts

10.儲存並確認執行結果,右邊會有一個icon,可以下載CI上傳的結果

  • 若路徑指定錯誤沒找到檔案,就不會顯示icon,可以從jobs的執行紀錄上查看失敗原因

補充:


Test

1.在yml加上test的步驟

  • 變數,指定測試專案的路徑
  • TestFolderPath: .\WebApplication.Tests
  • 在stages加上一個步驟
  • stages:
      - build
      - test
  • 加上這個階段要做的事
  • test_job:
      stage: test
      script:
        - dotnet test -v m --logger "trx;LogFileName=TestResults.trx"
      artifacts:
        when: always
        expire_in: 1 week
        paths:
          - '%TestFolderPath%\TestResults\TestResults.trx'
      dependencies:
        - build_job

2.在script內,呼叫 dotnet test執行測試

  • -v m 設定內容的詳細等級,有下面幾種可以使用,q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]
  • --logger ...,產生測試結果的檔案,內容是xml

3.同樣的上傳執行結果,保存一週

4.dependencies,相依於步驟build_job,如果建置沒成功就不會執行測試

5.儲存並執行,CI/CD變成兩個步驟,右邊的icon同樣會多一個測試的結果可以下載

  • GitLab似乎還不支援xUnit的測試結果清單,目前只能從job的執行內容裡面查看,如果有人知道如何添加,再麻煩告知,感謝

2020/4/15 補充

針對最後的測試結果清單,後來發現Gitlab官網有相關的說明,不過礙於沒權限尚未嘗試,有興趣的朋友可以試試看

https://docs.gitlab.com/ee/ci/junit_test_reports.html#viewing-junit-test-reports-on-gitlab


CD

1.Azure基本上有提供兩幾種部署的方式

2.第一種是前篇提到的git簽入,透過azure部署

3.第二種是透過FTP直接覆蓋檔案

  • FTP資訊可以在Azure應用程式上看到,或是從部署中心選擇FTP查看以及設定帳密
  • 原本想用這個方式部署,結果部署過程中遇到"檔案使用中,無法操作"之類的錯誤,導致部署失敗,必須停止應用部署才能正常...太麻煩了,馬上拋棄這個選項

4.第三種使用zip或war檔部署至azure,而且可以使用Rest API https://docs.microsoft.com/zh-tw/azure/app-service/deploy-zip#deploy-zip-file-with-rest-apis

  • 最後採用的是這個方式,後續會針對他做說明

5.先調整一下yml,加上部署的步驟

  • 變數,加上API的Url,中間的<AppName>要替換,以及publish的路徑
  • ​PostUrl: https://<AppName>.scm.azurewebsites.net/api/zipdeploy
    PublishPath: .\WebApplication\bin\Debug\netcoreapp3.1\publish\
  • 加入deploy的步驟
  • stages:
      - build
      - test
      - deploy
  • 接著是deploy要做的事情
  • deploy_job:
        stage: deploy
        script:
            - dotnet publish
            - powershell Compress-7Zip -Path %PublishPath% -ArchiveFileName Publish.zip
            - curl -X POST -u %AzureAccount%:%AzurePassword% --data-binary @"Publish.zip" %PostUrl%
        when: manual
        dependencies:
            - build_job

6.接著說明Script的內容

  • 先呼叫dotnet publish發佈,也可以加上參數 -c 指定組態
  • 呼叫powershell把publish產生的內容壓縮成.zip(後面會說明為什麼不使用Compress-Archive壓縮)
  • 接著用cUrl Post API並且把檔案丟上去 https://docs.microsoft.com/zh-tw/azure/app-service/deploy-zip#deploy-zip-file-with-rest-apis
    • 這邊用到的帳密是設定在全域變數,可以在這邊做設定
  • when: manual,指定這個步驟需要人工批准才會執行
  • 相依於步驟 build_job

7.接著儲存並執行,可以看到,當build跟test跑完後,第三個步驟需要人工點擊才會執行

8.執行完成後,可以回到azure的部署中心確認,應該會增加一條部署成功的紀錄

  • 若遇到cUrl執行的問題,請直接往最下面看

9.到這邊CI/CD的基本流程就有了,開心end

 

補充:

1.指令Compress-7Zip是powershell的額外套件 https://www.powershellgallery.com/packages/7Zip4Powershell/1.9.0

  • 若用powershell做壓縮,部署上azure後會部署失敗,大略google一下後,可能是powershell對zip編碼上的問題,改用7-zip就沒這問題
  • 我在azure是開linux的環境,在windows也有可能用powershell壓縮是正常的

2.runner註冊時若選擇shell,預設是跑powershell,在執行cUrl的時候會出現些問題,我懶,所以直接調整runner的設定檔,把shell更改為cmd


透過zip部署 https://docs.microsoft.com/zh-tw/azure/app-service/deploy-zip#deploy-zip-file-with-rest-apis

Linux部署可能的問題 https://docs.microsoft.com/zh-tw/azure/app-service/containers/app-service-linux-faq#continuous-integration-and-deployment