From fdf342a5d48f741d30329ef257b554a287aeacbb Mon Sep 17 00:00:00 2001 From: Stiwi Gabriel Courage Date: Fri, 8 May 2026 12:14:15 +0200 Subject: [PATCH] #174 fix: detect parent git repositories for nova bump Make nova bump and Update-NovaModuleVersion resolve Git history from parent repositories, so nested project folders infer the correct semantic version instead of falling back to Patch with Commits: 0. Add regression coverage for nested project bump inference and update the changelog. Closes #174 --- CHANGELOG.md | 2 + .../GetGitCommitMessagesForVersionBump.ps1 | 2 +- .../release/GetNovaVersionLabelForBump.ps1 | 4 -- tests/CoverageGaps.ReleaseInternals.Tests.ps1 | 22 ++++++++++ .../NovaCommandModel.StandaloneCli.Tests.ps1 | 40 +++++++++++++++++++ 5 files changed, 65 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6af582ec..58489022 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Fixed `nova bump` and `Update-NovaModuleVersion` so nested project folders now reuse parent Git repository history for bump inference instead of silently falling back to `Patch`. + ### Security ## [2.3.0] - 2026-05-06 diff --git a/src/private/release/GetGitCommitMessagesForVersionBump.ps1 b/src/private/release/GetGitCommitMessagesForVersionBump.ps1 index b121f46c..2b5a57e1 100644 --- a/src/private/release/GetGitCommitMessagesForVersionBump.ps1 +++ b/src/private/release/GetGitCommitMessagesForVersionBump.ps1 @@ -4,7 +4,7 @@ function Get-GitCommitMessageForVersionBump { [Parameter(Mandatory)][string]$ProjectRoot ) - if (-not (Test-Path -LiteralPath (Join-Path $ProjectRoot '.git'))) { + if (-not (Test-GitRepositoryIsAvailable -ProjectRoot $ProjectRoot)) { return @() } diff --git a/src/private/release/GetNovaVersionLabelForBump.ps1 b/src/private/release/GetNovaVersionLabelForBump.ps1 index bce84ef8..adb0fe71 100644 --- a/src/private/release/GetNovaVersionLabelForBump.ps1 +++ b/src/private/release/GetNovaVersionLabelForBump.ps1 @@ -35,10 +35,6 @@ function Test-GitRepositoryIsAvailable { [Parameter(Mandatory)][string]$ProjectRoot ) - if (-not (Test-Path -LiteralPath (Join-Path $ProjectRoot '.git'))) { - return $false - } - $result = Invoke-NovaGitCommand -ProjectRoot $ProjectRoot -Arguments @('rev-parse', '--git-dir') return $result.ExitCode -eq 0 } diff --git a/tests/CoverageGaps.ReleaseInternals.Tests.ps1 b/tests/CoverageGaps.ReleaseInternals.Tests.ps1 index 5527d321..83ffcbfb 100644 --- a/tests/CoverageGaps.ReleaseInternals.Tests.ps1 +++ b/tests/CoverageGaps.ReleaseInternals.Tests.ps1 @@ -620,6 +620,28 @@ Describe 'Coverage gaps for release and git internals' { } } + It 'Get-GitCommitMessageForVersionBump resolves parent git repositories for nested project paths' { + if (-not (Get-Command git -ErrorAction SilentlyContinue)) { + Set-ItResult -Skipped -Because 'git is not available in this environment' + return + } + + InModuleScope $script:moduleName { + $repositoryRoot = Join-Path $TestDrive 'parent-git-repo' + $projectRoot = Join-Path $repositoryRoot 'NestedProject' + Initialize-TestGitRepository -Path $repositoryRoot + New-Item -ItemType Directory -Path $projectRoot -Force | Out-Null + New-TestGitCommit -RepositoryPath $repositoryRoot -Message 'feat!: nested project change' -File @{ + Name = 'NestedProject/feature.txt' + Content = 'feature' + } + + $messages = @(Get-GitCommitMessageForVersionBump -ProjectRoot $projectRoot) + + $messages | Should -Be @('feat!: nested project change') + } + } + It 'Get-NovaVersionLabelForBump falls back to Patch when the project is not a git repository' { InModuleScope $script:moduleName { $projectRoot = Join-Path $TestDrive 'no-git-project-for-label' diff --git a/tests/NovaCommandModel.StandaloneCli.Tests.ps1 b/tests/NovaCommandModel.StandaloneCli.Tests.ps1 index 5015c667..2e5cc946 100644 --- a/tests/NovaCommandModel.StandaloneCli.Tests.ps1 +++ b/tests/NovaCommandModel.StandaloneCli.Tests.ps1 @@ -338,6 +338,46 @@ Describe '$projectName tests' { } } + It 'Install-NovaCli infers a major bump from parent Git repository history for nested project roots' { + $targetDirectory = Join-Path $TestDrive 'parent-git-bump-bin' + $installedPath = Join-Path $targetDirectory 'nova' + $repositoryRoot = Join-Path $TestDrive 'CliParentGitRepo' + $projectRoot = Join-Path $repositoryRoot 'AzureDevOpsAgentInstaller' + $projectJsonPath = Join-Path $projectRoot 'project.json' + $originalModulePath = $env:PSModulePath + $modulePathSeparator = [string][System.IO.Path]::PathSeparator + $distParent = Split-Path -Parent $script:distModuleDir + + $env:PSModulePath = "$distParent$modulePathSeparator$originalModulePath" + + New-Item -ItemType Directory -Path $repositoryRoot -Force | Out-Null + Initialize-TestNovaCliProjectLayout -ProjectRoot $projectRoot + Write-TestNovaCliProjectJson -ProjectRoot $projectRoot -ProjectName 'AzureDevOpsAgentInstaller' -ProjectGuid '77777777-7777-7777-7777-777777777777' + Write-TestNovaCliPublicFunction -ProjectRoot $projectRoot -FunctionName 'Invoke-TestNestedParentGitBump' + + $projectData = Get-Content -LiteralPath $projectJsonPath -Raw | ConvertFrom-Json + $projectData.Version = '1.5.4-preview' + $projectData | ConvertTo-Json -Depth 20 | Set-Content -LiteralPath $projectJsonPath -Encoding utf8 + + try { + Initialize-TestNovaCliGitRepository -ProjectRoot $repositoryRoot -CommitMessage 'feat!: add nested parent repo bump coverage' + + Install-NovaCli -DestinationDirectory $targetDirectory -Force | Out-Null + + $result = Invoke-TestInstalledNovaCommand -InstalledPath $installedPath -WorkingDirectory $projectRoot -Arguments @('bump', '--what-if') + $versionAfterBump = (Get-Content -LiteralPath $projectJsonPath -Raw | ConvertFrom-Json).Version + + $result.ExitCode | Should -Be 0 + $result.Text | Should -Match 'What if:' + $result.Text | Should -Match 'Version plan: 1\.5\.4-preview -> 2\.0\.0 \| Label: Major \| Commits: 1' + $result.Text | Should -Not -Match 'Version plan: 1\.5\.4-preview -> 1\.5\.4 \| Label: Patch \| Commits: 0' + $versionAfterBump | Should -Be '1.5.4-preview' + } + finally { + $env:PSModulePath = $originalModulePath + } + } + It 'Install-NovaCli rejects unsupported nova init invocations with clear migration guidance' -ForEach @( @{ Name = 'WhatIf'