為.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的執行紀錄上查看失敗原因
補充:
- 不同環境的變數使用方式 https://docs.gitlab.com/ee/ci/variables/#syntax-of-environment-variables-in-job-scripts
- 要查看使用了什麼環境,可以在runner資料夾內的設定檔確認及修改
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