diff --git a/Directory.Build.props b/Directory.Build.props index 0844eb19..85eaef50 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,9 +1,9 @@ - - - 5.0.5 - + + 5.0.5 + beta + Jonathan Horvath Z-bit Systems LLC Copyright © $(Company) $([System.DateTime]::Now.Year) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 37507164..033eabe6 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -21,27 +21,16 @@ jobs: vmImage: 'windows-latest' steps: - checkout: self - fetchDepth: 0 - template: ci/build.yml - - task: PowerShell@2 - displayName: 'Set GitVersion variables for package job' - inputs: - targetType: 'inline' - script: | - Write-Host "##vso[task.setvariable variable=GitVersion.SemVer;isOutput=true]$(GITVERSION_SEMVER)" - Write-Host "##vso[task.setvariable variable=GitVersion.MajorMinorPatch;isOutput=true]$(GITVERSION_MAJORMINORPATCH)" - name: GitVersionOutput - + - job: package condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master')) pool: vmImage: 'windows-latest' dependsOn: build - variables: - GitVersionSemVer: $[ dependencies.build.outputs['GitVersionOutput.GitVersion.SemVer'] ] - GitVersionAssembly: $[ dependencies.build.outputs['GitVersionOutput.GitVersion.MajorMinorPatch'] ] steps: - checkout: self - fetchDepth: 0 + persistCredentials: true + clean: true - template: ci/package.yml diff --git a/ci/GitVersion.yml b/ci/GitVersion.yml deleted file mode 100644 index 402accb5..00000000 --- a/ci/GitVersion.yml +++ /dev/null @@ -1,22 +0,0 @@ -workflow: 'GitHubFlow/v1' -next-version: '5.0.6' -branches: - main: - mode: ContinuousDelivery - label: 'beta' - increment: Patch - track-merge-target: false - tracks-release-branches: false - regex: ^master$|^main$ - is-release-branch: true - is-main-branch: true - prevent-increment: - of-merged-branch: true - develop: - label: 'beta' - increment: None - regex: ^dev(elop)?(ment)?$ - source-branches: - - main -ignore: - sha: [] diff --git a/ci/Update-Version.ps1 b/ci/Update-Version.ps1 new file mode 100644 index 00000000..cb3d0126 --- /dev/null +++ b/ci/Update-Version.ps1 @@ -0,0 +1,149 @@ +param( + [Parameter(Mandatory = $false)] + [string]$BuildSourceBranch, + + [Parameter(Mandatory = $false)] + [string]$BuildReason +) + +# Function to parse version from Directory.Build.props +function Get-CurrentVersion { + $propsFile = "Directory.Build.props" + if (-not (Test-Path $propsFile)) { + throw "Directory.Build.props not found" + } + + [xml]$xml = Get-Content $propsFile + $versionPrefix = $xml.Project.PropertyGroup.VersionPrefix + + if (-not $versionPrefix) { + throw "VersionPrefix not found in Directory.Build.props" + } + + return $versionPrefix +} + +# Function to update version in Directory.Build.props +function Update-VersionInProps { + param([string]$NewVersion) + + $propsFile = "Directory.Build.props" + [xml]$xml = Get-Content $propsFile + + $xml.Project.PropertyGroup.VersionPrefix = $NewVersion + $xml.Save((Resolve-Path $propsFile)) + + Write-Host "Updated version to $NewVersion in Directory.Build.props" +} + +# Function to increment patch version +function Get-IncrementedVersion { + param([string]$CurrentVersion) + + if ($CurrentVersion -match '^(\d+)\.(\d+)\.(\d+)$') { + $major = [int]$matches[1] + $minor = [int]$matches[2] + $patch = [int]$matches[3] + 1 + + return "$major.$minor.$patch" + } + else { + throw "Invalid version format: $CurrentVersion" + } +} + + +# Main execution +try { + Write-Host "Starting version management script..." + Write-Host "Build Source Branch: $BuildSourceBranch" + Write-Host "Build Reason: $BuildReason" + + # Get current version + $currentVersion = Get-CurrentVersion + Write-Host "Current version: $currentVersion" + + # Check if this should trigger a version increment + # In Azure DevOps, we want to increment when: + # 1. We're building the master branch + # 2. The source branch was develop (indicating a merge from develop to master) + $shouldIncrement = $false + + if ($BuildSourceBranch -eq "refs/heads/master" -or $BuildSourceBranch -eq "refs/heads/main") { + # Check if this is a merge from develop by looking at the commit message + $lastCommitMessage = git log -1 --pretty=format:"%s" + Write-Host "Checking commit message: $lastCommitMessage" + + if ($lastCommitMessage -match "Merge.*develop.*master|Merge.*develop.*main|Merge pull request.*develop") { + Write-Host "Detected develop to master merge from commit message" + $shouldIncrement = $true + } + else { + # Alternative check using git merge-base to see if develop was recently merged + $developCommit = git rev-parse origin/develop 2>$null + $masterCommit = git rev-parse HEAD + + if ($developCommit) { + $mergeBase = git merge-base $developCommit $masterCommit 2>$null + if ($mergeBase -eq $developCommit) { + Write-Host "Detected that develop branch was merged (develop is ancestor of current commit)" + $shouldIncrement = $true + } + } + } + } + + if ($shouldIncrement) { + Write-Host "Detected develop to master merge - incrementing version" + + # Increment version + $newVersion = Get-IncrementedVersion -CurrentVersion $currentVersion + Write-Host "New version: $newVersion" + + # Update Directory.Build.props + Update-VersionInProps -NewVersion $newVersion + + # Create git tag + $tagName = "v$newVersion" + Write-Host "Creating tag: $tagName" + + git config user.email "build@z-bit.com" + git config user.name "Azure DevOps Build" + + git add Directory.Build.props + git commit -m "Bump version to $newVersion" + git tag -a $tagName -m "Release version $newVersion" + + # Push tag to origin + git push origin $tagName + Write-Host "Pushed tag $tagName to origin" + + # Switch to develop and merge the version update + Write-Host "Switching to develop branch to merge version update" + git checkout develop + git merge master --no-ff -m "Merge version update from master" + git push origin develop + Write-Host "Merged version update to develop branch" + + # Switch back to master + git checkout master + + # Set output variables for Azure DevOps + Write-Host "##vso[task.setvariable variable=NewVersion;isOutput=true]$newVersion" + Write-Host "##vso[task.setvariable variable=VersionIncremented;isOutput=true]true" + } + else { + Write-Host "No version increment needed" + Write-Host "##vso[task.setvariable variable=NewVersion;isOutput=true]$currentVersion" + Write-Host "##vso[task.setvariable variable=VersionIncremented;isOutput=true]false" + } + + # Always output current version for build purposes + Write-Host "##vso[task.setvariable variable=BuildVersion;isOutput=true]$currentVersion" + + Write-Host "Version management script completed successfully" +} +catch { + Write-Error "Error in version management script: $_" + exit 1 +} \ No newline at end of file diff --git a/ci/build.yml b/ci/build.yml index 8693125e..7522a2eb 100644 --- a/ci/build.yml +++ b/ci/build.yml @@ -4,17 +4,6 @@ steps: inputs: packageType: 'sdk' version: '8.x' - - - task: gitversion-setup@4.1.0 - displayName: 'Install GitVersion' - inputs: - versionSpec: '6.3.x' - - - task: gitversion-execute@4.1.0 - displayName: 'Execute GitVersion' - inputs: - useConfigFile: true - configFilePath: 'ci/GitVersion.yml' - task: DotNetCoreCLI@2 displayName: 'dotnet build' @@ -22,8 +11,6 @@ steps: command: 'build' projects: '**/*.csproj' arguments: '--configuration $(buildConfiguration)' - versioningScheme: 'byEnvVar' - versionEnvVar: 'GitVersion.MajorMinorPatch' - task: DotNetCoreCLI@2 displayName: 'dotnet test' diff --git a/ci/package.yml b/ci/package.yml index 0c419f72..5c8a55d6 100644 --- a/ci/package.yml +++ b/ci/package.yml @@ -3,13 +3,13 @@ steps: displayName: 'Install .NET 8 SDK' inputs: packageType: 'sdk' - version: '8.x' + version: '8.x' - task: DotNetCoreCLI@2 displayName: 'dotnet pack' inputs: command: 'pack' - arguments: '--configuration $(buildConfiguration) /p:PackageVersion=$(GitVersionNuGet)' + arguments: '--configuration $(buildConfiguration)' packagesToPack: 'src/OSDP.Net/OSDP.Net.csproj' - task: DotNetCoreCLI@2 @@ -18,7 +18,7 @@ steps: command: 'publish' publishWebProjects: false projects: 'src/ACUConsole/ACUConsole.csproj' - arguments: '-r osx-arm64 --configuration $(BuildConfiguration) /p:PublishSingleFile=true /p:IncludeAllContentForSelfExtract=true --self-contained true --output $(Build.ArtifactStagingDirectory)/TestConsole/osx-arm64 /p:Version=$(GitVersionAssembly)' + arguments: '-r osx-arm64 --configuration $(BuildConfiguration) /p:PublishSingleFile=true /p:IncludeAllContentForSelfExtract=true --self-contained true --output $(Build.ArtifactStagingDirectory)/TestConsole/osx-arm64' zipAfterPublish: false modifyOutputPath: false @@ -30,7 +30,7 @@ steps: zipAfterPublish: false modifyOutputPath: false projects: 'src/ACUConsole/ACUConsole.csproj' - arguments: '-r win-x64 --configuration $(BuildConfiguration) /p:PublishSingleFile=true /p:IncludeAllContentForSelfExtract=true --self-contained true --output $(Build.ArtifactStagingDirectory)/TestConsole/win-x64 /p:Version=$(GitVersionAssembly)' + arguments: '-r win-x64 --configuration $(BuildConfiguration) /p:PublishSingleFile=true /p:IncludeAllContentForSelfExtract=true --self-contained true --output $(Build.ArtifactStagingDirectory)/TestConsole/win-x64' - task: DotNetCoreCLI@2 displayName: 'dotnet publish for linux-x64' @@ -40,7 +40,7 @@ steps: zipAfterPublish: false modifyOutputPath: false projects: 'src/ACUConsole/ACUConsole.csproj' - arguments: '-r linux-x64 --configuration $(BuildConfiguration) /p:PublishSingleFile=true /p:IncludeAllContentForSelfExtract=true --self-contained true --output $(Build.ArtifactStagingDirectory)/TestConsole/linux-x64 /p:Version=$(GitVersionAssembly)' + arguments: '-r linux-x64 --configuration $(BuildConfiguration) /p:PublishSingleFile=true /p:IncludeAllContentForSelfExtract=true --self-contained true --output $(Build.ArtifactStagingDirectory)/TestConsole/linux-x64' - task: DotNetCoreCLI@2 displayName: 'dotnet publish for linux-arm64' @@ -50,7 +50,7 @@ steps: zipAfterPublish: false modifyOutputPath: false projects: 'src/ACUConsole/ACUConsole.csproj' - arguments: '-r linux-arm64 --configuration $(BuildConfiguration) --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:IncludeAllContentForSelfExtract=true --output $(Build.ArtifactStagingDirectory)/TestConsole/linux-arm64 /p:Version=$(GitVersionAssembly)' + arguments: '-r linux-arm64 --configuration $(BuildConfiguration) --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:IncludeAllContentForSelfExtract=true --output $(Build.ArtifactStagingDirectory)/TestConsole/linux-arm64' - task: ArchiveFiles@2 inputs: @@ -63,3 +63,67 @@ steps: - task: PublishPipelineArtifact@1 inputs: targetPath: '$(Build.ArtifactStagingDirectory)' + + - task: PowerShell@2 + displayName: 'Increment patch version after successful packaging' + inputs: + targetType: 'inline' + script: | + # Configure git for the build agent + git config --global user.email "qubit@z-bitco.com" + git config --global user.name "Azure DevOps Build Agent" + + # Get current version for display + $currentVersion = & "$(Build.SourcesDirectory)/scripts/Get-Version.ps1" -Format Simple + Write-Host "Packaging completed successfully. Current version: $currentVersion" + + # Increment patch version + & "$(Build.SourcesDirectory)/scripts/Increment-Version.ps1" -IncrementType Patch + + # Get new version + $newVersion = & "$(Build.SourcesDirectory)/scripts/Get-Version.ps1" -Format Simple + Write-Host "New version: $newVersion" + + # Set pipeline variable for later use + Write-Host "##vso[task.setvariable variable=NewVersion]$newVersion" + + - task: PowerShell@2 + displayName: 'Commit version update and create tag' + inputs: + targetType: 'inline' + script: | + $newVersion = "$(NewVersion)" + + # Stage the Directory.Build.props file + git add Directory.Build.props + + # Commit the version update + git commit -m "Bump version to $newVersion [skip ci]" + + # Create a tag for the release + git tag -a "v$newVersion" -m "Release version $newVersion" + + # Push the commit and tag to master + git push origin HEAD:master + git push origin "v$newVersion" + + Write-Host "Version $newVersion committed and tagged successfully" + + - task: PowerShell@2 + displayName: 'Merge version update back to develop' + inputs: + targetType: 'inline' + script: | + $newVersion = "$(NewVersion)" + + # Checkout develop branch + git fetch origin develop + git checkout develop + + # Merge the version update from master + git merge origin/master --no-ff -m "Merge version bump $newVersion from master [skip ci]" + + # Push the merge back to develop + git push origin develop + + Write-Host "Version update $newVersion merged back to develop successfully" diff --git a/scripts/Get-Version.ps1 b/scripts/Get-Version.ps1 new file mode 100644 index 00000000..ab2abcfb --- /dev/null +++ b/scripts/Get-Version.ps1 @@ -0,0 +1,57 @@ +#!/usr/bin/env pwsh + +<# +.SYNOPSIS + Gets the current version from Directory.Build.props +.DESCRIPTION + This script reads and displays the current version from Directory.Build.props. +.PARAMETER BuildPropsPath + Path to Directory.Build.props file (default: Directory.Build.props in repository root) +.PARAMETER Format + Output format: Simple (version only) or Detailed (with labels) +.EXAMPLE + ./Get-Version.ps1 +.EXAMPLE + ./Get-Version.ps1 -Format Simple +#> + +param( + [Parameter(Mandatory = $false)] + [string]$BuildPropsPath = (Join-Path $PSScriptRoot ".." "Directory.Build.props"), + + [Parameter(Mandatory = $false)] + [ValidateSet("Simple", "Detailed")] + [string]$Format = "Detailed" +) + +function Get-Version { + param([string]$FilePath) + + if (-not (Test-Path $FilePath)) { + throw "Directory.Build.props not found at: $FilePath" + } + + $content = Get-Content $FilePath -Raw + $versionMatch = [regex]::Match($content, '([^<]+)') + + if (-not $versionMatch.Success) { + throw "Could not find VersionPrefix in Directory.Build.props" + } + + return $versionMatch.Groups[1].Value +} + +try { + $version = Get-Version -FilePath $BuildPropsPath + + if ($Format -eq "Simple") { + Write-Output $version + } else { + Write-Host "Current version: " -NoNewline -ForegroundColor Yellow + Write-Host $version -ForegroundColor Green + } +} +catch { + Write-Error "Error reading version: $($_.Exception.Message)" + exit 1 +} \ No newline at end of file diff --git a/scripts/Increment-Version.ps1 b/scripts/Increment-Version.ps1 new file mode 100644 index 00000000..d65ebcf9 --- /dev/null +++ b/scripts/Increment-Version.ps1 @@ -0,0 +1,104 @@ +#!/usr/bin/env pwsh + +<# +.SYNOPSIS + Increments the version in Directory.Build.props +.DESCRIPTION + This script increments the version number in Directory.Build.props based on the specified increment type. +.PARAMETER IncrementType + The type of version increment: Major, Minor, or Patch (default) +.PARAMETER BuildPropsPath + Path to Directory.Build.props file (default: Directory.Build.props in repository root) +.EXAMPLE + ./Increment-Version.ps1 -IncrementType Patch +.EXAMPLE + ./Increment-Version.ps1 -IncrementType Minor +.EXAMPLE + ./Increment-Version.ps1 -IncrementType Major +#> + +param( + [Parameter(Mandatory = $false)] + [ValidateSet("Major", "Minor", "Patch")] + [string]$IncrementType = "Patch", + + [Parameter(Mandatory = $false)] + [string]$BuildPropsPath = (Join-Path $PSScriptRoot ".." "Directory.Build.props") +) + +function Get-CurrentVersion { + param([string]$FilePath) + + if (-not (Test-Path $FilePath)) { + throw "Directory.Build.props not found at: $FilePath" + } + + $content = Get-Content $FilePath -Raw + $versionMatch = [regex]::Match($content, '(\d+)\.(\d+)\.(\d+)') + + if (-not $versionMatch.Success) { + throw "Could not find VersionPrefix in Directory.Build.props" + } + + return @{ + Major = [int]$versionMatch.Groups[1].Value + Minor = [int]$versionMatch.Groups[2].Value + Patch = [int]$versionMatch.Groups[3].Value + FullMatch = $versionMatch.Groups[0].Value + } +} + +function Set-NewVersion { + param( + [string]$FilePath, + [hashtable]$CurrentVersion, + [string]$IncrementType + ) + + $newMajor = $CurrentVersion.Major + $newMinor = $CurrentVersion.Minor + $newPatch = $CurrentVersion.Patch + + switch ($IncrementType) { + "Major" { + $newMajor++ + $newMinor = 0 + $newPatch = 0 + } + "Minor" { + $newMinor++ + $newPatch = 0 + } + "Patch" { + $newPatch++ + } + } + + $newVersionString = "$newMajor.$newMinor.$newPatch" + $newVersionElement = "$newVersionString" + + $content = Get-Content $FilePath -Raw + $newContent = $content -replace [regex]::Escape($CurrentVersion.FullMatch), $newVersionElement + + Set-Content $FilePath -Value $newContent -NoNewline + + return $newVersionString +} + +try { + Write-Host "Incrementing version ($IncrementType)..." -ForegroundColor Green + + $currentVersion = Get-CurrentVersion -FilePath $BuildPropsPath + $currentVersionString = "$($currentVersion.Major).$($currentVersion.Minor).$($currentVersion.Patch)" + + Write-Host "Current version: $currentVersionString" -ForegroundColor Yellow + + $newVersionString = Set-NewVersion -FilePath $BuildPropsPath -CurrentVersion $currentVersion -IncrementType $IncrementType + + Write-Host "New version: $newVersionString" -ForegroundColor Green + Write-Host "Version updated successfully!" -ForegroundColor Green +} +catch { + Write-Error "Error updating version: $($_.Exception.Message)" + exit 1 +} \ No newline at end of file diff --git a/scripts/Set-Version.ps1 b/scripts/Set-Version.ps1 new file mode 100644 index 00000000..c6334b98 --- /dev/null +++ b/scripts/Set-Version.ps1 @@ -0,0 +1,92 @@ +#!/usr/bin/env pwsh + +<# +.SYNOPSIS + Sets a specific version in Directory.Build.props +.DESCRIPTION + This script sets the version number in Directory.Build.props to a specific value. +.PARAMETER Version + The version to set (e.g., "5.1.0") +.PARAMETER BuildPropsPath + Path to Directory.Build.props file (default: Directory.Build.props in repository root) +.EXAMPLE + ./Set-Version.ps1 -Version "5.1.0" +.EXAMPLE + ./Set-Version.ps1 -Version "6.0.0-beta" +#> + +param( + [Parameter(Mandatory = $true)] + [string]$Version, + + [Parameter(Mandatory = $false)] + [string]$BuildPropsPath = (Join-Path $PSScriptRoot ".." "Directory.Build.props") +) + +function Validate-Version { + param([string]$Version) + + # Allow semantic version format (Major.Minor.Patch with optional pre-release) + $versionPattern = '^(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9\-\.]+))?$' + + if (-not ($Version -match $versionPattern)) { + throw "Invalid version format. Expected format: Major.Minor.Patch (e.g., '5.1.0' or '5.1.0-beta')" + } + + return $true +} + +function Set-Version { + param( + [string]$FilePath, + [string]$NewVersion + ) + + if (-not (Test-Path $FilePath)) { + throw "Directory.Build.props not found at: $FilePath" + } + + $content = Get-Content $FilePath -Raw + $versionMatch = [regex]::Match($content, '[^<]+') + + if (-not $versionMatch.Success) { + throw "Could not find VersionPrefix in Directory.Build.props" + } + + $currentVersionElement = $versionMatch.Groups[0].Value + $newVersionElement = "$NewVersion" + + $newContent = $content -replace [regex]::Escape($currentVersionElement), $newVersionElement + + Set-Content $FilePath -Value $newContent -NoNewline +} + +function Get-CurrentVersion { + param([string]$FilePath) + + $content = Get-Content $FilePath -Raw + $versionMatch = [regex]::Match($content, '([^<]+)') + + if ($versionMatch.Success) { + return $versionMatch.Groups[1].Value + } + + return "Unknown" +} + +try { + Write-Host "Setting version to: $Version" -ForegroundColor Green + + Validate-Version -Version $Version + + $currentVersion = Get-CurrentVersion -FilePath $BuildPropsPath + Write-Host "Current version: $currentVersion" -ForegroundColor Yellow + + Set-Version -FilePath $BuildPropsPath -NewVersion $Version + + Write-Host "Version updated successfully to: $Version" -ForegroundColor Green +} +catch { + Write-Error "Error setting version: $($_.Exception.Message)" + exit 1 +} \ No newline at end of file diff --git a/src/ACUConsole/ACUConsole.csproj b/src/ACUConsole/ACUConsole.csproj index 642910d0..39471fc4 100644 --- a/src/ACUConsole/ACUConsole.csproj +++ b/src/ACUConsole/ACUConsole.csproj @@ -6,6 +6,7 @@ default ACUConsole ACUConsole + $(VersionPrefix.Substring(0,3)).0.0 diff --git a/src/OSDP.Net.sln b/src/OSDP.Net.sln index 9dedf1f4..1b1ee48c 100644 --- a/src/OSDP.Net.sln +++ b/src/OSDP.Net.sln @@ -34,7 +34,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ci", "ci", "{B139D674-6612- ProjectSection(SolutionItems) = preProject ..\ci\build.yml = ..\ci\build.yml ..\ci\package.yml = ..\ci\package.yml - ..\ci\GitVersion.yml = ..\ci\GitVersion.yml ..\azure-pipelines.yml = ..\azure-pipelines.yml EndProjectSection EndProject diff --git a/src/OSDP.Net/OSDP.Net.csproj b/src/OSDP.Net/OSDP.Net.csproj index 54a544c3..d773a3cf 100644 --- a/src/OSDP.Net/OSDP.Net.csproj +++ b/src/OSDP.Net/OSDP.Net.csproj @@ -7,6 +7,7 @@ default netstandard2.0;net8.0 true + $(VersionPrefix.Substring(0,3)).0.0 diff --git a/src/PDConsole/PDConsole.csproj b/src/PDConsole/PDConsole.csproj index 52886a42..88c986a4 100644 --- a/src/PDConsole/PDConsole.csproj +++ b/src/PDConsole/PDConsole.csproj @@ -6,6 +6,7 @@ default PDConsole PDConsole + $(VersionPrefix.Substring(0,3)).0.0