點選上方藍字關註“汪宇傑部落格”
熟悉.NET Framework的人知道,我們可以透過指定AssemblyVersion為10.0.*來讓編譯器自增版本號。但是.NET Core和.NET Standard不行。即使有MSBump這樣的開源專案,也有一定的缺陷。一般這樣的需求會出現在CI/CD伺服器上。我們來看看如何用Azure DevOps輕鬆搞定。
關於.NET Core應用版本號
我曾經諧過一篇詳細的.NET Core應用版本號的文章:https://edi.wang/post/2018/9/27/get-app-version-net-core有興趣的可以先閱讀一下,因為本文的內容會基於文中的知識。(域名可能被HX,微信使用者可以複製到瀏覽器開啟)我們這次要控制的,是Version欄位。
就是它
使用.NET Core CLI的build命令直接編譯出來的DLL會顯示這個版本。
但其實,build命令是可以加引數的,想要在不更改csproj檔案的情況下build一個自定義版本可以加個/p引數,指定Version,這樣搞:
dotnet build /p:Version=10.0.8888.1234
基於這個原理,我們就能控制.NET Core應用程式在編譯環境的版本號。
為毛不用 MSBump
可能有朋友知道這麼一個專案:MSBump,也能用來在編譯時改變版本號。但是,它在編譯時候會去改csproj檔案,對於程式碼來說是一次更改。而傳統.NET Fx的編譯系統不會改程式碼。這對於我來說是無法接受的,因為引入了不可控的因素。在多人團隊本地build完竟然還要簽入僅僅是更改了版本號的csproj檔案,不是一種好方法。並且它的預設規則,不是根據時間戳來增加版本號的,而是根據本機當前工程檔案的版本。所以在多人協作的程式碼庫裡對導致版本混亂。因此我決定放棄MSBump,儘量用微軟自家技術,解決自家問題。
自動生成版本號
在全自動的CI環境,我們不可能每次手工幹預指定版本號。我需要一種規則和方法去生成每次都不一樣,並且一眼就能判斷新舊的版本號。
我個人使用的規則是:主.次.距2000年1月1日的天數.幸運數字
其中要計算的是距2000年1月1日的天數。可以用Windows計算器按出來,也可以寫程式算。但在自己動手造輪子之前,一個好習慣是看看微軟是否已經有現成的工具可以完成。當然,微軟一定是有的:PowerShell
PowerShell計算兩個日期之間相差的天數,非常簡單:
$baseDate = [datetime]”01/01/2000″
$currentDate = $(Get-Date)
$interval = NEW-TIMESPAN –Start $baseDate –End $currentDate
$days = $interval.Days
配置 Azure DevOps
有了以上的知識。我們要做的,就是讓Azure DevOps在編譯時,自動計算出版本號,然後給build命令加上/p:Version引數。怎麼做呢?很簡單!
環境變數
首先,我們需要一個變數,比如叫做 buildNumber
在編譯定義的variables裡可以新增。隨便指定一個版本號就行。
PowerShell 任務
我們要使用PowerShell計算版本號,並給剛才那個 buildNumber 變數賦值。所以,新增一個PowerShell任務,放在最前面。
給Azure DevOps編譯管線裡的變數賦值,有個神奇的技巧,就是用Write-Host就可以了:
##vso[task.setvariable variable=變數名稱]變數值
所以最終我們的指令碼是
Write-Host “Generating Build Number”
$baseDate = [datetime]”01/01/2000″
$currentDate = $(Get-Date)
$interval = NEW-TIMESPAN –Start $baseDate –End $currentDate
$days = $interval.Days
Write-Host “##vso[task.setvariable variable=buildNumber]10.0.$days.1024”
在任務屬性裡選擇inline,複製貼上了這段程式碼。 //能跑就行,實在不行,刪庫跑路,也挺省心。
更改.NET Core任務引數
在Build及Publish任務的Arguments後面都加上:
/p:Version=$(buildNumber)
註意/p的前面有個空格
重跑編譯,大功告成
觸發一個CI/CD管線,可以看到日誌中已經輸出了正確的版本和引數。
並且部署完後,也能得到正確的版本了: