看到阿迪王那邊出品了一個基於Azure Devops自增版本號 鏈接 http://edi.wang/post/2019/3/1/incremental-build-number-for-net-core-via-azure-devops
恰巧我自己也有一個版本(雖然核心原理是差不多的)也分享下
(以下均基於Tfs 2018的截圖,Azure Devops Server暫時還沒發布,只能Tfs將就着了,雖然Azure Devops跟當前的Tfs 2018已經界面有"一些"改動不過流程是相通)
先說下我們的場景,我們使用Tfs來進行發布,所以我希望做到一個事情是Tfs里Release的版本號能跟我dll的版本號對應上,這樣便於版本的對應和關聯(實際上我們站點在啟動的時候還會上報版本號到exceptionless,假如有機器漏發布了我們就能知道)
看下我們的最終效果,每次Tfs發布之后,都會改變我當前項目產生的dll的版本號,並且這個版本號(4位的)的其中后2位一定跟Tfs里的生成號一樣,而Tfs的生成好的第三位是當前的月份和日期,第四位是當天build的次數
首先我能將版本號和發布或者說編譯關聯,其次我也能知道當天到底編譯了幾次
先說2個前置知識
①Azure Devops里預定義的變量 https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml
②通過Powershell如何讀取Azure Devops里CI/CD的變量呢? 直接 $Env.變量名 (注意,他預定義變量名里有時候會有英文句號. 要將其轉為下划線,如Build.BuildNumber你要讀取的時候應該是 $Env.Build_BuildNumber)
再說說.Net里的文件版本號的是怎么來的,主要有Framework和Core兩個體系,因為我們兩種項目都有(當前還是Framework是大頭)所以2個都要支持
Framework,主要是在項目的Properties文件夾里的AssemblyInfo.cs定義
Core,主要是項目里的csproj
順帶我再加上一個自己的假設,在這些配置文件夾里只有我們的版本號會是正則表達式為 .\d+.\d+.\d+.\d+(也就是x.x.x.x)的規則,我只要用正則找出他替換就行了。
等下,好像哪里不對勁。
在core的csproj里因為還管着nuget的引用,所以里面會有他引用的nuget包信息,所以此時他里面可能會有這些內容
於是在core項目里,我們是將version統一抽走到要給獨立的props文件里
搞一個props文件,類似這樣
然后在你的項目導入你的props
其實這樣子之后,比如如我截圖里的,我在里面定義了我項目使用C# 7.2,那么我所有項目都跟着是7.2,我定義了打包帶symbol就所有都帶,統一了配置,也更好一些(個人感覺)
然后就是上powershell(這段powershell並非我原創,也不記得很久前哪里找來的了,然后稍加修改后一直使用至今)
# Enable -Verbose option
[CmdletBinding()]
# Regular expression pattern to find the version in the build number
# and then apply it to the assemblies
$VersionRegex = "(?<=\d+\.\d+\.)\d+\.\d+"
# Make sure path to source code directory is available
if (-not $Env:BUILD_SOURCESDIRECTORY)
{
Write-Error ("BUILD_SOURCESDIRECTORY environment variable is missing.")
exit 1
}
elseif (-not (Test-Path $Env:BUILD_SOURCESDIRECTORY))
{
Write-Error "BUILD_SOURCESDIRECTORY does not exist: $Env:BUILD_SOURCESDIRECTORY"
exit 1
}
Write-Verbose "BUILD_SOURCESDIRECTORY: $Env:BUILD_SOURCESDIRECTORY"
# Make sure there is a build number
if (-not $Env:BUILD_BUILDNUMBER)
{
Write-Error ("BUILD_BUILDNUMBER environment variable is missing.")
exit 1
}
Write-Verbose "BUILD_BUILDNUMBER: $Env:BUILD_BUILDNUMBER"
# Get and validate the version data
$VersionData = [regex]::matches($Env:BUILD_BUILDNUMBER,$VersionRegex)
switch($VersionData.Count)
{
0
{
Write-Error "Could not find version number data in BUILD_BUILDNUMBER."
exit 1
}
1 {}
default
{
Write-Warning "Found more than instance of version data in BUILD_BUILDNUMBER."
Write-Warning "Will assume first instance is version."
}
}
$NewVersion = $VersionData[0]
Write-Verbose "Version: $NewVersion"
# Apply the version to the assembly property files
$commonPropsFiles = Get-ChildItem -include common.props,AssemblyInfo.cs -recurse
if($commonPropsFiles)
{
Write-Verbose "Will apply $NewVersion to $($commonPropsFiles.count) files."
foreach ($file in $commonPropsFiles) {
$filecontent = Get-Content($file)
attrib $file -r
Write-Host $NewVersion
$filecontent -replace $VersionRegex, $NewVersion | Out-File $file
Write-Verbose "$file.FullName - version applied"
}
}
else
{
Write-Warning "Found no commonPropsFiles."
}
這段powershell可以弄成一個.ps1文件放到Azure Devops里然后引用
如
注意使用的時候一定要在高級里配置”工作文件夾”到你項目根目錄(一般是csproj所在文件夾)
或者直接用Powershell Inline
也就是阿迪王分享的博客里的直接將powershell貼入到里面去執行的那個方法
兩者效果一樣
然后在Azure Devops里下其生成的版本號規則,即可完成匹配
然后在進行編譯的時候你就能看到你的版本號被修改拉










