diff --git a/docs/input/docs/reference/configuration.md b/docs/input/docs/reference/configuration.md index 502d25a71d..536c5a1299 100644 --- a/docs/input/docs/reference/configuration.md +++ b/docs/input/docs/reference/configuration.md @@ -37,12 +37,11 @@ To see the effective configuration (defaults and overrides), you can run The following supported workflow configurations are available in GitVersion and can be referenced by the workflow property: - GitFlow (GitFlow/v1) - GitHubFlow (GitHubFlow/v1) -- TrunkBased (TrunkBased/v1) Example of using a `TrunkBased` workflow with a different `tag-prefix`: ```yaml -workflow: TrunkBased/v1 +workflow: GitHubFlow/v1 tag-prefix: '[abc]' ``` @@ -76,8 +75,10 @@ branches: prevent-increment: when-current-commit-tagged: false track-merge-target: true + track-merge-message: true regex: ^dev(elop)?(ment)?$ - source-branches: [] + source-branches: + - main is-source-branch-for: [] tracks-release-branches: true is-release-branch: false @@ -89,10 +90,9 @@ branches: prevent-increment: of-merged-branch: true track-merge-target: false + track-merge-message: true regex: ^master$|^main$ - source-branches: - - develop - - release + source-branches: [] is-source-branch-for: [] tracks-release-branches: false is-release-branch: false @@ -101,17 +101,15 @@ branches: release: mode: ManualDeployment label: beta - increment: None + increment: Minor prevent-increment: of-merged-branch: true when-current-commit-tagged: false track-merge-target: false regex: ^releases?[/-](?.+) source-branches: - - develop - main - support - - release is-source-branch-for: [] tracks-release-branches: false is-release-branch: true @@ -121,23 +119,28 @@ branches: mode: ManualDeployment label: '{BranchName}' increment: Inherit - prevent-increment: {} + prevent-increment: + when-current-commit-tagged: false + track-merge-message: true regex: ^features?[/-](?.+) source-branches: - develop - main - release - - feature - support - hotfix is-source-branch-for: [] + is-main-branch: false pre-release-weight: 30000 pull-request: mode: ContinuousDelivery label: PullRequest increment: Inherit - prevent-increment: {} + prevent-increment: + of-merged-branch: true + when-current-commit-tagged: false label-number-pattern: '[/-](?\d+)' + track-merge-message: true regex: ^(pull|pull\-requests|pr)[/-] source-branches: - develop @@ -156,12 +159,11 @@ branches: when-current-commit-tagged: false regex: ^hotfix(es)?[/-](?.+) source-branches: - - release - main - support - - hotfix is-source-branch-for: [] is-release-branch: true + is-main-branch: false pre-release-weight: 30000 support: label: '' @@ -181,7 +183,8 @@ branches: mode: ManualDeployment label: '{BranchName}' increment: Inherit - prevent-increment: {} + prevent-increment: + when-current-commit-tagged: true regex: (?.+) source-branches: - main @@ -192,6 +195,7 @@ branches: - hotfix - support is-source-branch-for: [] + is-main-branch: false ignore: sha: [] mode: ContinuousDelivery @@ -241,10 +245,10 @@ branches: increment: Patch prevent-increment: of-merged-branch: true - track-merge-target: false + tracks-merge-target: false + tracks-merge-message: true regex: ^master$|^main$ - source-branches: - - release + source-branches: [] is-source-branch-for: [] tracks-release-branches: false is-release-branch: false @@ -253,15 +257,16 @@ branches: release: mode: ManualDeployment label: beta - increment: None + increment: Patch prevent-increment: of-merged-branch: true + when-branch-merged: false when-current-commit-tagged: false track-merge-target: false + track-merge-message: true regex: ^releases?[/-](?.+) source-branches: - main - - release is-source-branch-for: [] tracks-release-branches: false is-release-branch: true @@ -271,17 +276,23 @@ branches: mode: ManualDeployment label: '{BranchName}' increment: Inherit + prevent-increment: + when-current-commit-tagged: false regex: ^features?[/-](?.+) source-branches: - main - release - - feature is-source-branch-for: [] + track-merge-message: true + is-main-branch: false pre-release-weight: 30000 pull-request: mode: ContinuousDelivery label: PullRequest increment: Inherit + prevent-increment: + of-merged-branch: true + when-current-commit-tagged: false label-number-pattern: '[/-](?\d+)' regex: ^(pull|pull\-requests|pr)[/-] source-branches: @@ -289,11 +300,14 @@ branches: - release - feature is-source-branch-for: [] + track-merge-message: true pre-release-weight: 30000 unknown: mode: ManualDeployment label: '{BranchName}' increment: Inherit + prevent-increment: + when-current-commit-tagged: false regex: (?.+) source-branches: - main @@ -301,6 +315,8 @@ branches: - feature - pull-request is-source-branch-for: [] + track-merge-message: false + is-main-branch: false ignore: sha: [] mode: ContinuousDelivery @@ -321,97 +337,11 @@ is-release-branch: false is-main-branch: false ``` -The supported built-in configuration for the `TrunkBased` workflow (`workflow: TrunkBased/v1`) looks like: - -```yaml -assembly-versioning-scheme: MajorMinorPatch -assembly-file-versioning-scheme: MajorMinorPatch -tag-prefix: '[vV]?' -version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* -major-version-bump-message: '\+semver:\s?(breaking|major)' -minor-version-bump-message: '\+semver:\s?(feature|minor)' -patch-version-bump-message: '\+semver:\s?(fix|patch)' -no-bump-message: '\+semver:\s?(none|skip)' -tag-pre-release-weight: 60000 -commit-date-format: yyyy-MM-dd -merge-message-formats: {} -update-build-number: true -semantic-version-format: Strict -strategies: -- TrunkBased -- ConfiguredNextVersion -branches: - main: - mode: ContinuousDeployment - label: '' - increment: Patch - prevent-increment: - of-merged-branch: true - track-merge-target: false - regex: ^master$|^main$ - source-branches: [] - tracks-release-branches: false - is-release-branch: false - is-main-branch: true - pre-release-weight: 55000 - feature: - increment: Minor - regex: ^features?[/-](?.+) - prevent-increment: - when-current-commit-tagged: false - source-branches: - - main - pre-release-weight: 30000 - hotfix: - increment: Patch - regex: ^hotfix(es)?[/-](?.+) - prevent-increment: - when-current-commit-tagged: false - source-branches: - - main - pre-release-weight: 30000 - pull-request: - mode: ContinuousDelivery - label: PullRequest - increment: Inherit - label-number-pattern: '[/-](?\d+)' - regex: ^(pull|pull\-requests|pr)[/-] - source-branches: - - main - pre-release-weight: 30000 - unknown: - increment: Patch - regex: (?.+) - prevent-increment: - when-current-commit-tagged: false - source-branches: - - main - pre-release-weight: 30000 -ignore: - sha: [] -mode: ContinuousDelivery -label: '{BranchName}' -increment: Inherit -prevent-increment: - of-merged-branch: false - when-branch-merged: false - when-current-commit-tagged: true -track-merge-target: false -track-merge-message: true -commit-message-incrementing: Enabled -regex: '' -tracks-release-branches: false -is-release-branch: false -is-main-branch: false - -``` - The details of the available options are as follows: ### workflow -The base template of the configuration to use. Possible values are: GitFlow/v1 or GitHubFlow/v1 or TrunkBased/v1. Defaults to GitFlow/v1 if not set. - +The base template of the configuration to use. Possible values are `GitFlow/v1` or `GitHubFlow/v1`. Defaults to `GitFlow/v1` if not set. To create a configuration from scratch without using a base template, please specify an empty string. ### next-version Allows you to bump the next version explicitly. Useful for bumping `main` or a diff --git a/src/GitVersion.Configuration.Tests/Configuration/ConfigurationProviderTests.CanWriteOutEffectiveConfiguration.approved.txt b/src/GitVersion.Configuration.Tests/Configuration/ConfigurationProviderTests.CanWriteOutEffectiveConfiguration.approved.txt index 8cb25f9a4d..78406ad6a1 100644 --- a/src/GitVersion.Configuration.Tests/Configuration/ConfigurationProviderTests.CanWriteOutEffectiveConfiguration.approved.txt +++ b/src/GitVersion.Configuration.Tests/Configuration/ConfigurationProviderTests.CanWriteOutEffectiveConfiguration.approved.txt @@ -25,8 +25,10 @@ branches: prevent-increment: when-current-commit-tagged: false track-merge-target: true + track-merge-message: true regex: ^dev(elop)?(ment)?$ - source-branches: [] + source-branches: + - main is-source-branch-for: [] tracks-release-branches: true is-release-branch: false @@ -38,10 +40,9 @@ branches: prevent-increment: of-merged-branch: true track-merge-target: false + track-merge-message: true regex: ^master$|^main$ - source-branches: - - develop - - release + source-branches: [] is-source-branch-for: [] tracks-release-branches: false is-release-branch: false @@ -50,17 +51,15 @@ branches: release: mode: ManualDeployment label: beta - increment: None + increment: Minor prevent-increment: of-merged-branch: true when-current-commit-tagged: false track-merge-target: false regex: ^releases?[/-](?.+) source-branches: - - develop - main - support - - release is-source-branch-for: [] tracks-release-branches: false is-release-branch: true @@ -70,23 +69,28 @@ branches: mode: ManualDeployment label: '{BranchName}' increment: Inherit - prevent-increment: {} + prevent-increment: + when-current-commit-tagged: false + track-merge-message: true regex: ^features?[/-](?.+) source-branches: - develop - main - release - - feature - support - hotfix is-source-branch-for: [] + is-main-branch: false pre-release-weight: 30000 pull-request: mode: ContinuousDelivery label: PullRequest increment: Inherit - prevent-increment: {} + prevent-increment: + of-merged-branch: true + when-current-commit-tagged: false label-number-pattern: '[/-](?\d+)' + track-merge-message: true regex: ^(pull|pull\-requests|pr)[/-] source-branches: - develop @@ -105,12 +109,11 @@ branches: when-current-commit-tagged: false regex: ^hotfix(es)?[/-](?.+) source-branches: - - release - main - support - - hotfix is-source-branch-for: [] is-release-branch: true + is-main-branch: false pre-release-weight: 30000 support: label: '' @@ -130,7 +133,8 @@ branches: mode: ManualDeployment label: '{BranchName}' increment: Inherit - prevent-increment: {} + prevent-increment: + when-current-commit-tagged: true regex: (?.+) source-branches: - main @@ -141,6 +145,7 @@ branches: - hotfix - support is-source-branch-for: [] + is-main-branch: false ignore: sha: [] mode: ContinuousDelivery diff --git a/src/GitVersion.Configuration.Tests/Configuration/ConfigurationProviderTests.cs b/src/GitVersion.Configuration.Tests/Configuration/ConfigurationProviderTests.cs index dd5256fbd0..45d66f314d 100644 --- a/src/GitVersion.Configuration.Tests/Configuration/ConfigurationProviderTests.cs +++ b/src/GitVersion.Configuration.Tests/Configuration/ConfigurationProviderTests.cs @@ -316,7 +316,7 @@ public void ShouldUseDefaultSourceBranchesWhenNotSpecifiedForDevelop() using var _ = this.fileSystem.SetupConfigFile(path: this.repoPath, text: text); var configuration = this.configurationProvider.ProvideForDirectory(this.repoPath); - configuration.Branches["develop"].SourceBranches.ShouldBe(new List()); + configuration.Branches["develop"].SourceBranches.ShouldBe(["main"]); } [Test] @@ -348,7 +348,7 @@ public void ShouldUseDefaultSourceBranchesWhenNotSpecifiedForFeature() var configuration = this.configurationProvider.ProvideForDirectory(this.repoPath); configuration.Branches["feature"].SourceBranches.ShouldBe( - new List { "develop", MainBranch, "release", "feature", "support", "hotfix" }); + ["develop", MainBranch, "release", "support", "hotfix"]); } [Test] diff --git a/src/GitVersion.Configuration/BranchConfiguration.cs b/src/GitVersion.Configuration/BranchConfiguration.cs index 4a55cf7e4b..6547ea51ac 100644 --- a/src/GitVersion.Configuration/BranchConfiguration.cs +++ b/src/GitVersion.Configuration/BranchConfiguration.cs @@ -107,4 +107,31 @@ public virtual IBranchConfiguration Inherit(IBranchConfiguration configuration) PreReleaseWeight = PreReleaseWeight ?? configuration.PreReleaseWeight }; } + + public virtual IBranchConfiguration Inherit(EffectiveConfiguration configuration) + { + configuration.NotNull(); + + return new BranchConfiguration(this) + { + Increment = Increment == IncrementStrategy.Inherit ? configuration.Increment : Increment, + DeploymentMode = DeploymentMode ?? configuration.DeploymentMode, + Label = Label ?? configuration.Label, + PreventIncrement = new PreventIncrementConfiguration() + { + OfMergedBranch = PreventIncrement.OfMergedBranch ?? configuration.PreventIncrementOfMergedBranch, + WhenBranchMerged = PreventIncrement.WhenBranchMerged ?? configuration.PreventIncrementWhenBranchMerged, + WhenCurrentCommitTagged = PreventIncrement.WhenCurrentCommitTagged ?? configuration.PreventIncrementWhenCurrentCommitTagged + }, + LabelNumberPattern = LabelNumberPattern ?? configuration.LabelNumberPattern, + TrackMergeTarget = TrackMergeTarget ?? configuration.TrackMergeTarget, + TrackMergeMessage = TrackMergeMessage ?? configuration.TrackMergeMessage, + CommitMessageIncrementing = CommitMessageIncrementing ?? configuration.CommitMessageIncrementing, + RegularExpression = RegularExpression ?? configuration.RegularExpression, + TracksReleaseBranches = TracksReleaseBranches ?? configuration.TracksReleaseBranches, + IsReleaseBranch = IsReleaseBranch ?? configuration.IsReleaseBranch, + IsMainBranch = IsMainBranch ?? configuration.IsMainBranch, + PreReleaseWeight = PreReleaseWeight ?? configuration.PreReleaseWeight + }; + } } diff --git a/src/GitVersion.Configuration/Builders/GitFlowConfigurationBuilder.cs b/src/GitVersion.Configuration/Builders/GitFlowConfigurationBuilder.cs index 6256bdda6f..2cba13d408 100644 --- a/src/GitVersion.Configuration/Builders/GitFlowConfigurationBuilder.cs +++ b/src/GitVersion.Configuration/Builders/GitFlowConfigurationBuilder.cs @@ -45,13 +45,14 @@ private GitFlowConfigurationBuilder() { Increment = IncrementStrategy.Minor, RegularExpression = DevelopBranch.RegexPattern, - SourceBranches = [], + SourceBranches = [this.MainBranch.Name], Label = "alpha", PreventIncrement = new PreventIncrementConfiguration() { WhenCurrentCommitTagged = false }, TrackMergeTarget = true, + TrackMergeMessage = true, TracksReleaseBranches = true, IsMainBranch = false, IsReleaseBranch = false, @@ -62,17 +63,14 @@ private GitFlowConfigurationBuilder() { Increment = IncrementStrategy.Patch, RegularExpression = MainBranch.RegexPattern, - SourceBranches = - [ - this.DevelopBranch.Name, - this.ReleaseBranch.Name - ], + SourceBranches = [], Label = string.Empty, PreventIncrement = new PreventIncrementConfiguration() { OfMergedBranch = true }, TrackMergeTarget = false, + TrackMergeMessage = true, TracksReleaseBranches = false, IsMainBranch = true, IsReleaseBranch = false, @@ -81,15 +79,13 @@ private GitFlowConfigurationBuilder() WithBranch(ReleaseBranch.Name).WithConfiguration(new BranchConfiguration { - Increment = IncrementStrategy.None, + Increment = IncrementStrategy.Minor, DeploymentMode = DeploymentMode.ManualDeployment, RegularExpression = ReleaseBranch.RegexPattern, SourceBranches = [ - this.DevelopBranch.Name, this.MainBranch.Name, this.SupportBranch.Name, - this.ReleaseBranch.Name ], Label = "beta", PreventIncrement = new PreventIncrementConfiguration() @@ -114,11 +110,16 @@ private GitFlowConfigurationBuilder() this.DevelopBranch.Name, this.MainBranch.Name, this.ReleaseBranch.Name, - this.FeatureBranch.Name, this.SupportBranch.Name, this.HotfixBranch.Name ], Label = ConfigurationConstants.BranchNamePlaceholder, + PreventIncrement = new PreventIncrementConfiguration() + { + WhenCurrentCommitTagged = false + }, + TrackMergeMessage = true, + IsMainBranch = false, PreReleaseWeight = 30000 }); @@ -137,7 +138,13 @@ private GitFlowConfigurationBuilder() this.HotfixBranch.Name ], Label = "PullRequest", + PreventIncrement = new PreventIncrementConfiguration() + { + OfMergedBranch = true, + WhenCurrentCommitTagged = false + }, LabelNumberPattern = ConfigurationConstants.DefaultLabelNumberPattern, + TrackMergeMessage = true, PreReleaseWeight = 30000 }); @@ -152,13 +159,12 @@ private GitFlowConfigurationBuilder() }, SourceBranches = [ - this.ReleaseBranch.Name, this.MainBranch.Name, this.SupportBranch.Name, - this.HotfixBranch.Name ], Label = "beta", IsReleaseBranch = true, + IsMainBranch = false, PreReleaseWeight = 30000 }); @@ -182,7 +188,6 @@ private GitFlowConfigurationBuilder() WithBranch(UnknownBranch.Name).WithConfiguration(new BranchConfiguration { RegularExpression = UnknownBranch.RegexPattern, - Label = ConfigurationConstants.BranchNamePlaceholder, DeploymentMode = DeploymentMode.ManualDeployment, Increment = IncrementStrategy.Inherit, SourceBranches = @@ -194,7 +199,13 @@ private GitFlowConfigurationBuilder() this.PullRequestBranch.Name, this.HotfixBranch.Name, this.SupportBranch.Name - ] + ], + Label = ConfigurationConstants.BranchNamePlaceholder, + PreventIncrement = new PreventIncrementConfiguration() + { + WhenCurrentCommitTagged = true + }, + IsMainBranch = false, }); } } diff --git a/src/GitVersion.Configuration/Builders/GitHubFlowConfigurationBuilder.cs b/src/GitVersion.Configuration/Builders/GitHubFlowConfigurationBuilder.cs index 9b22a282ff..3b67f085f8 100644 --- a/src/GitVersion.Configuration/Builders/GitHubFlowConfigurationBuilder.cs +++ b/src/GitVersion.Configuration/Builders/GitHubFlowConfigurationBuilder.cs @@ -24,10 +24,8 @@ private GitHubFlowConfigurationBuilder() TagPreReleaseWeight = ConfigurationConstants.DefaultTagPreReleaseWeight, UpdateBuildNumber = ConfigurationConstants.DefaultUpdateBuildNumber, DeploymentMode = DeploymentMode.ContinuousDelivery, - RegularExpression = string.Empty, Label = ConfigurationConstants.BranchNamePlaceholder, Increment = IncrementStrategy.Inherit, - CommitMessageIncrementing = CommitMessageIncrementMode.Enabled, PreventIncrement = new PreventIncrementConfiguration() { OfMergedBranch = false, @@ -36,6 +34,8 @@ private GitHubFlowConfigurationBuilder() }, TrackMergeTarget = false, TrackMergeMessage = true, + CommitMessageIncrementing = CommitMessageIncrementMode.Enabled, + RegularExpression = string.Empty, TracksReleaseBranches = false, IsReleaseBranch = false, IsMainBranch = false @@ -43,88 +43,107 @@ private GitHubFlowConfigurationBuilder() WithBranch(MainBranch.Name).WithConfiguration(new BranchConfiguration { - Increment = IncrementStrategy.Patch, - RegularExpression = MainBranch.RegexPattern, - SourceBranches = [this.ReleaseBranch.Name], Label = string.Empty, + Increment = IncrementStrategy.Patch, PreventIncrement = new PreventIncrementConfiguration() { OfMergedBranch = true }, TrackMergeTarget = false, + TrackMergeMessage = true, + RegularExpression = MainBranch.RegexPattern, + SourceBranches = [], TracksReleaseBranches = false, - IsMainBranch = true, IsReleaseBranch = false, + IsMainBranch = true, PreReleaseWeight = 55000 }); WithBranch(ReleaseBranch.Name).WithConfiguration(new BranchConfiguration { - Increment = IncrementStrategy.None, - RegularExpression = ReleaseBranch.RegexPattern, DeploymentMode = DeploymentMode.ManualDeployment, - SourceBranches = - [ - this.MainBranch.Name, - this.ReleaseBranch.Name - ], Label = "beta", + Increment = IncrementStrategy.Patch, PreventIncrement = new PreventIncrementConfiguration() { OfMergedBranch = true, + WhenBranchMerged = false, WhenCurrentCommitTagged = false }, TrackMergeTarget = false, + TrackMergeMessage = true, + RegularExpression = ReleaseBranch.RegexPattern, + SourceBranches = + [ + this.MainBranch.Name + ], TracksReleaseBranches = false, - IsMainBranch = false, IsReleaseBranch = true, + IsMainBranch = false, PreReleaseWeight = 30000 }); WithBranch(FeatureBranch.Name).WithConfiguration(new BranchConfiguration { + DeploymentMode = DeploymentMode.ManualDeployment, + Label = ConfigurationConstants.BranchNamePlaceholder, Increment = IncrementStrategy.Inherit, + PreventIncrement = new PreventIncrementConfiguration() + { + WhenCurrentCommitTagged = false + }, RegularExpression = FeatureBranch.RegexPattern, - DeploymentMode = DeploymentMode.ManualDeployment, SourceBranches = [ this.MainBranch.Name, - this.ReleaseBranch.Name, - this.FeatureBranch.Name + this.ReleaseBranch.Name ], - Label = ConfigurationConstants.BranchNamePlaceholder, + TrackMergeMessage = true, + IsMainBranch = false, PreReleaseWeight = 30000 }); WithBranch(PullRequestBranch.Name).WithConfiguration(new BranchConfiguration { + DeploymentMode = DeploymentMode.ContinuousDelivery, + Label = "PullRequest", Increment = IncrementStrategy.Inherit, + PreventIncrement = new PreventIncrementConfiguration() + { + OfMergedBranch = true, + WhenCurrentCommitTagged = false + }, + LabelNumberPattern = ConfigurationConstants.DefaultLabelNumberPattern, RegularExpression = PullRequestBranch.RegexPattern, - DeploymentMode = DeploymentMode.ContinuousDelivery, SourceBranches = [ this.MainBranch.Name, this.ReleaseBranch.Name, this.FeatureBranch.Name ], - Label = "PullRequest", - LabelNumberPattern = ConfigurationConstants.DefaultLabelNumberPattern, + TrackMergeMessage = true, PreReleaseWeight = 30000 }); WithBranch(UnknownBranch.Name).WithConfiguration(new BranchConfiguration { - RegularExpression = UnknownBranch.RegexPattern, - Label = ConfigurationConstants.BranchNamePlaceholder, DeploymentMode = DeploymentMode.ManualDeployment, + Label = ConfigurationConstants.BranchNamePlaceholder, Increment = IncrementStrategy.Inherit, + PreventIncrement = new PreventIncrementConfiguration() + { + WhenCurrentCommitTagged = false + }, + RegularExpression = UnknownBranch.RegexPattern, SourceBranches = [ this.MainBranch.Name, this.ReleaseBranch.Name, this.FeatureBranch.Name, this.PullRequestBranch.Name - ] + ], + TrackMergeMessage = false, + IsMainBranch = false }); } } diff --git a/src/GitVersion.Configuration/Builders/TrunkBasedConfigurationBuilder.cs b/src/GitVersion.Configuration/Builders/TrunkBasedConfigurationBuilder.cs index 1a17da8ae4..6ac109ccdb 100644 --- a/src/GitVersion.Configuration/Builders/TrunkBasedConfigurationBuilder.cs +++ b/src/GitVersion.Configuration/Builders/TrunkBasedConfigurationBuilder.cs @@ -46,78 +46,95 @@ private TrunkBasedConfigurationBuilder() WithBranch(MainBranch.Name).WithConfiguration(new BranchConfiguration() { - Increment = IncrementStrategy.Patch, - RegularExpression = MainBranch.RegexPattern, DeploymentMode = DeploymentMode.ContinuousDeployment, - SourceBranches = [], Label = string.Empty, + Increment = IncrementStrategy.Patch, PreventIncrement = new PreventIncrementConfiguration() { OfMergedBranch = true }, TrackMergeTarget = false, + TrackMergeMessage = true, + RegularExpression = MainBranch.RegexPattern, + SourceBranches = [], TracksReleaseBranches = false, - IsMainBranch = true, IsReleaseBranch = false, + IsMainBranch = true, PreReleaseWeight = 55000 }); WithBranch(FeatureBranch.Name).WithConfiguration(new BranchConfiguration() { + DeploymentMode = DeploymentMode.ContinuousDelivery, + Label = ConfigurationConstants.BranchNamePlaceholder, Increment = IncrementStrategy.Minor, + PreventIncrement = new PreventIncrementConfiguration() + { + WhenCurrentCommitTagged = false + }, RegularExpression = FeatureBranch.RegexPattern, SourceBranches = [ this.MainBranch.Name ], - PreventIncrement = new PreventIncrementConfiguration() - { - WhenCurrentCommitTagged = false - }, + TrackMergeMessage = true, + IsMainBranch = false, PreReleaseWeight = 30000 }); WithBranch(HotfixBranch.Name).WithConfiguration(new BranchConfiguration() { + DeploymentMode = DeploymentMode.ContinuousDelivery, + Label = ConfigurationConstants.BranchNamePlaceholder, Increment = IncrementStrategy.Patch, + PreventIncrement = new PreventIncrementConfiguration() + { + WhenCurrentCommitTagged = false + }, RegularExpression = HotfixBranch.RegexPattern, SourceBranches = [ this.MainBranch.Name ], - PreventIncrement = new PreventIncrementConfiguration() - { - WhenCurrentCommitTagged = false - }, + IsReleaseBranch = true, + IsMainBranch = false, PreReleaseWeight = 30000 }); WithBranch(PullRequestBranch.Name).WithConfiguration(new BranchConfiguration { + DeploymentMode = DeploymentMode.ContinuousDelivery, + Label = "PullRequest", Increment = IncrementStrategy.Inherit, + PreventIncrement = new PreventIncrementConfiguration() + { + OfMergedBranch = true, + WhenCurrentCommitTagged = false + }, + LabelNumberPattern = ConfigurationConstants.DefaultLabelNumberPattern, RegularExpression = PullRequestBranch.RegexPattern, - DeploymentMode = DeploymentMode.ContinuousDelivery, SourceBranches = [ - this.MainBranch.Name + this.MainBranch.Name, + this.FeatureBranch.Name, + this.HotfixBranch.Name, ], - Label = "PullRequest", - LabelNumberPattern = ConfigurationConstants.DefaultLabelNumberPattern, + TrackMergeMessage = true, PreReleaseWeight = 30000 }); WithBranch(UnknownBranch.Name).WithConfiguration(new BranchConfiguration { Increment = IncrementStrategy.Patch, + PreventIncrement = new PreventIncrementConfiguration() + { + WhenCurrentCommitTagged = false + }, RegularExpression = UnknownBranch.RegexPattern, SourceBranches = [ this.MainBranch.Name ], - PreventIncrement = new PreventIncrementConfiguration() - { - WhenCurrentCommitTagged = false - }, PreReleaseWeight = 30000 }); } diff --git a/src/GitVersion.Configuration/GitVersionConfiguration.cs b/src/GitVersion.Configuration/GitVersionConfiguration.cs index 079fd14b11..c0823eecc6 100644 --- a/src/GitVersion.Configuration/GitVersionConfiguration.cs +++ b/src/GitVersion.Configuration/GitVersionConfiguration.cs @@ -149,6 +149,8 @@ IReadOnlyDictionary IGitVersionConfiguration.Branc public override IBranchConfiguration Inherit(IBranchConfiguration configuration) => throw new NotSupportedException(); + public override IBranchConfiguration Inherit(EffectiveConfiguration configuration) => throw new NotSupportedException(); + public IBranchConfiguration GetEmptyBranchConfiguration() => new BranchConfiguration { RegularExpression = string.Empty, diff --git a/src/GitVersion.Configuration/Workflows/GitFlow/v1.yml b/src/GitVersion.Configuration/Workflows/GitFlow/v1.yml index 8cb25f9a4d..78406ad6a1 100644 --- a/src/GitVersion.Configuration/Workflows/GitFlow/v1.yml +++ b/src/GitVersion.Configuration/Workflows/GitFlow/v1.yml @@ -25,8 +25,10 @@ branches: prevent-increment: when-current-commit-tagged: false track-merge-target: true + track-merge-message: true regex: ^dev(elop)?(ment)?$ - source-branches: [] + source-branches: + - main is-source-branch-for: [] tracks-release-branches: true is-release-branch: false @@ -38,10 +40,9 @@ branches: prevent-increment: of-merged-branch: true track-merge-target: false + track-merge-message: true regex: ^master$|^main$ - source-branches: - - develop - - release + source-branches: [] is-source-branch-for: [] tracks-release-branches: false is-release-branch: false @@ -50,17 +51,15 @@ branches: release: mode: ManualDeployment label: beta - increment: None + increment: Minor prevent-increment: of-merged-branch: true when-current-commit-tagged: false track-merge-target: false regex: ^releases?[/-](?.+) source-branches: - - develop - main - support - - release is-source-branch-for: [] tracks-release-branches: false is-release-branch: true @@ -70,23 +69,28 @@ branches: mode: ManualDeployment label: '{BranchName}' increment: Inherit - prevent-increment: {} + prevent-increment: + when-current-commit-tagged: false + track-merge-message: true regex: ^features?[/-](?.+) source-branches: - develop - main - release - - feature - support - hotfix is-source-branch-for: [] + is-main-branch: false pre-release-weight: 30000 pull-request: mode: ContinuousDelivery label: PullRequest increment: Inherit - prevent-increment: {} + prevent-increment: + of-merged-branch: true + when-current-commit-tagged: false label-number-pattern: '[/-](?\d+)' + track-merge-message: true regex: ^(pull|pull\-requests|pr)[/-] source-branches: - develop @@ -105,12 +109,11 @@ branches: when-current-commit-tagged: false regex: ^hotfix(es)?[/-](?.+) source-branches: - - release - main - support - - hotfix is-source-branch-for: [] is-release-branch: true + is-main-branch: false pre-release-weight: 30000 support: label: '' @@ -130,7 +133,8 @@ branches: mode: ManualDeployment label: '{BranchName}' increment: Inherit - prevent-increment: {} + prevent-increment: + when-current-commit-tagged: true regex: (?.+) source-branches: - main @@ -141,6 +145,7 @@ branches: - hotfix - support is-source-branch-for: [] + is-main-branch: false ignore: sha: [] mode: ContinuousDelivery diff --git a/src/GitVersion.Configuration/Workflows/GitHubFlow/v1.yml b/src/GitVersion.Configuration/Workflows/GitHubFlow/v1.yml index 4082d04d3e..b6496b4d1d 100644 --- a/src/GitVersion.Configuration/Workflows/GitHubFlow/v1.yml +++ b/src/GitVersion.Configuration/Workflows/GitHubFlow/v1.yml @@ -24,10 +24,10 @@ branches: increment: Patch prevent-increment: of-merged-branch: true - track-merge-target: false + tracks-merge-target: false + tracks-merge-message: true regex: ^master$|^main$ - source-branches: - - release + source-branches: [] is-source-branch-for: [] tracks-release-branches: false is-release-branch: false @@ -36,15 +36,16 @@ branches: release: mode: ManualDeployment label: beta - increment: None + increment: Patch prevent-increment: of-merged-branch: true + when-branch-merged: false when-current-commit-tagged: false track-merge-target: false + track-merge-message: true regex: ^releases?[/-](?.+) source-branches: - main - - release is-source-branch-for: [] tracks-release-branches: false is-release-branch: true @@ -54,17 +55,23 @@ branches: mode: ManualDeployment label: '{BranchName}' increment: Inherit + prevent-increment: + when-current-commit-tagged: false regex: ^features?[/-](?.+) source-branches: - main - release - - feature is-source-branch-for: [] + track-merge-message: true + is-main-branch: false pre-release-weight: 30000 pull-request: mode: ContinuousDelivery label: PullRequest increment: Inherit + prevent-increment: + of-merged-branch: true + when-current-commit-tagged: false label-number-pattern: '[/-](?\d+)' regex: ^(pull|pull\-requests|pr)[/-] source-branches: @@ -72,11 +79,14 @@ branches: - release - feature is-source-branch-for: [] + track-merge-message: true pre-release-weight: 30000 unknown: mode: ManualDeployment label: '{BranchName}' increment: Inherit + prevent-increment: + when-current-commit-tagged: false regex: (?.+) source-branches: - main @@ -84,6 +94,8 @@ branches: - feature - pull-request is-source-branch-for: [] + track-merge-message: false + is-main-branch: false ignore: sha: [] mode: ContinuousDelivery diff --git a/src/GitVersion.Configuration/Workflows/TrunkBased/v1.yml b/src/GitVersion.Configuration/Workflows/TrunkBased/v1.yml index 023be21f85..07f190c332 100644 --- a/src/GitVersion.Configuration/Workflows/TrunkBased/v1.yml +++ b/src/GitVersion.Configuration/Workflows/TrunkBased/v1.yml @@ -21,6 +21,7 @@ branches: increment: Patch prevent-increment: of-merged-branch: true + when-current-commit-tagged: true track-merge-target: false regex: ^master$|^main$ source-branches: [] diff --git a/src/GitVersion.Core.Tests/IntegrationTests/AlignGitFlowWithTrunkBasedVersionStrategy.cs b/src/GitVersion.Core.Tests/IntegrationTests/AlignGitFlowWithTrunkBasedVersionStrategy.cs new file mode 100644 index 0000000000..fb568691dd --- /dev/null +++ b/src/GitVersion.Core.Tests/IntegrationTests/AlignGitFlowWithTrunkBasedVersionStrategy.cs @@ -0,0 +1,11257 @@ +using GitVersion.Configuration; +using GitVersion.VersionCalculation; + +namespace GitVersion.Core.Tests.IntegrationTests; + +[TestFixture] +[Parallelizable(ParallelScope.All)] +public class AlignGitFlowWithTrunkBasedVersionStrategy +{ + private static GitFlowConfigurationBuilder configurationBuilder => GitFlowConfigurationBuilder.New; + + /// + /// GitHubFlow - Feature branch (Increment inherit on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementInheritOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+1", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment inherit on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementInheritOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+4", configuration); + } + else + { + // ❔ expected: "2.0.0-2+4" + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment inherit on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementInheritOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+1", configuration); + + fixture.ApplyTag("2.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+4", configuration); + } + else + { + // ❔ expected: "2.0.1-1+4" + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment inherit on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementInheritOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+1", configuration); + + fixture.ApplyTag("2.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+4", configuration); + } + else + { + // ❔ expected: "2.1.0-1+4" + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment inherit on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementInheritOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+1", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment none on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementNoneOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.ApplyTag("0.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+4", configuration); + } + else + { + // ❔ expected: "0.0.0-2+4" + fixture.AssertFullSemver("0.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment none on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementNoneOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.ApplyTag("0.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+4", configuration); + } + else + { + // ❔ expected: "0.0.0-2+4" + fixture.AssertFullSemver("0.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment none on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementNoneOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+1", configuration); + + fixture.ApplyTag("0.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment none on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementNoneOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment none on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementNoneOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment patch on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementPatchOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+1", configuration); + + fixture.ApplyTag("0.0.3-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment patch on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementPatchOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.ApplyTag("0.0.2-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-2+4", configuration); + } + else + { + // ❔ expected: "0.0.2-2+4" + fixture.AssertFullSemver("0.0.3-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment patch on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementPatchOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+1", configuration); + + fixture.ApplyTag("0.0.3-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment patch on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementPatchOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment patch on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementPatchOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment minor on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMinorOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+1", configuration); + + fixture.ApplyTag("0.3.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment minor on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMinorOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+1", configuration); + + fixture.ApplyTag("0.2.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-2+4", configuration); + } + else + { + // ❔ expected: "0.2.0-2+4" + fixture.AssertFullSemver("0.3.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment minor on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMinorOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.1+1", configuration); + + fixture.ApplyTag("0.2.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-1+4", configuration); + } + else + { + // ❔ expected: "0.2.1-1+4" + fixture.AssertFullSemver("0.3.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment minor on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMinorOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+1", configuration); + + fixture.ApplyTag("0.3.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment minor on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMinorOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment major on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMajorOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+1", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment major on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMajorOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+4", configuration); + } + else + { + // ❔ expected: "2.0.0-2+4" + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment major on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMajorOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+1", configuration); + + fixture.ApplyTag("2.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+4", configuration); + } + else + { + // ❔ expected: "2.0.1-foo.2+3" + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment major on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMajorOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+1", configuration); + + fixture.ApplyTag("2.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+4", configuration); + } + else + { + // ❔ expected: "2.1.0-1+4" + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment major on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMajorOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+1", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment inherit on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementInheritOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+3", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment inherit on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementInheritOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+6", configuration); + } + else + { + // ❔ expected: "2.0.0-2+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment inherit on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementInheritOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+3", configuration); + + fixture.ApplyTag("2.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+6", configuration); + } + else + { + // ❔ expected: "2.0.1-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment inherit on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementInheritOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+3", configuration); + + fixture.ApplyTag("2.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+6", configuration); + } + else + { + // ❔ expected: "2.1.0-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment inherit on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementInheritOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+3", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment none on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementNoneOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+3", configuration); + + fixture.ApplyTag("0.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-3+6", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment none on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementNoneOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+3", configuration); + + fixture.ApplyTag("0.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-3+6", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment none on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementNoneOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MergeTo("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+2", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+2", configuration); + } + + fixture.MakeACommit("D"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+3", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+3", configuration); + } + + fixture.ApplyTag("0.0.2-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment none on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementNoneOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+3", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment none on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementNoneOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment patch on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementPatchOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+3", configuration); + + fixture.ApplyTag("0.0.3-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment patch on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementPatchOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+3", configuration); + + fixture.ApplyTag("0.0.2-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-2+6", configuration); + } + else + { + // ❔ expected: "0.0.2-2+6" + fixture.AssertFullSemver("0.0.3-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment patch on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementPatchOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+3", configuration); + + fixture.ApplyTag("0.0.3-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment patch on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementPatchOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+3", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment patch on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementPatchOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment minor on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMinorOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+3", configuration); + + fixture.ApplyTag("0.3.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment minor on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMinorOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+3", configuration); + + fixture.ApplyTag("0.2.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-2+6", configuration); + } + else + { + // ❔ expected: "0.2.0-1+6" + fixture.AssertFullSemver("0.3.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment minor on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMinorOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.1+3", configuration); + + fixture.ApplyTag("0.2.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-1+6", configuration); + } + else + { + // ❔ expected: "0.2.1-1+6" + fixture.AssertFullSemver("0.3.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment minor on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMinorOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+3", configuration); + + fixture.ApplyTag("0.3.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment minor on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMinorOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment major on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMajorOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+3", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment major on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMajorOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+6", configuration); + } + else + { + // ❔ expected: "2.0.0-2+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment major on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMajorOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+3", configuration); + + fixture.ApplyTag("2.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+6", configuration); + } + else + { + // ❔ expected: "2.0.1-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment major on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMajorOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+3", configuration); + + fixture.ApplyTag("2.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+6", configuration); + } + else + { + // ❔ expected: "2.1.0-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment major on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMajorOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+3", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment inherit on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementInheritOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment inherit on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementInheritOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "1.0.0-PullRequest2.2" + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-2+2", configuration); + } + else + { + // ❔ expected: "1.0.0-1+2" + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment inherit on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementInheritOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "1.0.1-PullRequest2.2" + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-1+2", configuration); + } + else + { + // ❔ expected: "1.0.1-1+2" + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment inherit on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementInheritOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "1.1.0-PullRequest2.2" + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-1+2", configuration); + } + else + { + // ❔ expected: "1.1.0-1+2" + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment inherit on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementInheritOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment none on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementNoneOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+2", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment none on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementNoneOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+2", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment none on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementNoneOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+2", configuration); + } + else + { + // ❔ expected: "0.0.1-1+2" + fixture.AssertFullSemver("0.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment none on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementNoneOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+2", configuration); + } + else + { + // ❔ expected: "0.1.0-1+2" + fixture.AssertFullSemver("0.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment none on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementNoneOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+2", configuration); + } + else + { + // ❔ expected: "1.0.0-1+2" + fixture.AssertFullSemver("0.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment patch on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementPatchOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+2", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment patch on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementPatchOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "0.0.1-PullRequest2.2" + fixture.AssertFullSemver("0.0.2-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-2+2", configuration); + } + else + { + // ❔ expected: "0.0.1-2+2" + fixture.AssertFullSemver("0.0.2-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment patch on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementPatchOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+2", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment patch on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementPatchOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+2", configuration); + } + else + { + // ❔ expected: "0.1.0-1+2" + fixture.AssertFullSemver("0.0.2-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment patch on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementPatchOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+2", configuration); + } + else + { + // ❔ expected: "1.0.0-1+2" + fixture.AssertFullSemver("0.0.2-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment minor on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMinorOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+2", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment minor on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMinorOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "0.1.0-PullRequest2.2" + fixture.AssertFullSemver("0.2.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-2+2", configuration); + } + else + { + // ❔ expected: "0.1.0-1+2" + fixture.AssertFullSemver("0.2.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment minor on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMinorOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "0.1.1-PullRequest2.2" + fixture.AssertFullSemver("0.2.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-1+2", configuration); + } + else + { + // ❔ expected: "0.1.1-1+2" + fixture.AssertFullSemver("0.2.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment minor on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMinorOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+2", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment minor on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMinorOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+2", configuration); + } + else + { + // ❔ expected: "1.0.0-1+2" + fixture.AssertFullSemver("0.2.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment major on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMajorOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment major on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMajorOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "1.0.0-PullRequest2.2" + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-2+2", configuration); + } + else + { + // ❔ expected: "1.0.0-1+2" + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment major on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMajorOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "1.0.1-PullRequest2.2" + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-1+2", configuration); + } + else + { + // ❔ expected: "1.0.1-1+2" + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment major on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMajorOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "1.1.0-PullRequest2.2" + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-1+2", configuration); + } + else + { + // ❔ expected: "1.1.0-1+2" + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment major on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMajorOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment inherit on main) + /// + [TestCase(false, IncrementStrategy.Inherit)] + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseBranchWithIncrementInheritOnMain(bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("release/3.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("release/3.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+4", configuration); + + fixture.ApplyTag("3.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("3.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("4.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment inherit on main and inherit on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + public void EnsureReleaseBranchWithIncrementInheritOnMainAndInheritOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+4", configuration); + + fixture.ApplyTag("3.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("3.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("4.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment inherit on main and none on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseBranchWithIncrementInheritOnMainAndNoneOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); + + fixture.ApplyTag("2.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+6", configuration); + } + else + { + // ❔ expected: "2.0.0-2+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("2.0.0"); + fixture.ApplyTag("2.0.0"); + } + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment inherit on main and patch on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + public void EnsureReleaseBranchWithIncrementInheritOnMainAndPatchOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.1+4", configuration); + + fixture.ApplyTag("2.0.1-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+6", configuration); + } + else + { + // ❔ expected: "2.0.1-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("2.0.1"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment inherit on main and minor on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + public void EnsureReleaseBranchWithIncrementInheritOnMainAndMinorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.1+4", configuration); + + fixture.ApplyTag("2.1.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+6", configuration); + } + else + { + // ❔ expected: "2.1.0-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("2.1.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment inherit on main and major on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + public void EnsureReleaseBranchWithIncrementInheritOnMainAndMajorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+4", configuration); + + fixture.ApplyTag("3.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("3.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("4.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment none on main) + /// + [TestCase(false, IncrementStrategy.Inherit)] + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseBranchWithIncrementNoneOnMain(bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); + + fixture.ApplyTag("2.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("G"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + } + + /// + /// GitHubFlow - Release branch (Increment none on main and inherit on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + public void EnsureReleaseBranchWithIncrementNoneOnMainAndInheritOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+4", configuration); + + fixture.ApplyTag("0.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-3+6", configuration); + } + else + { + // ❔ expected: "0.0.0-3+6" + fixture.AssertFullSemver("0.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MakeACommit("G"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-4+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + } + + /// + /// GitHubFlow - Release branch (Increment none on main and none on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + public void EnsureReleaseBranchWithIncrementNoneOnMainAndNoneOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+4", configuration); + + fixture.ApplyTag("0.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-3+6", configuration); + } + else + { + // ❔ expected: "0.0.0-3+6" + fixture.AssertFullSemver("0.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MakeACommit("G"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-4+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + } + + /// + /// GitHubFlow - Release branch (Increment none on main and patch on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + public void EnsureReleaseBranchWithIncrementNoneOnMainAndPatchOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+4", configuration); + + fixture.ApplyTag("0.0.1-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("G"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + } + } + + /// + /// GitHubFlow - Release branch (Increment none on main and minor on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + public void EnsureReleaseBranchWithIncrementNoneOnMainAndMinorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+4", configuration); + + fixture.ApplyTag("0.1.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("G"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + } + } + + /// + /// GitHubFlow - Release branch (Increment none on main and minor on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + public void EnsureReleaseBranchWithIncrementNoneOnMainAndMajorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + + fixture.ApplyTag("1.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("G"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + } + } + + /// + /// GitHubFlow - Release branch (Increment patch on main) + /// + [TestCase(false, IncrementStrategy.Inherit)] + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseBranchWithIncrementPatchOnMain(bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); + + fixture.ApplyTag("2.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment patch on main and inherit on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + public void EnsureReleaseBranchWithIncrementPatchOnMainAndInheritOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+4", configuration); + + fixture.ApplyTag("0.0.3-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.3"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.4-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment patch on main and none on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + public void EnsureReleaseBranchWithIncrementPatchOnMainAndNoneOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+4", configuration); + + fixture.ApplyTag("0.0.2-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-2+6", configuration); + } + else + { + // ❔ expected: "0.0.2-2+6" + fixture.AssertFullSemver("0.0.3-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.2"); + fixture.ApplyTag("0.0.2"); + } + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment patch on main and patch on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + public void EnsureReleaseBranchWithIncrementPatchOnMainAndPatchOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+4", configuration); + + fixture.ApplyTag("0.0.3-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.3"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.4-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment patch on main and minor on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + public void EnsureReleaseBranchWithIncrementPatchOnMainAndMinorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+4", configuration); + + fixture.ApplyTag("0.1.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment patch on main and major on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + public void EnsureReleaseBranchWithIncrementPatchOnMainAndMajorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + + fixture.ApplyTag("1.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment minor on main) + /// + [TestCase(false, IncrementStrategy.Inherit)] + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseBranchWithIncrementMinorOnMain(bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); + + fixture.ApplyTag("2.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment minor on main and inherit on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + public void EnsureReleaseBranchWithIncrementMinorOnMainAndInheritOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.1+4", configuration); + + fixture.ApplyTag("0.3.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.3.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.4.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment minor on main and none on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + public void EnsureReleaseBranchWithIncrementMinorOnMainAndNoneOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+4", configuration); + + fixture.ApplyTag("0.2.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-2+6", configuration); + } + else + { + // ❔ expected: "0.2.0-2+6" + fixture.AssertFullSemver("0.3.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.2.0"); + fixture.ApplyTag("0.2.0"); + } + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment minor on main and patch on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + public void EnsureReleaseBranchWithIncrementMinorOnMainAndPatchOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-beta.1+4", configuration); + + fixture.ApplyTag("0.2.1-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-1+6", configuration); + } + else + { + // ❔ expected: "0.2.1-1+6" + fixture.AssertFullSemver("0.3.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("0.2.1"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment minor on main and minor on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + public void EnsureReleaseBranchWithIncrementMinorOnMainAndMinorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.1+4", configuration); + + fixture.ApplyTag("0.3.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.3.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.4.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment minor on main and major on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + public void EnsureReleaseBranchWithIncrementMinorOnMainAndMajorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + + fixture.ApplyTag("1.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment major on main) + /// + [TestCase(false, IncrementStrategy.Inherit)] + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseBranchWithIncrementMajorOnMain(bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("release/3.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("release/3.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+4", configuration); + + fixture.ApplyTag("3.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("3.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("4.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment major on main and inherit on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + [TestCase(false, "release/1.1.1")] + [TestCase(true, "release/1.1.1")] + public void EnsureReleaseBranchWithIncrementMajorOnMainAndInheritOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+4", configuration); + + fixture.ApplyTag("3.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("3.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("4.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment major on main and none on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseBranchWithIncrementMajorOnMainAndNoneOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); + + fixture.ApplyTag("2.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+6", configuration); + } + else + { + // ❔ expected: "2.0.0-2+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("2.0.0"); + fixture.ApplyTag("2.0.0"); + } + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment major on main and patch on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + public void EnsureReleaseBranchWithIncrementMajorOnMainAndPatchOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.1+4", configuration); + + fixture.ApplyTag("2.0.1-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+6", configuration); + } + else + { + // ❔ expected: "2.0.1-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("2.0.1"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment major on main and minor on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + public void EnsureReleaseBranchWithIncrementMajorOnMainAndMinorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.1+4", configuration); + + fixture.ApplyTag("2.1.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+6", configuration); + } + else + { + // ❔ expected: "2.1.0-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("2.1.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment major on main and major on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + [TestCase(false, "release/1.1.1")] + [TestCase(true, "release/1.1.1")] + public void EnsureReleaseBranchWithIncrementMajorOnMainAndMajorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+4", configuration); + + fixture.ApplyTag("3.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("3.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("4.0.0-1+1", configuration); + } + + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseAndFeatureBranchWithIncrementInheritOnMain( + bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout("release/2.0.0"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo("release/2.0.0", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementInheritOnMainAndInheritOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementInheritOnMainAndNoneOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-2+6", configuration); + } + else + { + // ❔ expected: "1.0.0-2+6" + fixture.AssertFullSemver("2.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("1.0.0"); + fixture.ApplyTag("1.0.0"); + } + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + public void EnsureReleaseAndFeatureBranchWithIncrementInheritOnMainAndPatchOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+3", configuration); + + fixture.ApplyTag("1.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-1+6", configuration); + } + else + { + // ❔ expected: "1.0.1-1+6" + fixture.AssertFullSemver("2.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("1.0.1"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.0.2")] + [TestCase(true, "release/1.0.2")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementInheritOnMainAndMinorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+3", configuration); + + fixture.ApplyTag("1.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-1+6", configuration); + } + else + { + // ❔ expected: "1.1.0-1+6" + fixture.AssertFullSemver("2.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("1.1.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.0.2")] + [TestCase(true, "release/1.0.2")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + [TestCase(false, "release/1.1.1")] + [TestCase(true, "release/1.1.1")] + [TestCase(false, "release/2.0.0")] + [TestCase(true, "release/2.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementInheritOnMainAndMajorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseAndFeatureBranchWithIncrementNoneOnMain( + bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout("release/2.0.0"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo("release/2.0.0", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementNoneOnMainAndInheritOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+3", configuration); + + fixture.ApplyTag("0.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+6", configuration); + } + else + { + // ❔ expected: "0.0.0-2+6" + fixture.AssertFullSemver("0.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MakeACommit("F"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-3+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementNoneOnMainAndNoneOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+3", configuration); + + fixture.ApplyTag("0.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+6", configuration); + } + else + { + // ❔ expected: "0.0.0-2+6" + fixture.AssertFullSemver("0.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MakeACommit("F"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-3+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(true, "release/0.0.1")] + public void EnsureReleaseAndFeatureBranchWithIncrementNoneOnMainAndPatchOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+3", configuration); + + fixture.ApplyTag("0.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("F"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + } + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(true, "release/0.0.1")] + [TestCase(true, "release/0.0.2")] + [TestCase(true, "release/0.1.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementNoneOnMainAndMinorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+3", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("F"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + } + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(true, "release/0.0.1")] + [TestCase(true, "release/0.0.2")] + [TestCase(true, "release/0.1.0")] + [TestCase(true, "release/0.1.1")] + [TestCase(true, "release/0.2.0")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementNoneOnMainAndMajorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("F"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + } + } + + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseAndFeatureBranchWithIncrementPatchOnMain( + bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout("release/2.0.0"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo("release/2.0.0", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + public void EnsureReleaseAndFeatureBranchWithIncrementPatchOnMainAndInheritOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+3", configuration); + + fixture.ApplyTag("0.0.2-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + public void EnsureReleaseAndFeatureBranchWithIncrementPatchOnMainAndNoneOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+3", configuration); + + fixture.ApplyTag("0.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-2+6", configuration); + } + else + { + // ❔ expected: "0.0.1-2+6" + fixture.AssertFullSemver("0.0.2-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.1"); + fixture.ApplyTag("0.0.1"); + } + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + public void EnsureReleaseAndFeatureBranchWithIncrementPatchOnMainAndPatchOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+3", configuration); + + fixture.ApplyTag("0.0.2-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(true, "release/0.1.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementPatchOnMainAndMinorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+3", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(true, "release/0.1.0")] + [TestCase(true, "release/0.1.1")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementPatchOnMainAndMajorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-1+1", configuration); + } + + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseAndFeatureBranchWithIncrementMinorOnMain( + bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout("release/2.0.0"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo("release/2.0.0", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMinorOnMainAndInheritOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+3", configuration); + + fixture.ApplyTag("0.2.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMinorOnMainAndNoneOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+3", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-2+6", configuration); + } + else + { + // ❔ not expected + fixture.AssertFullSemver("0.2.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.1.0"); + fixture.ApplyTag("0.1.0"); + } + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + public void EnsureReleaseAndFeatureBranchWithIncrementMinorOnMainAndPatchOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.1+3", configuration); + + fixture.ApplyTag("0.1.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-1+6", configuration); + } + else + { + // ❔ not expected + fixture.AssertFullSemver("0.2.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("0.1.1"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMinorOnMainAndMinorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+3", configuration); + + fixture.ApplyTag("0.2.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMinorOnMainAndMajorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-1+1", configuration); + } + + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseAndFeatureBranchWithIncrementMajorOnMain( + bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout("release/2.0.0"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo("release/2.0.0", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMajorOnMainAndInheritOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMajorOnMainAndNoneOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-2+6", configuration); + } + else + { + // ❔ expected: "1.0.0-2+6" + fixture.AssertFullSemver("2.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("1.0.0"); + fixture.ApplyTag("1.0.0"); + } + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + public void EnsureReleaseAndFeatureBranchWithIncrementMajorOnMainAndPatchOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+3", configuration); + + fixture.ApplyTag("1.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-1+6", configuration); + } + else + { + // ❔ expected: "1.0.1-1+6" + fixture.AssertFullSemver("2.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("1.0.1"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.0.2")] + [TestCase(true, "release/1.0.2")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMajorOnMainAndMinorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+3", configuration); + + fixture.ApplyTag("1.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-1+6", configuration); + } + else + { + // ❔ expected: "1.1.0-1+6" + fixture.AssertFullSemver("2.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("1.1.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.0.2")] + [TestCase(true, "release/1.0.2")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + [TestCase(false, "release/1.1.1")] + [TestCase(true, "release/1.1.1")] + [TestCase(false, "release/2.0.0")] + [TestCase(true, "release/2.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMajorOnMainAndMajorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } +} diff --git a/src/GitVersion.Core.Tests/IntegrationTests/AlignGitHubFlowWithTrunkBasedVersionStrategy.cs b/src/GitVersion.Core.Tests/IntegrationTests/AlignGitHubFlowWithTrunkBasedVersionStrategy.cs new file mode 100644 index 0000000000..742250c376 --- /dev/null +++ b/src/GitVersion.Core.Tests/IntegrationTests/AlignGitHubFlowWithTrunkBasedVersionStrategy.cs @@ -0,0 +1,11257 @@ +using GitVersion.Configuration; +using GitVersion.VersionCalculation; + +namespace GitVersion.Core.Tests.IntegrationTests; + +[TestFixture] +[Parallelizable(ParallelScope.All)] +public class AlignGitHubFlowWithTrunkBasedVersionStrategy +{ + private static GitHubFlowConfigurationBuilder configurationBuilder => GitHubFlowConfigurationBuilder.New; + + /// + /// GitHubFlow - Feature branch (Increment inherit on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementInheritOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+1", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment inherit on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementInheritOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+4", configuration); + } + else + { + // ❔ expected: "2.0.0-2+4" + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment inherit on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementInheritOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+1", configuration); + + fixture.ApplyTag("2.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+4", configuration); + } + else + { + // ❔ expected: "2.0.1-1+4" + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment inherit on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementInheritOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+1", configuration); + + fixture.ApplyTag("2.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+4", configuration); + } + else + { + // ❔ expected: "2.1.0-1+4" + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment inherit on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementInheritOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+1", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment none on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementNoneOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.ApplyTag("0.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+4", configuration); + } + else + { + // ❔ expected: "0.0.0-2+4" + fixture.AssertFullSemver("0.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment none on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementNoneOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.ApplyTag("0.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+4", configuration); + } + else + { + // ❔ expected: "0.0.0-2+4" + fixture.AssertFullSemver("0.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment none on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementNoneOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+1", configuration); + + fixture.ApplyTag("0.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment none on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementNoneOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment none on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementNoneOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment patch on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementPatchOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+1", configuration); + + fixture.ApplyTag("0.0.3-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment patch on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementPatchOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.ApplyTag("0.0.2-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-2+4", configuration); + } + else + { + // ❔ expected: "0.0.2-2+4" + fixture.AssertFullSemver("0.0.3-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment patch on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementPatchOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+1", configuration); + + fixture.ApplyTag("0.0.3-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment patch on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementPatchOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment patch on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementPatchOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment minor on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMinorOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+1", configuration); + + fixture.ApplyTag("0.3.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment minor on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMinorOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+1", configuration); + + fixture.ApplyTag("0.2.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-2+4", configuration); + } + else + { + // ❔ expected: "0.2.0-2+4" + fixture.AssertFullSemver("0.3.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment minor on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMinorOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.1+1", configuration); + + fixture.ApplyTag("0.2.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-1+4", configuration); + } + else + { + // ❔ expected: "0.2.1-1+4" + fixture.AssertFullSemver("0.3.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment minor on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMinorOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+1", configuration); + + fixture.ApplyTag("0.3.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment minor on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMinorOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment major on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMajorOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+1", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + + /// + /// GitHubFlow - Feature branch (Increment major on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMajorOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+4", configuration); + } + else + { + // ❔ expected: "2.0.0-2+4" + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment major on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMajorOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+1", configuration); + + fixture.ApplyTag("2.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+4", configuration); + } + else + { + // ❔ expected: "2.0.1-foo.2+3" + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment major on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMajorOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+1", configuration); + + fixture.ApplyTag("2.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+4", configuration); + } + else + { + // ❔ expected: "2.1.0-1+4" + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + } + + /// + /// GitHubFlow - Feature branch (Increment major on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureWithIncrementMajorOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+1", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+4", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment inherit on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementInheritOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+3", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment inherit on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementInheritOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+6", configuration); + } + else + { + // ❔ expected: "2.0.0-2+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment inherit on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementInheritOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+3", configuration); + + fixture.ApplyTag("2.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+6", configuration); + } + else + { + // ❔ expected: "2.0.1-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment inherit on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementInheritOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+3", configuration); + + fixture.ApplyTag("2.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+6", configuration); + } + else + { + // ❔ expected: "2.1.0-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment inherit on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementInheritOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+3", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment none on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementNoneOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+3", configuration); + + fixture.ApplyTag("0.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-3+6", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment none on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementNoneOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+3", configuration); + + fixture.ApplyTag("0.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-3+6", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment none on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementNoneOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MergeTo("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+2", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+2", configuration); + } + + fixture.MakeACommit("D"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+3", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+3", configuration); + } + + fixture.ApplyTag("0.0.2-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment none on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementNoneOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+3", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment none on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementNoneOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment patch on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementPatchOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+3", configuration); + + fixture.ApplyTag("0.0.3-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment patch on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementPatchOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+3", configuration); + + fixture.ApplyTag("0.0.2-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-2+6", configuration); + } + else + { + // ❔ expected: "0.0.2-2+6" + fixture.AssertFullSemver("0.0.3-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment patch on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementPatchOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+3", configuration); + + fixture.ApplyTag("0.0.3-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment patch on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementPatchOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+3", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment patch on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementPatchOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment minor on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMinorOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+3", configuration); + + fixture.ApplyTag("0.3.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment minor on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMinorOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+3", configuration); + + fixture.ApplyTag("0.2.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-2+6", configuration); + } + else + { + // ❔ expected: "0.2.0-1+6" + fixture.AssertFullSemver("0.3.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment minor on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMinorOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.1+3", configuration); + + fixture.ApplyTag("0.2.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-1+6", configuration); + } + else + { + // ❔ expected: "0.2.1-1+6" + fixture.AssertFullSemver("0.3.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment minor on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMinorOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.1+3", configuration); + + fixture.ApplyTag("0.3.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment minor on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMinorOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment major on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMajorOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+3", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment major on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMajorOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+6", configuration); + } + else + { + // ❔ expected: "2.0.0-2+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment major on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMajorOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.1+3", configuration); + + fixture.ApplyTag("2.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+6", configuration); + } + else + { + // ❔ expected: "2.0.1-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment major on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMajorOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.1+3", configuration); + + fixture.ApplyTag("2.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+6", configuration); + } + else + { + // ❔ expected: "2.1.0-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment major on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeatureWithIncrementMajorOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.1+3", configuration); + + fixture.ApplyTag("3.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment inherit on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementInheritOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment inherit on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementInheritOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "1.0.0-PullRequest2.2" + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-2+2", configuration); + } + else + { + // ❔ expected: "1.0.0-1+2" + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment inherit on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementInheritOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "1.0.1-PullRequest2.2" + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-1+2", configuration); + } + else + { + // ❔ expected: "1.0.1-1+2" + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment inherit on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementInheritOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "1.1.0-PullRequest2.2" + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-1+2", configuration); + } + else + { + // ❔ expected: "1.1.0-1+2" + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment inherit on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementInheritOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment none on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementNoneOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+2", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment none on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementNoneOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+2", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment none on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementNoneOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+2", configuration); + } + else + { + // ❔ expected: "0.0.1-1+2" + fixture.AssertFullSemver("0.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment none on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementNoneOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+2", configuration); + } + else + { + // ❔ expected: "0.1.0-1+2" + fixture.AssertFullSemver("0.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment none on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementNoneOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+2", configuration); + } + else + { + // ❔ expected: "1.0.0-1+2" + fixture.AssertFullSemver("0.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment patch on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementPatchOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+2", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment patch on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementPatchOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "0.0.1-PullRequest2.2" + fixture.AssertFullSemver("0.0.2-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-2+2", configuration); + } + else + { + // ❔ expected: "0.0.1-2+2" + fixture.AssertFullSemver("0.0.2-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment patch on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementPatchOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+2", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment patch on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementPatchOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+2", configuration); + } + else + { + // ❔ expected: "0.1.0-1+2" + fixture.AssertFullSemver("0.0.2-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment patch on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementPatchOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+2", configuration); + } + else + { + // ❔ expected: "1.0.0-1+2" + fixture.AssertFullSemver("0.0.2-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment minor on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMinorOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+2", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment minor on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMinorOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "0.1.0-PullRequest2.2" + fixture.AssertFullSemver("0.2.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-2+2", configuration); + } + else + { + // ❔ expected: "0.1.0-1+2" + fixture.AssertFullSemver("0.2.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment minor on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMinorOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "0.1.1-PullRequest2.2" + fixture.AssertFullSemver("0.2.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-1+2", configuration); + } + else + { + // ❔ expected: "0.1.1-1+2" + fixture.AssertFullSemver("0.2.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment minor on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMinorOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+2", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment minor on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMinorOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+2", configuration); + } + else + { + // ❔ expected: "1.0.0-1+2" + fixture.AssertFullSemver("0.2.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment major on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMajorOnMainAndInheritOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment major on main and none on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMajorOnMainAndNoneOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.None) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "1.0.0-PullRequest2.2" + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-2+2", configuration); + } + else + { + // ❔ expected: "1.0.0-1+2" + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment major on main and patch on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMajorOnMainAndPatchOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Patch) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "1.0.1-PullRequest2.2" + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-1+2", configuration); + } + else + { + // ❔ expected: "1.0.1-1+2" + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment major on main and minor on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMajorOnMainAndMinorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Minor) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-PullRequest2.2", configuration); + } + else + { + // ❔ expected: "1.1.0-PullRequest2.2" + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + } + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-1+2", configuration); + } + else + { + // ❔ expected: "1.1.0-1+2" + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + } + + /// + /// GitHubFlow - Pull requests (increment major on main and major on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequestWithIncrementMajorOnMainAndMajorOnFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Major) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+2", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment inherit on main) + /// + [TestCase(false, IncrementStrategy.Inherit)] + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseBranchWithIncrementInheritOnMain(bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("release/3.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("release/3.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+4", configuration); + + fixture.ApplyTag("3.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("3.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("4.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment inherit on main and inherit on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + public void EnsureReleaseBranchWithIncrementInheritOnMainAndInheritOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+4", configuration); + + fixture.ApplyTag("3.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("3.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("4.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment inherit on main and none on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseBranchWithIncrementInheritOnMainAndNoneOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); + + fixture.ApplyTag("2.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+6", configuration); + } + else + { + // ❔ expected: "2.0.0-2+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("2.0.0"); + fixture.ApplyTag("2.0.0"); + } + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment inherit on main and patch on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + public void EnsureReleaseBranchWithIncrementInheritOnMainAndPatchOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.1+4", configuration); + + fixture.ApplyTag("2.0.1-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+6", configuration); + } + else + { + // ❔ expected: "2.0.1-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("2.0.1"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment inherit on main and minor on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + public void EnsureReleaseBranchWithIncrementInheritOnMainAndMinorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.1+4", configuration); + + fixture.ApplyTag("2.1.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+6", configuration); + } + else + { + // ❔ expected: "2.1.0-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("2.1.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment inherit on main and major on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + public void EnsureReleaseBranchWithIncrementInheritOnMainAndMajorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+4", configuration); + + fixture.ApplyTag("3.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("3.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("4.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment none on main) + /// + [TestCase(false, IncrementStrategy.Inherit)] + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseBranchWithIncrementNoneOnMain(bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); + + fixture.ApplyTag("2.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("G"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + } + + /// + /// GitHubFlow - Release branch (Increment none on main and inherit on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + public void EnsureReleaseBranchWithIncrementNoneOnMainAndInheritOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+4", configuration); + + fixture.ApplyTag("0.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-3+6", configuration); + } + else + { + // ❔ expected: "0.0.0-3+6" + fixture.AssertFullSemver("0.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MakeACommit("G"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-4+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + } + + /// + /// GitHubFlow - Release branch (Increment none on main and none on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + public void EnsureReleaseBranchWithIncrementNoneOnMainAndNoneOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+4", configuration); + + fixture.ApplyTag("0.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-3+6", configuration); + } + else + { + // ❔ expected: "0.0.0-3+6" + fixture.AssertFullSemver("0.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MakeACommit("G"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-4+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + } + + /// + /// GitHubFlow - Release branch (Increment none on main and patch on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + public void EnsureReleaseBranchWithIncrementNoneOnMainAndPatchOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+4", configuration); + + fixture.ApplyTag("0.0.1-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("G"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + } + } + + /// + /// GitHubFlow - Release branch (Increment none on main and minor on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + public void EnsureReleaseBranchWithIncrementNoneOnMainAndMinorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+4", configuration); + + fixture.ApplyTag("0.1.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("G"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + } + } + + /// + /// GitHubFlow - Release branch (Increment none on main and minor on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + public void EnsureReleaseBranchWithIncrementNoneOnMainAndMajorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + + fixture.ApplyTag("1.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("G"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + } + } + + /// + /// GitHubFlow - Release branch (Increment patch on main) + /// + [TestCase(false, IncrementStrategy.Inherit)] + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseBranchWithIncrementPatchOnMain(bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); + + fixture.ApplyTag("2.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment patch on main and inherit on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + public void EnsureReleaseBranchWithIncrementPatchOnMainAndInheritOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+4", configuration); + + fixture.ApplyTag("0.0.3-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.3"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.4-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment patch on main and none on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + public void EnsureReleaseBranchWithIncrementPatchOnMainAndNoneOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+4", configuration); + + fixture.ApplyTag("0.0.2-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-2+6", configuration); + } + else + { + // ❔ expected: "0.0.2-2+6" + fixture.AssertFullSemver("0.0.3-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.2"); + fixture.ApplyTag("0.0.2"); + } + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment patch on main and patch on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + public void EnsureReleaseBranchWithIncrementPatchOnMainAndPatchOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+4", configuration); + + fixture.ApplyTag("0.0.3-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.3"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.4-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment patch on main and minor on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + public void EnsureReleaseBranchWithIncrementPatchOnMainAndMinorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+4", configuration); + + fixture.ApplyTag("0.1.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment patch on main and major on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + public void EnsureReleaseBranchWithIncrementPatchOnMainAndMajorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + + fixture.ApplyTag("1.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment minor on main) + /// + [TestCase(false, IncrementStrategy.Inherit)] + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseBranchWithIncrementMinorOnMain(bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); + + fixture.ApplyTag("2.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment minor on main and inherit on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + public void EnsureReleaseBranchWithIncrementMinorOnMainAndInheritOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.1+4", configuration); + + fixture.ApplyTag("0.3.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.3.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.4.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment minor on main and none on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + public void EnsureReleaseBranchWithIncrementMinorOnMainAndNoneOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+4", configuration); + + fixture.ApplyTag("0.2.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-2+6", configuration); + } + else + { + // ❔ expected: "0.2.0-2+6" + fixture.AssertFullSemver("0.3.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.2.0"); + fixture.ApplyTag("0.2.0"); + } + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment minor on main and patch on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + public void EnsureReleaseBranchWithIncrementMinorOnMainAndPatchOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-beta.1+4", configuration); + + fixture.ApplyTag("0.2.1-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.1-1+6", configuration); + } + else + { + // ❔ expected: "0.2.1-1+6" + fixture.AssertFullSemver("0.3.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("0.2.1"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment minor on main and minor on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + public void EnsureReleaseBranchWithIncrementMinorOnMainAndMinorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.1+4", configuration); + + fixture.ApplyTag("0.3.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.3.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.4.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment minor on main and major on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + public void EnsureReleaseBranchWithIncrementMinorOnMainAndMajorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + + fixture.ApplyTag("1.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment major on main) + /// + [TestCase(false, IncrementStrategy.Inherit)] + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseBranchWithIncrementMajorOnMain(bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("release/3.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo("release/3.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+4", configuration); + + fixture.ApplyTag("3.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("3.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("4.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment major on main and inherit on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + [TestCase(false, "release/1.1.1")] + [TestCase(true, "release/1.1.1")] + public void EnsureReleaseBranchWithIncrementMajorOnMainAndInheritOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+4", configuration); + + fixture.ApplyTag("3.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("3.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("4.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment major on main and none on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseBranchWithIncrementMajorOnMainAndNoneOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); + + fixture.ApplyTag("2.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+6", configuration); + } + else + { + // ❔ expected: "2.0.0-2+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("2.0.0"); + fixture.ApplyTag("2.0.0"); + } + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment major on main and patch on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + public void EnsureReleaseBranchWithIncrementMajorOnMainAndPatchOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.1+4", configuration); + + fixture.ApplyTag("2.0.1-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+6", configuration); + } + else + { + // ❔ expected: "2.0.1-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("2.0.1"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment major on main and minor on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + public void EnsureReleaseBranchWithIncrementMajorOnMainAndMinorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.1+4", configuration); + + fixture.ApplyTag("2.1.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+6", configuration); + } + else + { + // ❔ expected: "2.1.0-1+6" + fixture.AssertFullSemver("3.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("2.1.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment major on main and major on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + [TestCase(false, "release/1.1.1")] + [TestCase(true, "release/1.1.1")] + public void EnsureReleaseBranchWithIncrementMajorOnMainAndMajorOnReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.1+4", configuration); + + fixture.ApplyTag("3.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("3.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("4.0.0-1+1", configuration); + } + + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseAndFeatureBranchWithIncrementInheritOnMain( + bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout("release/2.0.0"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo("release/2.0.0", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementInheritOnMainAndInheritOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementInheritOnMainAndNoneOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-2+6", configuration); + } + else + { + // ❔ expected: "1.0.0-2+6" + fixture.AssertFullSemver("2.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("1.0.0"); + fixture.ApplyTag("1.0.0"); + } + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + public void EnsureReleaseAndFeatureBranchWithIncrementInheritOnMainAndPatchOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+3", configuration); + + fixture.ApplyTag("1.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-1+6", configuration); + } + else + { + // ❔ expected: "1.0.1-1+6" + fixture.AssertFullSemver("2.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("1.0.1"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.0.2")] + [TestCase(true, "release/1.0.2")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementInheritOnMainAndMinorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+3", configuration); + + fixture.ApplyTag("1.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-1+6", configuration); + } + else + { + // ❔ expected: "1.1.0-1+6" + fixture.AssertFullSemver("2.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("1.1.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.0.2")] + [TestCase(true, "release/1.0.2")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + [TestCase(false, "release/1.1.1")] + [TestCase(true, "release/1.1.1")] + [TestCase(false, "release/2.0.0")] + [TestCase(true, "release/2.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementInheritOnMainAndMajorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Inherit) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseAndFeatureBranchWithIncrementNoneOnMain( + bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout("release/2.0.0"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo("release/2.0.0", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementNoneOnMainAndInheritOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+3", configuration); + + fixture.ApplyTag("0.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+6", configuration); + } + else + { + // ❔ expected: "0.0.0-2+6" + fixture.AssertFullSemver("0.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MakeACommit("F"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-3+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementNoneOnMainAndNoneOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.1+3", configuration); + + fixture.ApplyTag("0.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-2+6", configuration); + } + else + { + // ❔ expected: "0.0.0-2+6" + fixture.AssertFullSemver("0.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.0"); + fixture.ApplyTag("0.0.0"); + } + fixture.MakeACommit("F"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-3+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + } + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(true, "release/0.0.1")] + public void EnsureReleaseAndFeatureBranchWithIncrementNoneOnMainAndPatchOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+3", configuration); + + fixture.ApplyTag("0.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("F"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + } + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(true, "release/0.0.1")] + [TestCase(true, "release/0.0.2")] + [TestCase(true, "release/0.1.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementNoneOnMainAndMinorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+3", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("F"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + } + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(true, "release/0.0.1")] + [TestCase(true, "release/0.0.2")] + [TestCase(true, "release/0.1.0")] + [TestCase(true, "release/0.1.1")] + [TestCase(true, "release/0.2.0")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementNoneOnMainAndMajorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.None) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("F"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-2+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + } + } + + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseAndFeatureBranchWithIncrementPatchOnMain( + bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout("release/2.0.0"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo("release/2.0.0", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + public void EnsureReleaseAndFeatureBranchWithIncrementPatchOnMainAndInheritOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+3", configuration); + + fixture.ApplyTag("0.0.2-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + public void EnsureReleaseAndFeatureBranchWithIncrementPatchOnMainAndNoneOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.1+3", configuration); + + fixture.ApplyTag("0.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-2+6", configuration); + } + else + { + // ❔ expected: "0.0.1-2+6" + fixture.AssertFullSemver("0.0.2-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.0.1"); + fixture.ApplyTag("0.0.1"); + } + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + public void EnsureReleaseAndFeatureBranchWithIncrementPatchOnMainAndPatchOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+3", configuration); + + fixture.ApplyTag("0.0.2-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(true, "release/0.1.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementPatchOnMainAndMinorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+3", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(true, "release/0.1.0")] + [TestCase(true, "release/0.1.1")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementPatchOnMainAndMajorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Patch) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-1+1", configuration); + } + + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseAndFeatureBranchWithIncrementMinorOnMain( + bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout("release/2.0.0"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo("release/2.0.0", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.1.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMinorOnMainAndInheritOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+3", configuration); + + fixture.ApplyTag("0.2.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMinorOnMainAndNoneOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+3", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-2+6", configuration); + } + else + { + // ❔ not expected + fixture.AssertFullSemver("0.2.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("0.1.0"); + fixture.ApplyTag("0.1.0"); + } + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + public void EnsureReleaseAndFeatureBranchWithIncrementMinorOnMainAndPatchOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.1+3", configuration); + + fixture.ApplyTag("0.1.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-1+6", configuration); + } + else + { + // ❔ not expected + fixture.AssertFullSemver("0.2.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("0.1.1"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMinorOnMainAndMinorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.1+3", configuration); + + fixture.ApplyTag("0.2.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.2.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.2.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.3.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMinorOnMainAndMajorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Minor) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-1+1", configuration); + } + + [TestCase(true, IncrementStrategy.Inherit)] + [TestCase(false, IncrementStrategy.None)] + [TestCase(true, IncrementStrategy.None)] + [TestCase(false, IncrementStrategy.Patch)] + [TestCase(true, IncrementStrategy.Patch)] + [TestCase(false, IncrementStrategy.Minor)] + [TestCase(true, IncrementStrategy.Minor)] + [TestCase(false, IncrementStrategy.Major)] + [TestCase(true, IncrementStrategy.Major)] + public void EnsureReleaseAndFeatureBranchWithIncrementMajorOnMain( + bool useTrunkBased, IncrementStrategy incrementOnReleaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(incrementOnReleaseBranch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout("release/2.0.0"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo("release/2.0.0", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMajorOnMainAndInheritOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMajorOnMainAndNoneOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.None) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-2+6", configuration); + } + else + { + // ❔ expected: "1.0.0-2+6" + fixture.AssertFullSemver("2.0.0-1+6", configuration); + } + + if (!useTrunkBased) + { + fixture.Repository.Tags.Remove("1.0.0"); + fixture.ApplyTag("1.0.0"); + } + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + public void EnsureReleaseAndFeatureBranchWithIncrementMajorOnMainAndPatchOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Patch) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.1+3", configuration); + + fixture.ApplyTag("1.0.1-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-1+6", configuration); + } + else + { + // ❔ expected: "1.0.1-1+6" + fixture.AssertFullSemver("2.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("1.0.1"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.0.2")] + [TestCase(true, "release/1.0.2")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMajorOnMainAndMinorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Minor) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.1+3", configuration); + + fixture.ApplyTag("1.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-1+6", configuration); + } + else + { + // ❔ expected: "1.1.0-1+6" + fixture.AssertFullSemver("2.0.0-1+6", configuration); + } + + if (!useTrunkBased) fixture.ApplyTag("1.1.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(false, "release/0.1.0")] + [TestCase(true, "release/0.1.0")] + [TestCase(false, "release/0.1.1")] + [TestCase(true, "release/0.1.1")] + [TestCase(false, "release/0.2.0")] + [TestCase(true, "release/0.2.0")] + [TestCase(false, "release/1.0.0")] + [TestCase(true, "release/1.0.0")] + [TestCase(false, "release/1.0.1")] + [TestCase(true, "release/1.0.1")] + [TestCase(false, "release/1.0.2")] + [TestCase(true, "release/1.0.2")] + [TestCase(false, "release/1.1.0")] + [TestCase(true, "release/1.1.0")] + [TestCase(false, "release/1.1.1")] + [TestCase(true, "release/1.1.1")] + [TestCase(false, "release/2.0.0")] + [TestCase(true, "release/2.0.0")] + public void EnsureReleaseAndFeatureBranchWithIncrementMajorOnMainAndMajorOnReleaseBranch( + bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder + .WithIncrement(IncrementStrategy.Major) + .WithBranch("main", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment) + .WithIncrement(IncrementStrategy.Major) + ).WithBranch("release", _ => _ + .WithIncrement(IncrementStrategy.Major) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).WithBranch("feature", _ => _ + .WithIncrement(IncrementStrategy.Inherit) + .WithDeploymentMode(DeploymentMode.ManualDeployment) + ).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-1+1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-1+6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("3.0.0-1+1", configuration); + } +} diff --git a/src/GitVersion.Core.Tests/IntegrationTests/BranchWithoutCommitScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/BranchWithoutCommitScenarios.cs index e64fdcec3c..9735e16114 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/BranchWithoutCommitScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/BranchWithoutCommitScenarios.cs @@ -15,23 +15,23 @@ public void CanTakeVersionFromReleaseBranch() fixture.Repository.CreateBranch("release-4.0.123"); fixture.Checkout(commit.Sha); - fixture.AssertFullSemver("4.0.123-beta.1+0", null, fixture.Repository, commit.Sha, false, "release-4.0.123"); + fixture.AssertFullSemver("4.0.123-beta.1+1", null, fixture.Repository, commit.Sha, false, "release-4.0.123"); } - [Test] - public void BranchVersionHavePrecedenceOverTagVersionIfVersionGreaterThanTag() + [TestCase("0.1.0-alpha.1", "1.0.0-beta.1+2")] + [TestCase("1.0.0-alpha.1", "1.0.0-beta.1+2")] + [TestCase("1.0.1-alpha.1", "1.0.1-beta.1+2")] + public void BranchVersionHavePrecedenceOverTagVersionIfVersionGreaterThanTag(string tag, string expected) { using var fixture = new EmptyRepositoryFixture(); - fixture.Repository.MakeACommit(); + fixture.MakeACommit(); - fixture.Repository.CreateBranch("develop"); - fixture.Checkout("develop"); - fixture.MakeATaggedCommit("0.1.0-alpha.1"); // simulate merge from feature branch + fixture.BranchTo("develop"); + fixture.MakeATaggedCommit(tag); // simulate merge from feature branch - fixture.Repository.CreateBranch("release/1.0.0"); - fixture.Checkout("release/1.0.0"); + fixture.BranchTo("release/1.0.0"); - fixture.AssertFullSemver("1.0.0-beta.1+0"); + fixture.AssertFullSemver(expected); } } diff --git a/src/GitVersion.Core.Tests/IntegrationTests/CompareTheDifferentWhenUsingTrunkBasedVersionStrategyWithGitFlow.cs b/src/GitVersion.Core.Tests/IntegrationTests/CompareTheDifferentWhenUsingTrunkBasedVersionStrategyWithGitFlow.cs new file mode 100644 index 0000000000..373d689197 --- /dev/null +++ b/src/GitVersion.Core.Tests/IntegrationTests/CompareTheDifferentWhenUsingTrunkBasedVersionStrategyWithGitFlow.cs @@ -0,0 +1,1329 @@ +using GitVersion.Configuration; +using GitVersion.VersionCalculation; + +namespace GitVersion.Core.Tests.IntegrationTests; + +[TestFixture] +[Parallelizable(ParallelScope.All)] +public class CompareTheDifferentWhenUsingTrunkBasedVersionStrategyWithGitFlow +{ + private static GitFlowConfigurationBuilder configurationBuilder => GitFlowConfigurationBuilder.New; + + /// + /// GitFlow - Feature branch (Increment patch on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeature(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+1", configuration); + + fixture.ApplyTag("0.0.3-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-4", configuration); + } + + /// + /// GitFlow - Merge main to feature branch (Increment patch on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeature(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+3", configuration); + + fixture.ApplyTag("0.0.3-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-6", configuration); + } + + /// + /// GitFlow - Pull requests (increment patch on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequest(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-2", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void EnsureReleaseAndFeatureBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout("release/2.0.0"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo("release/2.0.0", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(true, "release/0.1.0")] + public void EnsureReleaseAndFeatureBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+3", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-1", configuration); + } + + /// + /// GitFlow - Release branch (Increment patch on main) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureReleaseBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); + + fixture.ApplyTag("2.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1", configuration); + } + + /// + /// GitFlow - Release branch (Increment patch on main and none on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + [TestCase(true, "release/0.1.0")] + public void EnsureReleaseBranch(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+4", configuration); + + fixture.ApplyTag("0.1.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureDevelopmentWithDevelopBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("develop"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.1", configuration); + + fixture.ApplyTag("0.1.0-alpha.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.2", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+3", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+2", configuration); + + fixture.Checkout("develop"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.6", configuration); + + fixture.Checkout("feature/foo"); + fixture.Repository.Branches.Remove("pull/2/merge"); + fixture.MergeTo("develop", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.6", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/3/merge"); + fixture.MergeNoFF("develop"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest3.7", configuration); + + fixture.Checkout("develop"); + fixture.Repository.Branches.Remove("pull/3/merge"); + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-7", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureDevelopmentWithDevelopBranchFast(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("develop"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.0", configuration); + + fixture.BranchTo("feature/foo"); + + if (useTrunkBased) + { + // ❔ expected: "0.1.0-foo.1+0" + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+0", configuration); + } + + fixture.MakeACommit("B"); + + if (useTrunkBased) + { + // ❔ expected: "0.1.0-foo.1+1" + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+1", configuration); + } + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+2", configuration); + + fixture.Checkout("develop"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.4", configuration); + + fixture.Checkout("feature/foo"); + fixture.Repository.Branches.Remove("pull/2/merge"); + fixture.MergeTo("develop", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.4", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/3/merge"); + fixture.MergeNoFF("develop"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest3.5", configuration); + + fixture.Checkout("develop"); + fixture.Repository.Branches.Remove("pull/3/merge"); + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-5", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void EnsureDevelopmentWithMainBranchFast(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.ApplyTag("0.0.2-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+1", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+2", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest2.4", configuration); + + fixture.Checkout("feature/foo"); + fixture.Repository.Branches.Remove("pull/2/merge"); + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-4", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void EnsureBugFixWithMainBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("hotfix/bar"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+1", configuration); + + fixture.ApplyTag("0.0.2-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.2+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.2+1", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.2+2", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("hotfix/bar"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest2.4", configuration); + + fixture.Checkout("hotfix/bar"); + fixture.Repository.Branches.Remove("pull/2/merge"); + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-4", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void EnsureBugFixWithDevelopBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("develop"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.1", configuration); + + fixture.BranchTo("hotfix/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+2", configuration); + + fixture.ApplyTag("0.0.2-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.2+2", configuration); + + fixture.Checkout("develop"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("hotfix/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.5", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/3/merge"); + fixture.MergeNoFF("hotfix/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest3.5", configuration); + + fixture.Checkout("hotfix/foo"); + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-5", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void EnsureBugFixWithDevelopBranchFast(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("develop"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.0", configuration); + + fixture.BranchTo("hotfix/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+1", configuration); + + fixture.ApplyTag("0.0.2-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.2+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.2+1", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.2+2", configuration); + + fixture.Checkout("develop"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("hotfix/foo"); + + if (useTrunkBased) + { + // ❔ expected: "0.1.0-PullRequest2.4" + fixture.AssertFullSemver("0.0.2-PullRequest2.4", configuration); + } + else + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.4", configuration); + } + + fixture.Checkout("main"); + fixture.BranchTo("pull/3/merge"); + fixture.MergeNoFF("hotfix/foo"); + + if (useTrunkBased) + { + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest3.4", configuration); + } + else + { + // ❔ expected: "0.0.2-PullRequest3.4" + fixture.AssertFullSemver("0.1.0-PullRequest3.4", configuration); + } + + fixture.Checkout("hotfix/foo"); + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-4", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1", configuration); + } + + [Test] + public void JustATest() + { + var configuration = configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased).Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + fixture.ApplyTag("0.1.0"); + + for (int i = 0; i < 10; i++) fixture.MakeACommit(); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.10-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureDevelopmentWithReleaseNextBranch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("develop"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.1", configuration); + + fixture.BranchTo("release/next"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.Checkout("develop"); + fixture.MakeACommit(); + fixture.Checkout("release/next"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+2", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+3", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+3", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+4", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+2", configuration); + + fixture.Checkout("release/next"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.7", configuration); + + fixture.Checkout("feature/foo"); + fixture.Repository.Branches.Remove("pull/2/merge"); + fixture.MergeTo("release/next", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+7", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/3/merge"); + fixture.MergeNoFF("release/next"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest3.8", configuration); + + fixture.Checkout("release/next"); + fixture.Repository.Branches.Remove("pull/3/merge"); + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-8", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureDevelopmentWithReleaseNextBranchFast(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("develop"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.0", configuration); + + fixture.BranchTo("release/next"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.Checkout("develop"); + fixture.MakeACommit(); + fixture.Checkout("release/next"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+2", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.1+3", configuration); + + fixture.ApplyTag("0.1.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-foo.2+2", configuration); + + fixture.Checkout("release/next"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest2.6", configuration); + + fixture.Checkout("feature/foo"); + fixture.Repository.Branches.Remove("pull/2/merge"); + fixture.MergeTo("release/next", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-beta.1+6", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/3/merge"); + fixture.MergeNoFF("release/next"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-PullRequest3.7", configuration); + + fixture.Checkout("release/next"); + fixture.Repository.Branches.Remove("pull/3/merge"); + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-7", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.1.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.1-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void EnsureFeatureDevelopmentWithRelease100Branch(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("develop"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.1.0-alpha.1", configuration); + + fixture.BranchTo("release/1.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.Checkout("develop"); + fixture.MakeACommit(); + fixture.Checkout("release/1.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+3", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.1+4", configuration); + + fixture.ApplyTag("1.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-foo.2+2", configuration); + + fixture.Checkout("release/1.0.0"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest2.7", configuration); + + fixture.Checkout("feature/foo"); + fixture.Repository.Branches.Remove("pull/2/merge"); + fixture.MergeTo("release/1.0.0", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+7", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/3/merge"); + fixture.MergeNoFF("release/1.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-PullRequest3.8", configuration); + + fixture.Checkout("release/1.0.0"); + fixture.Repository.Branches.Remove("pull/3/merge"); + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-8", configuration); + + if (!useTrunkBased) fixture.ApplyTag("1.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.1-1", configuration); + } +} diff --git a/src/GitVersion.Core.Tests/IntegrationTests/CompareTheDifferentWhenUsingTrunkBasedVersionStrategyWithGitHubFlow.cs b/src/GitVersion.Core.Tests/IntegrationTests/CompareTheDifferentWhenUsingTrunkBasedVersionStrategyWithGitHubFlow.cs new file mode 100644 index 0000000000..58136956fa --- /dev/null +++ b/src/GitVersion.Core.Tests/IntegrationTests/CompareTheDifferentWhenUsingTrunkBasedVersionStrategyWithGitHubFlow.cs @@ -0,0 +1,494 @@ +using GitVersion.Configuration; +using GitVersion.VersionCalculation; + +namespace GitVersion.Core.Tests.IntegrationTests; + +[TestFixture] +[Parallelizable(ParallelScope.All)] +public class CompareTheDifferentWhenUsingTrunkBasedVersionStrategyWithGitHubFlow +{ + private static GitHubFlowConfigurationBuilder configurationBuilder => GitHubFlowConfigurationBuilder.New; + + /// + /// GitHubFlow - Feature branch (Increment patch on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureFeature1(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+0", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+1", configuration); + + fixture.ApplyTag("0.0.3-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+0", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+1", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-4", configuration); + } + + /// + /// GitHubFlow - Merge main to feature branch (Increment patch on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureMergeMainToFeature2(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.1+3", configuration); + + fixture.ApplyTag("0.0.3-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+1", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-foo.2+2", configuration); + + fixture.MergeTo("main"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-6", configuration); + } + + /// + /// GitHubFlow - Pull requests (increment patch on main and inherit on feature) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsurePullRequest(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.Checkout("main"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest2.2", configuration); + + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-2", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void EnsureReleaseAndFeatureBranch1(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.1+3", configuration); + + fixture.ApplyTag("2.0.0-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + + fixture.Checkout("release/2.0.0"); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo("release/2.0.0", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1", configuration); + } + + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(true, "release/0.0.2")] + public void EnsureReleaseAndFeatureBranch2(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+1", configuration); + + fixture.BranchTo("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+1", configuration); + + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.1+3", configuration); + + fixture.ApplyTag("0.0.2-foo.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+0", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-foo.2+1", configuration); + + fixture.Checkout(releaseBranch); + fixture.BranchTo("pull/2/merge"); + fixture.MergeNoFF("feature/foo"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-PullRequest2.5", configuration); + + fixture.Checkout("feature/foo"); + fixture.MergeTo(releaseBranch, removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+5", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment patch on main) + /// + [TestCase(false)] + [TestCase(true)] + public void EnsureReleaseBranch1(bool useTrunkBased) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo("release/2.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); + + fixture.ApplyTag("2.0.0-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.0-6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("2.0.0"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("2.0.1-1", configuration); + } + + /// + /// GitHubFlow - Release branch (Increment patch on main and none on release) + /// + [TestCase(false, "release/next")] + [TestCase(true, "release/next")] + [TestCase(false, "release/0.0.0")] + [TestCase(true, "release/0.0.0")] + [TestCase(false, "release/0.0.1")] + [TestCase(true, "release/0.0.1")] + [TestCase(false, "release/0.0.2")] + [TestCase(true, "release/0.0.2")] + public void EnsureReleaseBranch2(bool useTrunkBased, string releaseBranch) + { + var builder = useTrunkBased + ? configurationBuilder.WithVersionStrategy(VersionStrategies.TrunkBased) + : configurationBuilder; + var configuration = builder.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit("A"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.1"); + fixture.BranchTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+0", configuration); + + fixture.MakeACommit("B"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-beta.1+1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("C"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.2-1", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.2"); + fixture.MergeTo(releaseBranch); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+2", configuration); + + fixture.MakeACommit("D"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+3", configuration); + + fixture.MakeACommit("E"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.1+4", configuration); + + fixture.ApplyTag("0.0.3-beta.1"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.2+0", configuration); + + fixture.MakeACommit("F"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-beta.2+1", configuration); + + fixture.MergeTo("main", removeBranchAfterMerging: true); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.3-6", configuration); + + if (!useTrunkBased) fixture.ApplyTag("0.0.3"); + fixture.MakeACommit("G"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.4-1", configuration); + } +} diff --git a/src/GitVersion.Core.Tests/IntegrationTests/ContinuousDeliveryTestScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/ContinuousDeliveryTestScenarios.cs index a2cc3db30f..60c0cc0ab2 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/ContinuousDeliveryTestScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/ContinuousDeliveryTestScenarios.cs @@ -238,32 +238,32 @@ public void ShouldCalculateTheCorrectVersionWhenMergingFromReleaseToFeatureBranc fixture.BranchTo("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1", configuration); fixture.BranchTo("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-just-a-test.0", configuration); + fixture.AssertFullSemver("1.0.0-just-a-test.1", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-just-a-test.1", configuration); + fixture.AssertFullSemver("1.0.0-just-a-test.2", configuration); fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1", configuration); fixture.MergeNoFF("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.2", configuration); + fixture.AssertFullSemver("1.0.0-beta.3", configuration); fixture.Repository.Branches.Remove("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.2", configuration); + fixture.AssertFullSemver("1.0.0-beta.3", configuration); fixture.Repository.DumpGraph(); } @@ -287,10 +287,10 @@ public void ShouldFallbackToTheVersionOnDevelopLikeTheReleaseWasNeverCreatedWhen .WithTrackMergeTarget(false) ) .WithBranch("develop", builder => builder - .WithDeploymentMode(DeploymentMode.ContinuousDelivery).WithTrackMergeTarget(false) + .WithTrackMergeTarget(false) ) .WithBranch("release", builder => builder - .WithDeploymentMode(DeploymentMode.ContinuousDelivery).WithTrackMergeTarget(false) + .WithTrackMergeTarget(false) ) .Build(); @@ -314,17 +314,17 @@ public void ShouldFallbackToTheVersionOnDevelopLikeTheReleaseWasNeverCreatedWhen fixture.BranchTo("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.2", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); fixture.Checkout("develop"); @@ -344,8 +344,8 @@ public void ShouldFallbackToTheVersionOnDevelopLikeTheReleaseWasNeverCreatedWhen // cancel the release 1.0.0 fixture.Repository.Branches.Remove("release/1.0.0"); - // ❔ expected: "0.1.0-alpha.6" - fixture.AssertFullSemver("1.1.0-alpha.4", configuration); + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-alpha.6", configuration); fixture.Repository.DumpGraph(); } @@ -373,11 +373,9 @@ public void ShouldConsiderTheMergeCommitFromMainToDevelopWhenReleaseHasBeenMerge .WithTrackMergeTarget(false) ) .WithBranch("develop", builder => builder - .WithDeploymentMode(DeploymentMode.ContinuousDelivery) .WithTrackMergeTarget(false) ) .WithBranch("release", builder => builder - .WithDeploymentMode(DeploymentMode.ContinuousDelivery) .WithTrackMergeTarget(false) ) .Build(); @@ -402,17 +400,17 @@ public void ShouldConsiderTheMergeCommitFromMainToDevelopWhenReleaseHasBeenMerge fixture.BranchTo("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.2", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); fixture.Checkout("develop"); @@ -427,8 +425,8 @@ public void ShouldConsiderTheMergeCommitFromMainToDevelopWhenReleaseHasBeenMerge fixture.Checkout("main"); fixture.MergeNoFF("release/1.0.0"); - // ❔ expected: "0.0.1-ci.5" - fixture.AssertFullSemver("1.0.0-ci.0", configuration); + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-ci.5", configuration); fixture.ApplyTag("1.0.0"); @@ -442,13 +440,13 @@ public void ShouldConsiderTheMergeCommitFromMainToDevelopWhenReleaseHasBeenMerge fixture.MergeNoFF("main"); - // ❔ expected: "1.1.0-alpha.2" - fixture.AssertFullSemver("1.1.0-alpha.6", configuration); + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-alpha.2", configuration); fixture.Repository.Branches.Remove("release/1.0.0"); - // ❔ expected: "1.1.0-alpha.2 - fixture.AssertFullSemver("1.1.0-alpha.6", configuration); + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-alpha.2", configuration); fixture.Repository.DumpGraph(); } diff --git a/src/GitVersion.Core.Tests/IntegrationTests/CreatingAFeatureBranchFromAReleaseBranchScenario.cs b/src/GitVersion.Core.Tests/IntegrationTests/CreatingAFeatureBranchFromAReleaseBranchScenario.cs index 50d2c3e7f1..e803fa05f1 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/CreatingAFeatureBranchFromAReleaseBranchScenario.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/CreatingAFeatureBranchFromAReleaseBranchScenario.cs @@ -32,12 +32,12 @@ public void ShouldTreatTheFeatureBranchLikeTheFirstReleaseBranchWhenItHasBeenBra fixture.BranchTo("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); fixture.BranchTo("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-just-a-test.1+0", configuration); + fixture.AssertFullSemver("1.0.0-just-a-test.1+1", configuration); fixture.Checkout("main"); fixture.MakeACommit(); @@ -49,37 +49,37 @@ public void ShouldTreatTheFeatureBranchLikeTheFirstReleaseBranchWhenItHasBeenBra fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); fixture.Checkout("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-just-a-test.1+0", configuration); + fixture.AssertFullSemver("1.0.0-just-a-test.1+1", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-just-a-test.1+1", configuration); + fixture.AssertFullSemver("1.0.0-just-a-test.1+2", configuration); fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); fixture.MergeNoFF("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); fixture.Repository.Branches.Remove("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); fixture.Repository.DumpGraph(); } @@ -108,7 +108,7 @@ public void ShouldTreatTheFeatureBranchNotLikeTheReleaseBranchWhenItHasBeenBranc fixture.BranchTo("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); // 1.1.0 is correct because the base branch points to develop and release // maybe we can fix it somehow using the configuration with PreReleaseWeight? @@ -131,45 +131,43 @@ public void ShouldTreatTheFeatureBranchNotLikeTheReleaseBranchWhenItHasBeenBranc fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); fixture.Checkout("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-just-a-test.1+0", configuration); + fixture.AssertFullSemver("1.0.0-just-a-test.1+1", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-just-a-test.1+1", configuration); + fixture.AssertFullSemver("1.0.0-just-a-test.1+2", configuration); fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); fixture.MergeNoFF("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); fixture.Repository.Branches.Remove("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); fixture.Repository.DumpGraph(); } - [TestCase("main")] - [TestCase("develop")] - public void ShouldTreatTheHotfixBranchLikeTheFirstReleaseBranchWhenItHasBeenBranchedFromMainOrDevelopAndFirstReleaseBranchButNotFromTheSecondReleaseBranch( - string branchName) + [Test] + public void ShouldTreatTheHotfixBranchLikeTheFirstReleaseBranchWhenItHasBeenBranchedFromMainAndFirstReleaseBranchButNotFromTheSecondReleaseBranch() { // *2b9c8bf 42 minutes ago(HEAD -> release/ 1.0.0) // *66cfc66 44 minutes ago @@ -182,64 +180,202 @@ public void ShouldTreatTheHotfixBranchLikeTheFirstReleaseBranchWhenItHasBeenBran var configuration = GitFlowConfigurationBuilder.New.Build(); - using var fixture = new EmptyRepositoryFixture(branchName); + using var fixture = new EmptyRepositoryFixture("main"); - fixture.Repository.MakeACommit(); + fixture.MakeACommit(); fixture.BranchTo("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); fixture.BranchTo("hotfix/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("0.0.1-beta.1+1", configuration); - fixture.Checkout(branchName); + fixture.Checkout("main"); fixture.MakeACommit(); fixture.BranchTo("release/1.1.0"); fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); fixture.Checkout("hotfix/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("0.0.1-beta.1+1", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("0.0.1-beta.1+2", configuration); fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); fixture.MergeNoFF("hotfix/just-a-test"); + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + + fixture.Repository.Branches.Remove("hotfix/just-a-test"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + + fixture.MakeACommit(); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + + fixture.Repository.DumpGraph(); + } + + [Test] + public void ShouldTreatTheHotfixBranchLikeTheFirstReleaseBranchWhenItHasBeenBranchedFromDevelopAndFirstReleaseBranchButNotFromTheSecondReleaseBranch() + { + // *2b9c8bf 42 minutes ago(HEAD -> release/ 1.0.0) + // *66cfc66 44 minutes ago + // |\ + // | *e9978b9 45 minutes ago + // |/ + // | *c2b96e5 47 minutes ago(release/ 1.1.0, main|develop) + // |/ + // *e00f53d 49 minutes ago + + var configuration = GitFlowConfigurationBuilder.New.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + + fixture.MakeACommit(); + fixture.BranchTo("develop"); + fixture.MakeACommit(); + fixture.BranchTo("release/1.0.0"); + // ✅ succeeds as expected fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + fixture.BranchTo("hotfix/just-a-test"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+2", configuration); + + fixture.Checkout("develop"); + fixture.MakeACommit(); + fixture.BranchTo("release/1.1.0"); + fixture.Checkout("release/1.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + + fixture.Checkout("hotfix/just-a-test"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+2", configuration); + + fixture.MakeACommit(); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+3", configuration); + + fixture.Checkout("release/1.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + + fixture.MergeNoFF("hotfix/just-a-test"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + fixture.Repository.Branches.Remove("hotfix/just-a-test"); + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + + fixture.MakeACommit(); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); + + fixture.Repository.DumpGraph(); + } + + [Test] + public void ShouldTreatTheFeatureBranchLikeTheFirstReleaseBranchWhenItHasBeenBranchedFromFirstButNotFromTheSecondReleaseBranchFromMain() + { + // * 3807c66 49 minutes ago (HEAD -> release/1.0.0) + // * da32145 51 minutes ago + // |\ + // | * 6a89f35 52 minutes ago + // |/ + // * 19f2980 56 minutes ago + // | * 2282a59 54 minutes ago (release/1.1.0, main) + // |/ + // * d7b7c5e 58 minutes ago + + var configuration = GitFlowConfigurationBuilder.New.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + fixture.Repository.MakeACommit(); + + fixture.BranchTo("release/1.0.0"); + fixture.Repository.MakeACommit(); + // ✅ succeeds as expected fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + fixture.BranchTo("feature/just-a-test"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-just-a-test.1+2", configuration); + + fixture.Checkout("main"); fixture.MakeACommit(); + fixture.BranchTo("release/1.1.0"); + fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + + fixture.Checkout("feature/just-a-test"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-just-a-test.1+2", configuration); + + fixture.MakeACommit(); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-just-a-test.1+3", configuration); + + fixture.Checkout("release/1.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + + fixture.MergeNoFF("feature/just-a-test"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + + fixture.Repository.Branches.Remove("feature/just-a-test"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + + fixture.MakeACommit(); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); fixture.Repository.DumpGraph(); } - [TestCase("main")] - [TestCase("develop")] - public void ShouldTreatTheFeatureBranchLikeTheFirstReleaseBranchWhenItHasBeenBranchedFromFirstButNotFromTheSecondReleaseBranch( - string branchName) + [Test] + public void ShouldTreatTheFeatureBranchLikeTheFirstReleaseBranchWhenItHasBeenBranchedFromFirstButNotFromTheSecondReleaseBranchFromDevelop() { // *1525ad0 38 minutes ago(HEAD -> release/ 1.0.0) // *476fc51 40 minutes ago @@ -253,65 +389,66 @@ public void ShouldTreatTheFeatureBranchLikeTheFirstReleaseBranchWhenItHasBeenBra var configuration = GitFlowConfigurationBuilder.New.Build(); - using var fixture = new EmptyRepositoryFixture(branchName); + using var fixture = new EmptyRepositoryFixture("main"); + fixture.Repository.MakeACommit(); + + fixture.BranchTo("develop"); fixture.Repository.MakeACommit(); fixture.BranchTo("release/1.0.0"); fixture.Repository.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); fixture.BranchTo("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-just-a-test.1+1", configuration); + fixture.AssertFullSemver("1.0.0-just-a-test.1+3", configuration); - fixture.Checkout(branchName); + fixture.Checkout("main"); fixture.MakeACommit(); fixture.BranchTo("release/1.1.0"); fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); fixture.Checkout("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-just-a-test.1+1", configuration); + fixture.AssertFullSemver("1.0.0-just-a-test.1+3", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-just-a-test.1+2", configuration); + fixture.AssertFullSemver("1.0.0-just-a-test.1+4", configuration); fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); fixture.MergeNoFF("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); fixture.Repository.Branches.Remove("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+6", configuration); fixture.Repository.DumpGraph(); } - [TestCase("main")] - [TestCase("develop")] - public void ShouldTreatTheHotfixBranchLikeTheFirstReleaseBranchWhenItHasBeenBranchedFromFirstButNotFromTheSecondReleaseBranch( - string branchName) + [Test] + public void ShouldTreatTheHotfixBranchLikeTheFirstReleaseBranchWhenItHasBeenBranchedFromFirstButNotFromTheSecondReleaseBranchOnMain() { // *1525ad0 38 minutes ago(HEAD -> release/ 1.0.0) // *476fc51 40 minutes ago @@ -325,57 +462,130 @@ public void ShouldTreatTheHotfixBranchLikeTheFirstReleaseBranchWhenItHasBeenBran var configuration = GitFlowConfigurationBuilder.New.Build(); - using var fixture = new EmptyRepositoryFixture(branchName); + using var fixture = new EmptyRepositoryFixture("main"); fixture.Repository.MakeACommit(); fixture.BranchTo("release/1.0.0"); fixture.Repository.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); fixture.BranchTo("hotfix/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("0.0.1-beta.1+2", configuration); - fixture.Checkout(branchName); + fixture.Checkout("main"); fixture.MakeACommit(); fixture.BranchTo("release/1.1.0"); fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); fixture.Checkout("hotfix/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("0.0.1-beta.1+2", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + fixture.AssertFullSemver("0.0.1-beta.1+3", configuration); fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); fixture.MergeNoFF("hotfix/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); fixture.Repository.Branches.Remove("hotfix/just-a-test"); + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + + fixture.MakeACommit(); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); + + fixture.Repository.DumpGraph(); + } + + [Test] + public void ShouldTreatTheHotfixBranchLikeTheFirstReleaseBranchWhenItHasBeenBranchedFromFirstButNotFromTheSecondReleaseBranchOnDevelop() + { + // *1525ad0 38 minutes ago(HEAD -> release/ 1.0.0) + // *476fc51 40 minutes ago + // |\ + // | *c8c5030 41 minutes ago + // |/ + // *d91061d 45 minutes ago + // | *1ac98f5 43 minutes ago(release/ 1.1.0, develop) + // |/ + // *22596b8 47 minutes ago + + var configuration = GitFlowConfigurationBuilder.New.Build(); + + using var fixture = new EmptyRepositoryFixture("main"); + fixture.Repository.MakeACommit(); + + fixture.BranchTo("develop"); + fixture.Repository.MakeACommit(); + + fixture.BranchTo("release/1.0.0"); + fixture.Repository.MakeACommit(); + // ✅ succeeds as expected fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + fixture.BranchTo("hotfix/just-a-test"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+3", configuration); + + fixture.Checkout("develop"); fixture.MakeACommit(); + fixture.BranchTo("release/1.1.0"); + fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + + fixture.Checkout("hotfix/just-a-test"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+3", configuration); + + fixture.MakeACommit(); + + // ✅ succeeds as expected + fixture.AssertFullSemver("0.0.1-beta.1+4", configuration); + + fixture.Checkout("release/1.0.0"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + + fixture.MergeNoFF("hotfix/just-a-test"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); + + fixture.Repository.Branches.Remove("hotfix/just-a-test"); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); + + fixture.MakeACommit(); + + // ✅ succeeds as expected + fixture.AssertFullSemver("1.0.0-beta.1+6", configuration); fixture.Repository.DumpGraph(); } @@ -403,42 +613,42 @@ public void ShouldTreatTheFeatureBranchLikeTheReleaseBranchWhenItHasBeenBranched fixture.BranchTo("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); fixture.BranchTo("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-just-a-test.1+1", configuration); + fixture.AssertFullSemver("1.0.0-just-a-test.1+2", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-just-a-test.1+2", configuration); + fixture.AssertFullSemver("1.0.0-just-a-test.1+3", configuration); fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); fixture.MergeNoFF("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); fixture.Repository.Branches.Remove("feature/just-a-test"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+5", configuration); fixture.Repository.DumpGraph(); } @@ -478,17 +688,17 @@ public void ShouldTreatTheMergeFromReleaseToDevelopLikeTheReleaseBranchHasNeverB fixture.BranchTo("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); fixture.Checkout("develop"); @@ -508,12 +718,12 @@ public void ShouldTreatTheMergeFromReleaseToDevelopLikeTheReleaseBranchHasNeverB fixture.Repository.Branches.Remove("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.1.0-alpha.4", configuration); + fixture.AssertFullSemver("1.1.0-alpha.6", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.1.0-alpha.5", configuration); + fixture.AssertFullSemver("1.1.0-alpha.7", configuration); fixture.Repository.DumpGraph(); } @@ -556,17 +766,17 @@ public void ShouldOnlyTrackTheCommitsOnDevelopBranchForNextReleaseWhenReleaseHas fixture.BranchTo("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); fixture.Checkout("develop"); @@ -582,7 +792,7 @@ public void ShouldOnlyTrackTheCommitsOnDevelopBranchForNextReleaseWhenReleaseHas fixture.MergeNoFF("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-0", configuration); + fixture.AssertFullSemver("1.0.0-5", configuration); fixture.ApplyTag("1.0.0"); @@ -597,12 +807,12 @@ public void ShouldOnlyTrackTheCommitsOnDevelopBranchForNextReleaseWhenReleaseHas fixture.MergeNoFF("main"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.1.0-alpha.6", configuration); + fixture.AssertFullSemver("1.1.0-alpha.2", configuration); fixture.Repository.Branches.Remove("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.1.0-alpha.6", configuration); + fixture.AssertFullSemver("1.1.0-alpha.2", configuration); fixture.Repository.DumpGraph(); } @@ -645,17 +855,17 @@ public void ShouldNotConsiderTheMergeCommitFromReleaseToMainWhenCommitHasNotBeen fixture.BranchTo("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+3", configuration); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+2", configuration); + fixture.AssertFullSemver("1.0.0-beta.1+4", configuration); fixture.Checkout("develop"); @@ -671,12 +881,12 @@ public void ShouldNotConsiderTheMergeCommitFromReleaseToMainWhenCommitHasNotBeen fixture.MergeNoFF("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-0", configuration); + fixture.AssertFullSemver("1.0.0-5", configuration); fixture.Repository.Branches.Remove("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-0", configuration); + fixture.AssertFullSemver("1.0.0-5", configuration); fixture.ApplyTag("1.0.0"); @@ -691,7 +901,7 @@ public void ShouldNotConsiderTheMergeCommitFromReleaseToMainWhenCommitHasNotBeen fixture.MergeNoFF("main"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.1.0-alpha.6", configuration); + fixture.AssertFullSemver("1.1.0-alpha.2", configuration); fixture.Repository.DumpGraph(); } diff --git a/src/GitVersion.Core.Tests/IntegrationTests/DevelopScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/DevelopScenarios.cs index 1cf52387d6..2fab203ef4 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/DevelopScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/DevelopScenarios.cs @@ -161,7 +161,7 @@ public void InheritVersionFromParentReleaseBranchWithVersion2InsteadOfVersion3() fixture.BranchTo("release/2.0.0"); fixture.MakeACommit(); fixture.MakeACommit(); - fixture.AssertFullSemver("2.0.0-beta.1+2"); + fixture.AssertFullSemver("2.0.0-beta.1+3"); fixture.Checkout("develop"); fixture.AssertFullSemver("3.1.0-alpha.1"); fixture.MakeACommit(); @@ -171,7 +171,7 @@ public void InheritVersionFromParentReleaseBranchWithVersion2InsteadOfVersion3() fixture.Checkout("release/2.0.0"); fixture.BranchTo("feature/MyFeature"); fixture.MakeACommit(); - fixture.AssertFullSemver("2.0.0-MyFeature.1+3"); + fixture.AssertFullSemver("2.0.0-MyFeature.1+4"); } [Test] @@ -225,7 +225,7 @@ public void CommitsSinceVersionSourceShouldNotGoDownUponGitFlowReleaseFinish() fixture.MakeACommit("commit in develop - 1"); fixture.AssertFullSemver("1.2.0-alpha.1"); fixture.BranchTo("release/1.2.0"); - fixture.AssertFullSemver("1.2.0-beta.1+0"); + fixture.AssertFullSemver("1.2.0-beta.1+1"); fixture.Checkout("develop"); fixture.MakeACommit("commit in develop - 2"); fixture.MakeACommit("commit in develop - 3"); @@ -236,18 +236,18 @@ public void CommitsSinceVersionSourceShouldNotGoDownUponGitFlowReleaseFinish() fixture.MakeACommit("commit in release/1.2.0 - 1"); fixture.MakeACommit("commit in release/1.2.0 - 2"); fixture.MakeACommit("commit in release/1.2.0 - 3"); - fixture.AssertFullSemver("1.2.0-beta.1+3"); + fixture.AssertFullSemver("1.2.0-beta.1+4"); fixture.Checkout(MainBranch); fixture.MergeNoFF("release/1.2.0"); fixture.ApplyTag("1.2.0"); fixture.Checkout("develop"); fixture.MergeNoFF("release/1.2.0"); fixture.MakeACommit("commit in develop - 6"); - fixture.AssertFullSemver("1.3.0-alpha.9"); + fixture.AssertFullSemver("1.3.0-alpha.6"); fixture.SequenceDiagram.Destroy("release/1.2.0"); fixture.Repository.Branches.Remove("release/1.2.0"); - const string expectedFullSemVer = "1.3.0-alpha.9"; + const string expectedFullSemVer = "1.3.0-alpha.6"; fixture.AssertFullSemver(expectedFullSemVer, configuration); } @@ -270,17 +270,17 @@ public void CommitsSinceVersionSourceShouldNotGoDownUponMergingFeatureOnlyToDeve fixture.MakeACommit("commit in release - 1"); fixture.MakeACommit("commit in release - 2"); fixture.MakeACommit("commit in release - 3"); - fixture.AssertFullSemver("1.2.0-beta.1+3"); + fixture.AssertFullSemver("1.2.0-beta.1+4"); fixture.ApplyTag("1.2.0"); fixture.Checkout("develop"); fixture.MakeACommit("commit in develop - 2"); fixture.AssertFullSemver("1.3.0-alpha.1"); fixture.MergeNoFF("release/1.2.0"); - fixture.AssertFullSemver("1.3.0-alpha.5"); + fixture.AssertFullSemver("1.3.0-alpha.2"); fixture.SequenceDiagram.Destroy("release/1.2.0"); fixture.Repository.Branches.Remove("release/1.2.0"); - const string expectedFullSemVer = "1.3.0-alpha.5"; + const string expectedFullSemVer = "1.3.0-alpha.2"; fixture.AssertFullSemver(expectedFullSemVer, configuration); } @@ -333,16 +333,16 @@ public void WhenPreventIncrementOfMergedBranchVersionIsSetToFalseForDevelopCommi fixture.MergeNoFF(ReleaseBranch); // Version numbers will still be correct when the release branch is around. - fixture.AssertFullSemver("1.2.0-alpha.6"); - fixture.AssertFullSemver("1.2.0-alpha.6", configuration); + fixture.AssertFullSemver("1.2.0-alpha.3"); + fixture.AssertFullSemver("1.2.0-alpha.3", configuration); var versionSourceBeforeReleaseBranchIsRemoved = fixture.GetVersion(configuration).Sha; fixture.Repository.Branches.Remove(ReleaseBranch); var versionSourceAfterReleaseBranchIsRemoved = fixture.GetVersion(configuration).Sha; Assert.That(versionSourceAfterReleaseBranchIsRemoved, Is.EqualTo(versionSourceBeforeReleaseBranchIsRemoved)); - fixture.AssertFullSemver("1.2.0-alpha.6"); - fixture.AssertFullSemver("1.2.0-alpha.6", configuration); + fixture.AssertFullSemver("1.2.0-alpha.3"); + fixture.AssertFullSemver("1.2.0-alpha.3", configuration); } [Test] @@ -374,15 +374,15 @@ public void WhenPreventIncrementOfMergedBranchVersionIsSetToTrueForDevelopCommit fixture.MergeNoFF(ReleaseBranch); // Version numbers will still be correct when the release branch is around. - fixture.AssertFullSemver("1.2.0-alpha.6"); - fixture.AssertFullSemver("1.2.0-alpha.6", configuration); + fixture.AssertFullSemver("1.2.0-alpha.3"); + fixture.AssertFullSemver("1.2.0-alpha.3", configuration); var versionSourceBeforeReleaseBranchIsRemoved = fixture.GetVersion(configuration).Sha; fixture.Repository.Branches.Remove(ReleaseBranch); var versionSourceAfterReleaseBranchIsRemoved = fixture.GetVersion(configuration).Sha; Assert.That(versionSourceAfterReleaseBranchIsRemoved, Is.EqualTo(versionSourceBeforeReleaseBranchIsRemoved)); - fixture.AssertFullSemver("1.2.0-alpha.6"); + fixture.AssertFullSemver("1.2.0-alpha.3"); fixture.AssertFullSemver("1.2.0-alpha.3", configuration); } @@ -412,7 +412,7 @@ public void WhenPreventIncrementOfMergedBranchVersionIsSetToFalseForDevelopCommi const string ReleaseBranch = "release/1.1.0"; Commands.Checkout(fixture.Repository, fixture.Repository.CreateBranch(ReleaseBranch)); fixture.Repository.MakeCommits(3); - fixture.AssertFullSemver("1.1.0-beta.1+3", configuration); + fixture.AssertFullSemver("1.1.0-beta.1+7", configuration); // Simulate a GitFlow release finish. fixture.Checkout(MainBranch); @@ -424,7 +424,7 @@ public void WhenPreventIncrementOfMergedBranchVersionIsSetToFalseForDevelopCommi fixture.Repository.MakeCommits(2); fixture.MergeNoFF(ReleaseBranch); fixture.Repository.Branches.Remove(ReleaseBranch); - fixture.AssertFullSemver("1.2.0-alpha.6", configuration); + fixture.AssertFullSemver("1.2.0-alpha.3", configuration); // Create hotfix for defects found in release/1.1.0 const string HotfixBranch = "hotfix/1.1.1"; @@ -441,12 +441,12 @@ public void WhenPreventIncrementOfMergedBranchVersionIsSetToFalseForDevelopCommi fixture.Checkout("develop"); // Simulate some work done on develop while the hotfix branch was open. fixture.Repository.MakeCommits(3); - fixture.AssertFullSemver("1.2.0-alpha.9", configuration); + fixture.AssertFullSemver("1.2.0-alpha.6", configuration); fixture.Repository.MergeNoFF(HotfixBranch); - fixture.AssertFullSemver("1.2.0-alpha.19", configuration); + fixture.AssertFullSemver("1.2.0-alpha.7", configuration); fixture.Repository.Branches.Remove(HotfixBranch); - fixture.AssertFullSemver("1.2.0-alpha.19", configuration); + fixture.AssertFullSemver("1.2.0-alpha.7", configuration); } [Test] @@ -497,7 +497,7 @@ public void PreventDecrementationOfVersionsOnTheMainBranch() fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configurationBuilder.Build()); + fixture.AssertFullSemver("1.0.0-beta.1+2", configurationBuilder.Build()); // now we makes changes on develop that may or may not end up in the 1.0.0 release fixture.Checkout("develop"); @@ -532,7 +532,7 @@ public void PreventDecrementationOfVersionsOnTheMainBranch() fixture.Repository.Branches.Remove("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.1.0-alpha.4", configurationBuilder.Build()); + fixture.AssertFullSemver("1.1.0-alpha.5", configurationBuilder.Build()); fixture.Repository.Tags.Remove("1.0.0-beta.1"); @@ -540,12 +540,12 @@ public void PreventDecrementationOfVersionsOnTheMainBranch() fixture.BranchTo("main"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-0", configurationBuilder.Build()); + fixture.AssertFullSemver("1.0.0-5", configurationBuilder.Build()); configurationBuilder.WithNextVersion("1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-0", configurationBuilder.Build()); + fixture.AssertFullSemver("1.0.0-5", configurationBuilder.Build()); // Mark this version as RTM fixture.ApplyTag("1.0.0"); diff --git a/src/GitVersion.Core.Tests/IntegrationTests/DocumentationSamples.cs b/src/GitVersion.Core.Tests/IntegrationTests/DocumentationSamples.cs index 9f1a2a895b..71160f3a31 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/DocumentationSamples.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/DocumentationSamples.cs @@ -118,7 +118,7 @@ public void GitFlowMinorRelease() // Create release branch fixture.BranchTo("release/1.3.0", "release"); fixture.SequenceDiagram.Activate("release/1.3.0"); - fixture.AssertFullSemver("1.3.0-beta.1+0"); + fixture.AssertFullSemver("1.3.0-beta.1+1"); // Make another commit on develop fixture.Checkout("develop"); @@ -128,7 +128,7 @@ public void GitFlowMinorRelease() // Make a commit to release-1.3.0 fixture.Checkout("release/1.3.0"); fixture.MakeACommit(); - fixture.AssertFullSemver("1.3.0-beta.1+1"); + fixture.AssertFullSemver("1.3.0-beta.1+2"); // Apply beta.1 tag should be exact tag fixture.ApplyTag("1.3.0-beta.1"); @@ -152,7 +152,7 @@ public void GitFlowMinorRelease() // Not 0 for commit count as we can't know the increment rules of the merged branch fixture.Checkout("develop"); - fixture.AssertFullSemver("1.4.0-alpha.4"); + fixture.AssertFullSemver("1.4.0-alpha.2"); Console.WriteLine(fixture.SequenceDiagram.GetDiagram()); } @@ -173,7 +173,7 @@ public void GitFlowMajorRelease() // Create release branch fixture.BranchTo("release/2.0.0", "release"); fixture.SequenceDiagram.Activate("release/2.0.0"); - fixture.AssertFullSemver("2.0.0-beta.1+0"); + fixture.AssertFullSemver("2.0.0-beta.1+1"); // Make another commit on develop fixture.Checkout("develop"); @@ -183,7 +183,7 @@ public void GitFlowMajorRelease() // Make a commit to release-2.0.0 fixture.Checkout("release/2.0.0"); fixture.MakeACommit(); - fixture.AssertFullSemver("2.0.0-beta.1+1"); + fixture.AssertFullSemver("2.0.0-beta.1+2"); // Apply beta.1 tag should be exact tag fixture.ApplyTag("2.0.0-beta.1"); @@ -202,13 +202,13 @@ public void GitFlowMajorRelease() fixture.SequenceDiagram.NoteOver("Release branches are deleted once merged", "release/2.0.0"); fixture.Checkout(MainBranch); - fixture.AssertFullSemver("2.0.0-0"); + fixture.AssertFullSemver("2.0.0-4"); fixture.ApplyTag("2.0.0"); fixture.AssertFullSemver("2.0.0"); // Not 0 for commit count as we can't know the increment rules of the merged branch fixture.Checkout("develop"); - fixture.AssertFullSemver("2.1.0-alpha.4"); + fixture.AssertFullSemver("2.1.0-alpha.2"); Console.WriteLine(fixture.SequenceDiagram.GetDiagram()); } @@ -291,7 +291,7 @@ public void GitFlowSupportMinorRelease() fixture.MergeNoFF("release/1.4.0"); fixture.SequenceDiagram.Destroy("release/1.4.0"); fixture.SequenceDiagram.NoteOver("Release branches are deleted once merged", "release/1.4.0"); - fixture.AssertFullSemver("1.4.0-0"); + fixture.AssertFullSemver("1.4.0-3"); fixture.ApplyTag("1.4.0"); fixture.AssertFullSemver("1.4.0"); Console.WriteLine(fixture.SequenceDiagram.GetDiagram()); @@ -392,7 +392,7 @@ public void GitHubFlowMajorRelease() fixture.SequenceDiagram.Destroy("release/2.0.0"); fixture.SequenceDiagram.NoteOver("Release branches are deleted once merged", "release/2.0.0"); - fixture.AssertFullSemver("2.0.0-0"); + fixture.AssertFullSemver("2.0.0-4"); fixture.ApplyTag("2.0.0"); fixture.AssertFullSemver("2.0.0"); fixture.MakeACommit(); diff --git a/src/GitVersion.Core.Tests/IntegrationTests/DocumentationSamplesForGitFlow.cs b/src/GitVersion.Core.Tests/IntegrationTests/DocumentationSamplesForGitFlow.cs new file mode 100644 index 0000000000..085c667bb5 --- /dev/null +++ b/src/GitVersion.Core.Tests/IntegrationTests/DocumentationSamplesForGitFlow.cs @@ -0,0 +1,1058 @@ +using GitVersion.Configuration; +using GitVersion.VersionCalculation; +using LibGit2Sharp; + +namespace GitVersion.Core.Tests.IntegrationTests; + +[TestFixture] +public class DocumentationSamplesForGitFlow +{ + [TestCase(false)] + [TestCase(true)] + public void FeatureFromMainBranch(bool withPullRequestIntoMain) + { + var configuration = GitFlowConfigurationBuilder.New.Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.Repository.MakeACommit(); + fixture.ApplyTag("1.2.0"); + fixture.AssertFullSemver("1.2.0", configuration); + + // Branch from main + const string branchName = "feature/foo"; + fixture.BranchTo(branchName, "feature"); + fixture.SequenceDiagram.Activate("feature"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.1-foo.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-foo.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + fixture.ApplyTag("1.2.1"); + fixture.AssertFullSemver("1.2.1", configuration); + + // Merge main to feature branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.2-foo.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: minor"); + fixture.AssertFullSemver("1.3.0-foo.1+3", configuration); + + // Create pre-release on feature branch + fixture.ApplyTag("2.0.0-foo.1"); + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge feature into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Feature branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("2.0.0-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.0-6", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void FeatureFromMainBranchWithMainline(bool withPullRequestIntoMain) + { + var configuration = GitFlowConfigurationBuilder.New + .WithNextVersion("1.2.0") + .WithVersionStrategies(VersionStrategies.ConfiguredNextVersion, VersionStrategies.TrunkBased) + .Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.0-1", configuration); + fixture.Repository.ApplyTag("1.2.0"); + + // Branch from main + const string branchName = "feature/foo"; + fixture.BranchTo(branchName, "feature"); + fixture.SequenceDiagram.Activate("feature"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.1-foo.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-foo.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + + // Merge main to feature branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.2-foo.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: minor"); + fixture.AssertFullSemver("1.3.0-foo.1+3", configuration); + + // Create pre-release on feature branch + fixture.ApplyTag("2.0.0-foo.1"); + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge feature into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Feature branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("2.0.0-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.1-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void HotfixBranch(bool withPullRequestIntoMain) + { + var configuration = GitFlowConfigurationBuilder.New.Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.Repository.MakeACommit(); + fixture.ApplyTag("1.2.0"); + fixture.AssertFullSemver("1.2.0", configuration); + + // Branch from main + const string branchName = "hotfix/next"; + fixture.BranchTo(branchName, "hotfix"); + fixture.SequenceDiagram.Activate("hotfix"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.1-beta.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-beta.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + fixture.ApplyTag("1.2.1"); + fixture.AssertFullSemver("1.2.1", configuration); + + // Merge main to hotfix branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.2-beta.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: minor"); + fixture.AssertFullSemver("1.3.0-beta.1+3", configuration); + + // Create pre-release on hotfix branch + fixture.ApplyTag("2.0.0-beta.1"); + fixture.AssertFullSemver("2.0.0-beta.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.0-beta.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge hotfix into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Hotfix branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("2.0.0-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.0-6", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void HotfixBranchWithMainline(bool withPullRequestIntoMain) + { + var configuration = GitFlowConfigurationBuilder.New + .WithNextVersion("1.2.0") + .WithVersionStrategies(VersionStrategies.ConfiguredNextVersion, VersionStrategies.TrunkBased) + .Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.0-1", configuration); + fixture.Repository.ApplyTag("1.2.0"); + + // Branch from main + const string branchName = "hotfix/next"; + fixture.BranchTo(branchName, "hotfix"); + fixture.SequenceDiagram.Activate("hotfix"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.1-beta.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-beta.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + + // Merge main to hotfix branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.2-beta.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: minor"); + fixture.AssertFullSemver("1.3.0-beta.1+3", configuration); + + // Create pre-release on hotfix branch + fixture.ApplyTag("2.0.0-beta.1"); + fixture.AssertFullSemver("2.0.0-beta.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.0-beta.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge hotfix into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Hotfix branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("2.0.0-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.1-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void VersionedHotfixBranch(bool withPullRequestIntoMain) + { + var configuration = GitFlowConfigurationBuilder.New.Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.Repository.MakeACommit(); + fixture.ApplyTag("1.2.0"); + fixture.AssertFullSemver("1.2.0", configuration); + + // Branch from main + const string branchName = "hotfix/2.2.1"; + fixture.BranchTo(branchName, "hotfix"); + fixture.SequenceDiagram.Activate("hotfix"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("2.2.1-beta.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.2.1-beta.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + fixture.ApplyTag("2.2.1"); + fixture.AssertFullSemver("2.2.1", configuration); + + // Merge main to hotfix branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("2.2.2-beta.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: major"); + fixture.AssertFullSemver("3.0.0-beta.1+3", configuration); + + // Create pre-release on hotfix branch + fixture.ApplyTag("3.0.1-beta.1"); + fixture.AssertFullSemver("3.0.1-beta.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("3.0.1-beta.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("3.0.1-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge hotfix into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Hotfix branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("3.0.1-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("3.0.1-6", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void VersionedHotfixBranchWithMainline(bool withPullRequestIntoMain) + { + var configuration = GitFlowConfigurationBuilder.New + .WithNextVersion("1.2.0") + .WithVersionStrategies(VersionStrategies.ConfiguredNextVersion, VersionStrategies.TrunkBased) + .Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.0-1", configuration); + fixture.Repository.ApplyTag("1.2.0"); + + // Branch from main + const string branchName = "hotfix/2.2.1"; + fixture.BranchTo(branchName, "hotfix"); + fixture.SequenceDiagram.Activate("hotfix"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("2.2.1-beta.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.2.1-beta.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + + // Merge main to hotfix branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("2.2.1-beta.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: major"); + fixture.AssertFullSemver("2.2.1-beta.1+3", configuration); + + // Create pre-release on hotfix branch + fixture.ApplyTag("2.2.2-beta.1"); + fixture.AssertFullSemver("2.2.2-beta.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.2.2-beta.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("2.2.2-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge hotfix into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Hotfix branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("2.2.2-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.2.3-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void ReleaseBranch(bool withPullRequestIntoMain) + { + var configuration = GitFlowConfigurationBuilder.New.Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.Repository.MakeACommit(); + fixture.ApplyTag("1.2.0"); + fixture.AssertFullSemver("1.2.0", configuration); + + // Branch from main + const string branchName = "release/next"; + fixture.BranchTo(branchName, "release"); + fixture.SequenceDiagram.Activate("release"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.3.0-beta.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.3.0-beta.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + fixture.ApplyTag("1.2.1"); + fixture.AssertFullSemver("1.2.1", configuration); + + // Merge main to release branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.3.0-beta.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: major"); + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + + // Create pre-release on release branch + fixture.ApplyTag("2.0.1-beta.1"); + fixture.AssertFullSemver("2.0.1-beta.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.1-beta.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("2.0.1-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge release into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Release branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("2.0.1-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.1-6", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void ReleaseBranchWithMainline(bool withPullRequestIntoMain) + { + var configuration = GitFlowConfigurationBuilder.New + .WithNextVersion("1.2.0") + .WithVersionStrategies(VersionStrategies.ConfiguredNextVersion, VersionStrategies.TrunkBased) + .Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.0-1", configuration); + fixture.Repository.ApplyTag("1.2.0"); + + // Branch from main + const string branchName = "release/next"; + fixture.BranchTo(branchName, "release"); + fixture.SequenceDiagram.Activate("release"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.3.0-beta.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.3.0-beta.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + + // Merge main to release branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.3.0-beta.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: major"); + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + + // Create pre-release on release branch + fixture.ApplyTag("2.0.1-beta.1"); + fixture.AssertFullSemver("2.0.1-beta.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.1-beta.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("2.0.1-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge release into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Release branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("2.0.1-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.2-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void VersionedReleaseBranch(bool withPullRequestIntoMain) + { + var configuration = GitFlowConfigurationBuilder.New.Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.Repository.MakeACommit(); + fixture.ApplyTag("1.2.0"); + fixture.AssertFullSemver("1.2.0", configuration); + + // Branch from main + const string branchName = "release/2.2.1"; + fixture.BranchTo(branchName, "release"); + fixture.SequenceDiagram.Activate("release"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("2.2.1-beta.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.2.1-beta.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + fixture.ApplyTag("2.2.1"); + fixture.AssertFullSemver("2.2.1", configuration); + + // Merge main to release branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("2.3.0-beta.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: major"); + fixture.AssertFullSemver("3.0.0-beta.1+3", configuration); + + // Create pre-release on release branch + fixture.ApplyTag("3.0.1-beta.1"); + fixture.AssertFullSemver("3.0.1-beta.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("3.0.1-beta.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("3.0.1-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge release into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Release branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("3.0.1-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("3.0.1-6", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void VersionedReleaseBranchWithMainline(bool withPullRequestIntoMain) + { + var configuration = GitFlowConfigurationBuilder.New + .WithNextVersion("1.2.0") + .WithVersionStrategies(VersionStrategies.ConfiguredNextVersion, VersionStrategies.TrunkBased) + .Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.0-1", configuration); + fixture.Repository.ApplyTag("1.2.0"); + + // Branch from main + const string branchName = "release/2.2.1"; + fixture.BranchTo(branchName, "release"); + fixture.SequenceDiagram.Activate("release"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("2.2.1-beta.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.2.1-beta.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + + // Merge main to release branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("2.2.1-beta.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: major"); + fixture.AssertFullSemver("2.2.1-beta.1+3", configuration); + + // Create pre-release on release branch + fixture.ApplyTag("2.2.1-beta.1"); + fixture.AssertFullSemver("2.2.1-beta.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.2.1-beta.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("2.2.1-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge release into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Release branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("2.2.1-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.2.2-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void DevelopBranch(bool withPullRequestIntoMain) + { + var configuration = GitFlowConfigurationBuilder.New.Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + fixture.SequenceDiagram.Participant("main"); + fixture.SequenceDiagram.Participant("develop"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.Repository.MakeACommit(); + fixture.ApplyTag("1.2.0"); + fixture.AssertFullSemver("1.2.0", configuration); + + // Branch from main + const string branchName = "develop"; + fixture.BranchTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.SequenceDiagram.Activate(branchName); + fixture.AssertFullSemver("1.3.0-alpha.0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.3.0-alpha.1", configuration); + + // Create release from develop branch + fixture.BranchTo("release/1.3.0", "release"); + fixture.SequenceDiagram.Deactivate("develop"); + fixture.SequenceDiagram.Activate("release"); + fixture.AssertFullSemver("1.3.0-beta.1+1", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.3.0-beta.1+2", configuration); + + // Bump to major version increment + fixture.Checkout("develop"); + fixture.SequenceDiagram.Activate("develop"); + fixture.AssertFullSemver("1.4.0-alpha.0", configuration); + + // Merge release into develop branch + fixture.MergeNoFF("release/1.3.0"); + fixture.AssertFullSemver("1.4.0-alpha.2", configuration); + + // Merge release into main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MergeNoFF("release/1.3.0"); + fixture.Remove("release/1.3.0"); + fixture.SequenceDiagram.NoteOver("Release branches should\r\nbe deleted once merged", "release"); + fixture.ApplyTag("1.3.0"); + fixture.AssertFullSemver("1.3.0", configuration); + + // Create hotfix on main branch + fixture.MakeACommit(); + fixture.AssertFullSemver("1.3.1-1", configuration); + + // Merge main to release branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.4.0-alpha.3", configuration); + fixture.MakeACommit("+semver: major"); + fixture.AssertFullSemver("2.0.0-alpha.4", configuration); + + // Create pre-release on release branch + fixture.ApplyTag("2.1.0-alpha.1"); + fixture.AssertFullSemver("2.1.0-alpha.1", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.1.0-alpha.2", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("2.1.0-PullRequest2.6", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge develop into main branch + fixture.MergeNoFF(branchName); + fixture.SequenceDiagram.Deactivate(branchName); + fixture.AssertFullSemver("2.1.0-6", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.1.0-7", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void DevelopBranchWithMainline(bool withPullRequestIntoMain) + { + var configuration = GitFlowConfigurationBuilder.New + .WithNextVersion("1.2.0") + .WithVersionStrategies(VersionStrategies.ConfiguredNextVersion, VersionStrategies.TrackReleaseBranches, VersionStrategies.TrunkBased) + .Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + fixture.SequenceDiagram.Participant("main"); + fixture.SequenceDiagram.Participant("develop"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.0-1", configuration); + fixture.Repository.ApplyTag("1.2.0"); + + // Branch from main + const string branchName = "develop"; + fixture.BranchTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.SequenceDiagram.Activate(branchName); + fixture.AssertFullSemver("1.3.0-alpha.0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.3.0-alpha.1", configuration); + + // Create release from develop branch + fixture.BranchTo("release/1.3.0", "release"); + fixture.SequenceDiagram.Deactivate("develop"); + fixture.SequenceDiagram.Activate("release"); + fixture.AssertFullSemver("1.3.0-beta.1+1", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.3.0-beta.1+2", configuration); + + // Bump to major version increment + fixture.Checkout("develop"); + fixture.SequenceDiagram.Activate("develop"); + fixture.AssertFullSemver("1.4.0-alpha.0", configuration); + + // Merge release into develop branch + fixture.MergeNoFF("release/1.3.0"); + fixture.AssertFullSemver("1.4.0-alpha.2", configuration); + + // Merge release into main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MergeNoFF("release/1.3.0"); + fixture.Remove("release/1.3.0"); + fixture.SequenceDiagram.NoteOver("Release branches should\r\nbe deleted once merged", "release"); + + // Create hotfix on main branch + fixture.MakeACommit(); + fixture.AssertFullSemver("1.3.1-1", configuration); + + // Merge main to release branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.4.0-alpha.2", configuration); + fixture.MakeACommit("+semver: major"); + fixture.AssertFullSemver("2.0.0-alpha.3", configuration); + + // Create pre-release on release branch + fixture.ApplyTag("2.1.0-alpha.1"); + fixture.AssertFullSemver("2.1.0-alpha.1", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.1.0-alpha.2", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("2.1.0-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge develop into main branch + fixture.MergeNoFF(branchName); + fixture.SequenceDiagram.Deactivate(branchName); + fixture.AssertFullSemver("2.1.0-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.1.1-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void SupportBranch(bool withPullRequestIntoSupport) + { + var configuration = GitFlowConfigurationBuilder.New.Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + fixture.SequenceDiagram.Participant("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.Repository.MakeACommit(); + fixture.ApplyTag("1.2.0"); + fixture.AssertFullSemver("1.2.0", configuration); + + // Branch from main + fixture.BranchToFromTag("support/1.x", "1.2.0", "main", "support"); + fixture.SequenceDiagram.Activate("support"); + fixture.AssertFullSemver("1.2.0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("+semver: major"); + fixture.AssertFullSemver("2.0.0-1", configuration); + fixture.ApplyTag("2.0.0"); + fixture.AssertFullSemver("2.0.0", configuration); + + fixture.Checkout("support/1.x"); + fixture.BranchTo("hotfix/1.2.2", "hotfix"); + fixture.SequenceDiagram.Deactivate("support"); + fixture.SequenceDiagram.Activate("hotfix"); + fixture.AssertFullSemver("1.2.2-beta.1+1", configuration); + fixture.MakeACommit(); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.2-beta.1+3", configuration); + fixture.ApplyTag("1.2.3-beta.1"); + fixture.AssertFullSemver("1.2.3-beta.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.3-beta.2+1", configuration); + fixture.Checkout("support/1.x"); + + if (withPullRequestIntoSupport) + { + // Create a PullRequest into support + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF("hotfix/1.2.2"); + fixture.AssertFullSemver("1.2.3-PullRequest2.5", configuration); + fixture.Checkout("support/1.x"); + fixture.Remove("pull/2/merge"); + } + + // Merge hotfix into support branch + fixture.MergeNoFF("hotfix/1.2.2"); + fixture.Remove("hotfix/1.2.2"); + fixture.SequenceDiagram.NoteOver("Hotfix branches should\r\nbe deleted once merged", "hotfix/1.2.2"); + fixture.AssertFullSemver("1.2.3-5", configuration); + + // Commit on support branch + fixture.SequenceDiagram.Activate("support"); + fixture.ApplyTag("1.2.3"); + fixture.AssertFullSemver("1.2.3", configuration); + + fixture.Checkout("main"); + fixture.AssertFullSemver("2.0.0", configuration); + fixture.MergeNoFF("support/1.x"); + fixture.AssertFullSemver("2.0.1-6", configuration); + fixture.ApplyTag("2.0.1"); + fixture.AssertFullSemver("2.0.1", configuration); + + fixture.Checkout("support/1.x"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.4-1", configuration); + + fixture.Checkout("main"); + fixture.MergeNoFF("support/1.x"); + fixture.AssertFullSemver("2.0.2-2", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void SupportBranchWithMainline(bool withPullRequestIntoSupport) + { + var configuration = GitFlowConfigurationBuilder.New + .WithNextVersion("1.2.0") + .WithVersionStrategies(VersionStrategies.ConfiguredNextVersion, VersionStrategies.TrackReleaseBranches, VersionStrategies.TrunkBased) + .Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + fixture.SequenceDiagram.Participant("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.0-1", configuration); + fixture.Repository.ApplyTag("1.2.0"); + + // Branch from main + fixture.BranchToFromTag("support/1.x", "1.2.0", "main", "support"); + fixture.SequenceDiagram.Activate("support"); + fixture.AssertFullSemver("1.2.0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + + fixture.Checkout("main"); + fixture.MakeACommit("+semver: major"); + fixture.AssertFullSemver("2.0.0-1", configuration); + + fixture.Checkout("support/1.x"); + fixture.BranchTo("hotfix/1.2.2", "hotfix"); + fixture.SequenceDiagram.Deactivate("support"); + fixture.SequenceDiagram.Activate("hotfix"); + fixture.AssertFullSemver("1.2.2-beta.1+0", configuration); + fixture.MakeACommit(); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.2-beta.1+2", configuration); + fixture.ApplyTag("1.2.3-beta.1"); + fixture.AssertFullSemver("1.2.3-beta.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.3-beta.2+1", configuration); + fixture.Checkout("support/1.x"); + + if (withPullRequestIntoSupport) + { + // Create a PullRequest into support + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF("hotfix/1.2.2"); + fixture.AssertFullSemver("1.2.3-PullRequest2.4", configuration); + fixture.Checkout("support/1.x"); + fixture.Remove("pull/2/merge"); + } + + // Merge hotfix into support branch + fixture.MergeNoFF("hotfix/1.2.2"); + fixture.Remove("hotfix/1.2.2"); + fixture.SequenceDiagram.NoteOver("Hotfix branches should\r\nbe deleted once merged", "hotfix/1.2.2"); + fixture.AssertFullSemver("1.2.3-4", configuration); + + // Commit on support branch + fixture.SequenceDiagram.Activate("support"); + + fixture.Checkout("main"); + fixture.AssertFullSemver("2.0.0-1", configuration); + //fixture.MergeNoFF("support/1.x"); + //fixture.AssertFullSemver("2.0.1-6", configuration); + + //fixture.Checkout("support/1.x"); + //fixture.MakeACommit(); + //fixture.AssertFullSemver("1.2.4-1", configuration); + + //fixture.Checkout("main"); + //fixture.MergeNoFF("support/1.x"); + //fixture.AssertFullSemver("2.0.2-2", configuration); + } +} diff --git a/src/GitVersion.Core.Tests/IntegrationTests/DocumentationSamplesForGitHubFlow.cs b/src/GitVersion.Core.Tests/IntegrationTests/DocumentationSamplesForGitHubFlow.cs new file mode 100644 index 0000000000..14e9ef28a0 --- /dev/null +++ b/src/GitVersion.Core.Tests/IntegrationTests/DocumentationSamplesForGitHubFlow.cs @@ -0,0 +1,432 @@ +using GitVersion.Configuration; +using GitVersion.VersionCalculation; +using LibGit2Sharp; + +namespace GitVersion.Core.Tests.IntegrationTests; + +[TestFixture] +public class DocumentationSamplesForGitHubFlow +{ + [TestCase(false)] + [TestCase(true)] + public void FeatureBranch(bool withPullRequestIntoMain) + { + var configuration = GitHubFlowConfigurationBuilder.New.Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.Repository.MakeACommit(); + fixture.ApplyTag("1.2.0"); + fixture.AssertFullSemver("1.2.0", configuration); + + // Branch from main + const string branchName = "feature/foo"; + fixture.BranchTo(branchName, "feature"); + fixture.SequenceDiagram.Activate("feature"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.1-foo.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-foo.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + fixture.ApplyTag("1.2.1"); + fixture.AssertFullSemver("1.2.1", configuration); + + // Merge main to feature branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.2-foo.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: minor"); + fixture.AssertFullSemver("1.3.0-foo.1+3", configuration); + + // Create pre-release on feature branch + fixture.ApplyTag("2.0.0-foo.1"); + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge feature into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Feature branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("2.0.0-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.0-6", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void FeatureBranchWithMainline(bool withPullRequestIntoMain) + { + var configuration = GitHubFlowConfigurationBuilder.New + .WithNextVersion("1.2.0") + .WithVersionStrategies(VersionStrategies.ConfiguredNextVersion, VersionStrategies.TrunkBased) + .Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.0-1", configuration); + fixture.Repository.ApplyTag("1.2.0"); + + // Branch from main + const string branchName = "feature/foo"; + fixture.BranchTo(branchName, "feature"); + fixture.SequenceDiagram.Activate("feature"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.1-foo.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-foo.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + + // Merge main to feature branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.2-foo.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: minor"); + fixture.AssertFullSemver("1.3.0-foo.1+3", configuration); + + // Create pre-release on feature branch + fixture.ApplyTag("2.0.0-foo.1"); + fixture.AssertFullSemver("2.0.0-foo.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.0-foo.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("2.0.0-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge feature into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Feature branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("2.0.0-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.0.1-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void ReleaseBranch(bool withPullRequestIntoMain) + { + var configuration = GitHubFlowConfigurationBuilder.New.Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.Repository.MakeACommit(); + fixture.ApplyTag("1.2.0"); + fixture.AssertFullSemver("1.2.0", configuration); + + // Branch from main + const string branchName = "release/next"; + fixture.BranchTo(branchName, "release"); + fixture.SequenceDiagram.Activate("release"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.1-beta.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-beta.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + fixture.ApplyTag("1.2.1"); + fixture.AssertFullSemver("1.2.1", configuration); + + // Merge main to release branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.2-beta.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: minor"); + fixture.AssertFullSemver("1.3.0-beta.1+3", configuration); + + // Create pre-release on release branch + fixture.ApplyTag("1.3.1-beta.1"); + fixture.AssertFullSemver("1.3.1-beta.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.3.1-beta.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("1.3.1-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge release into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Release branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("1.3.1-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.3.1-6", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void ReleaseBranchWithMainline(bool withPullRequestIntoMain) + { + var configuration = GitHubFlowConfigurationBuilder.New + .WithNextVersion("1.2.0") + .WithVersionStrategies(VersionStrategies.ConfiguredNextVersion, VersionStrategies.TrunkBased) + .Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.0-1", configuration); + fixture.Repository.ApplyTag("1.2.0"); + + // Branch from main + const string branchName = "release/next"; + fixture.BranchTo(branchName, "release"); + fixture.SequenceDiagram.Activate("release"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.1-beta.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-beta.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + + // Merge main to release branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("1.2.2-beta.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: minor"); + fixture.AssertFullSemver("1.3.0-beta.1+3", configuration); + + // Create pre-release on release branch + fixture.ApplyTag("1.3.1-beta.1"); + fixture.AssertFullSemver("1.3.1-beta.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.3.1-beta.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("1.3.1-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge release into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Release branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("1.3.1-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.3.2-1", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void VersionedReleaseBranch(bool withPullRequestIntoMain) + { + var configuration = GitHubFlowConfigurationBuilder.New.Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.Repository.MakeACommit(); + fixture.ApplyTag("1.2.0"); + fixture.AssertFullSemver("1.2.0", configuration); + + // Branch from main + const string branchName = "release/2.2.1"; + fixture.BranchTo(branchName, "release"); + fixture.SequenceDiagram.Activate("release"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("2.2.1-beta.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.2.1-beta.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + fixture.ApplyTag("2.2.1"); + fixture.AssertFullSemver("2.2.1", configuration); + + // Merge main to release branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("2.2.2-beta.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: minor"); + fixture.AssertFullSemver("2.3.0-beta.1+3", configuration); + + // Create pre-release on release branch + fixture.ApplyTag("2.3.1-beta.1"); + fixture.AssertFullSemver("2.3.1-beta.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.3.1-beta.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("2.3.1-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge release into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Release branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("2.3.1-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.3.1-6", configuration); + } + + [TestCase(false)] + [TestCase(true)] + public void VersionedReleaseBranchWithMainline(bool withPullRequestIntoMain) + { + var configuration = GitHubFlowConfigurationBuilder.New + .WithNextVersion("1.2.0") + .WithVersionStrategies(VersionStrategies.ConfiguredNextVersion, VersionStrategies.TrunkBased) + .Build(); + + using EmptyRepositoryFixture fixture = new("main"); + + // GitFlow setup + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.0-1", configuration); + fixture.Repository.ApplyTag("1.2.0"); + + // Branch from main + const string branchName = "release/2.2.1"; + fixture.BranchTo(branchName, "release"); + fixture.SequenceDiagram.Activate("release"); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("2.2.1-beta.1+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.2.1-beta.1+1", configuration); + + // Create hotfix on main branch + fixture.Checkout("main"); + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("1.2.1-1", configuration); + + // Merge main to release branch + fixture.MergeTo(branchName); + fixture.SequenceDiagram.Deactivate("main"); + fixture.AssertFullSemver("2.2.1-beta.1+2", configuration); + + // Bump to minor version increment + fixture.MakeACommit("+semver: major"); + fixture.AssertFullSemver("2.2.1-beta.1+3", configuration); + + // Create pre-release on release branch + fixture.ApplyTag("2.2.1-beta.1"); + fixture.AssertFullSemver("2.2.1-beta.2+0", configuration); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.2.1-beta.2+1", configuration); + fixture.Checkout("main"); + + if (withPullRequestIntoMain) + { + // Create a PullRequest into main + fixture.BranchTo("pull/2/merge", "pull"); + fixture.SequenceDiagram.Activate("pull/2/merge"); + fixture.MergeNoFF(branchName); + fixture.AssertFullSemver("2.2.1-PullRequest2.5", configuration); + fixture.Checkout("main"); + fixture.Remove("pull/2/merge"); + } + + // Merge release into main branch + fixture.MergeNoFF(branchName); + fixture.Remove(branchName); + fixture.SequenceDiagram.NoteOver("Release branches should\r\nbe deleted once merged", branchName); + fixture.AssertFullSemver("2.2.1-5", configuration); + + // Commit on main branch + fixture.SequenceDiagram.Activate("main"); + fixture.MakeACommit(); + fixture.AssertFullSemver("2.2.2-1", configuration); + } +} diff --git a/src/GitVersion.Core.Tests/IntegrationTests/FeatureBranchScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/FeatureBranchScenarios.cs index e0db3bb7ee..9b30536fd7 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/FeatureBranchScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/FeatureBranchScenarios.cs @@ -179,7 +179,7 @@ public void CanUseBranchNameOffAReleaseBranch() fixture.BranchTo("feature/PROJ-1"); fixture.MakeACommit(); - fixture.AssertFullSemver("0.3.0-PROJ-1.1+3", configuration); + fixture.AssertFullSemver("0.3.0-PROJ-1.1+4", configuration); } [TestCase("alpha", "JIRA-123", "^features?[/-](?.+)", "alpha")] @@ -213,7 +213,7 @@ public void BranchCreatedAfterFinishReleaseShouldInheritAndIncrementFromLastMain Commands.Checkout(fixture.Repository, "release/0.2.0"); //validate release version - fixture.AssertFullSemver("0.2.0-beta.1+0"); + fixture.AssertFullSemver("0.2.0-beta.1+1"); fixture.Checkout(MainBranch); fixture.Repository.MergeNoFF("release/0.2.0"); @@ -424,7 +424,7 @@ public void PickUpVersionFromMainMarkedWithIsTracksReleaseBranches() .WithDeploymentMode(DeploymentMode.ManualDeployment) .WithBranch("unknown", builder => builder.WithIncrement(IncrementStrategy.Patch).WithTracksReleaseBranches(true)) .WithBranch(MainBranch, builder => builder.WithLabel("pre").WithTracksReleaseBranches(true)) - .WithBranch("release", builder => builder.WithLabel("rc").WithTracksReleaseBranches(true)) + .WithBranch("release", builder => builder.WithLabel("rc")) .Build(); using var fixture = new EmptyRepositoryFixture(); @@ -434,7 +434,7 @@ public void PickUpVersionFromMainMarkedWithIsTracksReleaseBranches() fixture.BranchTo("release/0.10.0"); fixture.MakeACommit(); fixture.MakeACommit(); - fixture.AssertFullSemver("0.10.0-rc.1+2", configuration); + fixture.AssertFullSemver("0.10.0-rc.1+3", configuration); // switch to main and verify the version fixture.Checkout(MainBranch); diff --git a/src/GitVersion.Core.Tests/IntegrationTests/GitflowScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/GitflowScenarios.cs index 9b7fc6ce56..26ee975616 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/GitflowScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/GitflowScenarios.cs @@ -30,39 +30,39 @@ public void GitflowComplexExample() // Release 1.1.0 fixture.BranchTo(release1Branch); fixture.MakeACommit("release stabilization"); - fixture.AssertFullSemver("1.1.0-beta.1+1"); + fixture.AssertFullSemver("1.1.0-beta.1+4"); fixture.Checkout(MainBranch); fixture.MergeNoFF(release1Branch); - fixture.AssertFullSemver("1.1.0-0"); + fixture.AssertFullSemver("1.1.0-5"); fixture.ApplyTag("1.1.0"); fixture.AssertFullSemver("1.1.0"); fixture.Checkout(developBranch); fixture.MergeNoFF(release1Branch); fixture.Repository.Branches.Remove(fixture.Repository.Branches[release1Branch]); - fixture.AssertFullSemver("1.2.0-alpha.2"); + fixture.AssertFullSemver("1.2.0-alpha.1"); // Feature 2 fixture.BranchTo(feature2Branch); fixture.MakeACommit("added feature 2"); - fixture.AssertFullSemver("1.2.0-f2.1+3"); + fixture.AssertFullSemver("1.2.0-f2.1+2"); fixture.Checkout(developBranch); fixture.MergeNoFF(feature2Branch); fixture.Repository.Branches.Remove(fixture.Repository.Branches[feature2Branch]); - fixture.AssertFullSemver("1.2.0-alpha.4"); + fixture.AssertFullSemver("1.2.0-alpha.3"); // Release 1.2.0 fixture.BranchTo(release2Branch); fixture.MakeACommit("release stabilization"); - fixture.AssertFullSemver("1.2.0-beta.1+1"); + fixture.AssertFullSemver("1.2.0-beta.1+8"); fixture.Checkout(MainBranch); fixture.MergeNoFF(release2Branch); - fixture.AssertFullSemver("1.2.0-0"); + fixture.AssertFullSemver("1.2.0-5"); fixture.ApplyTag("1.2.0"); fixture.AssertFullSemver("1.2.0"); fixture.Checkout(developBranch); fixture.MergeNoFF(release2Branch); fixture.Repository.Branches.Remove(fixture.Repository.Branches[release2Branch]); - fixture.AssertFullSemver("1.3.0-alpha.2"); + fixture.AssertFullSemver("1.3.0-alpha.1"); // Hotfix fixture.Checkout(MainBranch); @@ -77,7 +77,7 @@ public void GitflowComplexExample() fixture.Checkout(developBranch); fixture.MergeNoFF(hotfixBranch); fixture.Repository.Branches.Remove(fixture.Repository.Branches[hotfixBranch]); - fixture.AssertFullSemver("1.3.0-alpha.9"); + fixture.AssertFullSemver("1.3.0-alpha.2"); } } } diff --git a/src/GitVersion.Core.Tests/IntegrationTests/HotfixBranchScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/HotfixBranchScenarios.cs index ed1b452457..8bd468453a 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/HotfixBranchScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/HotfixBranchScenarios.cs @@ -39,7 +39,7 @@ public void PatchLatestReleaseExample() fixture.AssertFullSemver("1.3.0-alpha.1"); fixture.Repository.MergeNoFF("hotfix-1.2.1", Generate.SignatureNow()); - fixture.AssertFullSemver("1.3.0-alpha.5"); + fixture.AssertFullSemver("1.3.0-alpha.2"); } [Test] @@ -141,7 +141,7 @@ public void FeatureOnHotfixFeatureBranchDeleted() // create release branch fixture.BranchTo(release450); - fixture.AssertFullSemver("4.5.0-beta.1+0", configuration); + fixture.AssertFullSemver("4.5.0-beta.1+1", configuration); fixture.MakeACommit("blabla"); fixture.Checkout("develop"); fixture.MergeNoFF(release450); @@ -162,7 +162,7 @@ public void FeatureOnHotfixFeatureBranchDeleted() fixture.Checkout(hotfix451); fixture.MergeNoFF(featureBranch); // commit 2 fixture.Repository.Branches.Remove(featureBranch); - fixture.AssertFullSemver("4.5.1-beta.1+4", configuration); + fixture.AssertFullSemver("4.5.1-beta.1+2", configuration); } /// @@ -187,7 +187,7 @@ public void FeatureOnHotfixFeatureBranchNotDeleted() // create release branch fixture.BranchTo(release450); - fixture.AssertFullSemver("4.5.0-beta.1+0", configuration); + fixture.AssertFullSemver("4.5.0-beta.1+1", configuration); fixture.MakeACommit("blabla"); fixture.Checkout("develop"); fixture.MergeNoFF(release450); @@ -208,7 +208,7 @@ public void FeatureOnHotfixFeatureBranchNotDeleted() fixture.Checkout(hotfix451); fixture.MergeNoFF(featureBranch); // commit 2 - fixture.AssertFullSemver("4.5.1-beta.1+4", configuration); + fixture.AssertFullSemver("4.5.1-beta.1+2", configuration); } [Test] @@ -222,15 +222,15 @@ public void IsVersionTakenFromHotfixBranchName() fixture.AssertFullSemver("4.21.0-alpha.1", configuration); fixture.BranchTo("release/4.21.1"); - fixture.AssertFullSemver("4.21.1-beta.1+0", configuration); + fixture.AssertFullSemver("4.21.1-beta.1+1", configuration); fixture.MakeACommit(); - fixture.AssertFullSemver("4.21.1-beta.1+1", configuration); + fixture.AssertFullSemver("4.21.1-beta.1+2", configuration); fixture.BranchTo("hotfix/4.21.1"); - fixture.AssertFullSemver("4.21.1-beta.1+1", configuration); + fixture.AssertFullSemver("4.21.1-beta.1+2", configuration); fixture.MakeACommit(); - fixture.AssertFullSemver("4.21.1-beta.1+2", configuration); + fixture.AssertFullSemver("4.21.1-beta.1+3", configuration); } } diff --git a/src/GitVersion.Core.Tests/IntegrationTests/MainScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/MainScenarios.cs index 6278afdfea..c4bae960c6 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/MainScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/MainScenarios.cs @@ -300,13 +300,13 @@ public void PreventDecrementationOfVersionsOnTheDevelopmentBranch() fixture.Checkout("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+0", configurationBuilder.Build()); + fixture.AssertFullSemver("1.0.0-beta.1+1", configurationBuilder.Build()); // make another commit on release/1.0.0 to prepare the actual beta1 release fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.0.0-beta.1+1", configurationBuilder.Build()); + fixture.AssertFullSemver("1.0.0-beta.1+2", configurationBuilder.Build()); // now we makes changes on develop that may or may not end up in the 1.0.0 release fixture.Checkout("develop"); @@ -370,23 +370,21 @@ public void PreventDecrementationOfVersionsOnTheDevelopmentBranch() fixture.Repository.Branches.Remove("release/1.0.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.1.0-alpha.3", configurationBuilder.Build()); + fixture.AssertFullSemver("1.1.0-alpha.6", configurationBuilder.Build()); fixture.Repository.Tags.Remove("1.0.0-beta.1"); fixture.Repository.Tags.Remove("1.0.0-beta.2"); - // ❔ expected: "1.0.0-alpha.3" - // This behavior needs to be changed for the git flow workflow using the track-merge-message or track-merge-target options. - // [Bug] track-merge-changes produces unexpected result when combining hotfix and support branches #3052 - fixture.AssertFullSemver("1.1.0-alpha.3", configurationBuilder.Build()); + // ✅ succeeds as expected + fixture.AssertFullSemver("1.1.0-alpha.6", configurationBuilder.Build()); configurationBuilder.WithNextVersion("1.1.0"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.1.0-alpha.3", configurationBuilder.Build()); + fixture.AssertFullSemver("1.1.0-alpha.6", configurationBuilder.Build()); } - [TestCase(true, "1.1.0-0")] + [TestCase(true, "1.1.0-4")] [TestCase(false, "1.0.1-4")] public void TrackMergeMessageShouldBeConsideredOnTheMainBranch(bool trackMergeMessage, string expectedSemanticVersion) { diff --git a/src/GitVersion.Core.Tests/IntegrationTests/OtherBranchScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/OtherBranchScenarios.cs index 2af65b65a1..985e6e865a 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/OtherBranchScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/OtherBranchScenarios.cs @@ -95,7 +95,7 @@ public void ShouldOnlyConsiderTagsMatchingOfCurrentBranch() fixture.BranchTo("release/0.1.2"); // ✅ succeeds as expected - fixture.AssertFullSemver("0.1.2-rc.1+0", configuration); + fixture.AssertFullSemver("0.1.2-rc.1+3", configuration); } [Test] @@ -113,7 +113,7 @@ public void CanTakeVersionFromReleaseBranch() fixture.BranchTo("release/2.0.0-LTS"); fixture.MakeACommit(); - fixture.AssertFullSemver("2.0.0-LTS.1+1", configuration); + fixture.AssertFullSemver("2.0.0-LTS.1+6", configuration); } [Test] diff --git a/src/GitVersion.Core.Tests/IntegrationTests/OtherScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/OtherScenarios.cs index 73a968ff64..34e7881620 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/OtherScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/OtherScenarios.cs @@ -1053,7 +1053,9 @@ public void EnsureThePreReleaseTagIsCorrectlyGeneratedWhenPreReleaseLabelIsEmpty } [TestCase("0.0.1-alpha.2", true, "0.0.1-alpha.2")] - [TestCase("0.0.1-alpha.2", false, "0.1.0-alpha.1+0")] + [TestCase("0.0.1-alpha.2", false, "0.0.1-alpha.3+0")] + [TestCase("0.1.0-alpha.2", true, "0.1.0-alpha.2")] + [TestCase("0.1.0-alpha.2", false, "0.1.0-alpha.3+0")] [TestCase("0.0.1", true, "0.0.1")] [TestCase("0.0.1", false, "0.1.0-alpha.1+0")] [TestCase("0.0.1-beta.2", true, "0.1.0-alpha.1+1")] @@ -1080,7 +1082,9 @@ public void EnsurePreventIncrementWhenCurrentCommitTaggedOnDevelopWithDeployment } [TestCase("0.0.1-alpha.2", true, "0.0.1-alpha.2")] - [TestCase("0.0.1-alpha.2", false, "0.1.0-alpha.0")] + [TestCase("0.0.1-alpha.2", false, "0.0.1-alpha.2")] + [TestCase("0.1.0-alpha.2", true, "0.1.0-alpha.2")] + [TestCase("0.1.0-alpha.2", false, "0.1.0-alpha.2")] [TestCase("0.0.1", true, "0.0.1")] [TestCase("0.0.1", false, "0.1.0-alpha.0")] [TestCase("0.0.1-beta.2", true, "0.1.0-alpha.1")] @@ -1107,7 +1111,9 @@ public void EnsurePreventIncrementWhenCurrentCommitTaggedOnDevelopWithDeployment } [TestCase("0.0.1-alpha.2", true, "0.0.1")] - [TestCase("0.0.1-alpha.2", false, "0.1.0")] + [TestCase("0.0.1-alpha.2", false, "0.0.1")] + [TestCase("0.1.0-alpha.2", true, "0.1.0")] + [TestCase("0.1.0-alpha.2", false, "0.1.0")] [TestCase("0.0.1", true, "0.0.1")] [TestCase("0.0.1", false, "0.1.0")] [TestCase("0.0.1-beta.2", true, "0.1.0")] @@ -1153,20 +1159,20 @@ public void EnsurePreventIncrementWhenCurrentCommitTaggedOnDevelopWithNextVersio fixture.AssertFullSemver(semVersion, configuration); } - [TestCase(null, true, "6.0.0-beta.1+0")] - [TestCase(null, false, "6.0.0-beta.1+0")] + [TestCase(null, true, "6.0.0-beta.1+1")] + [TestCase(null, false, "6.0.0-beta.1+1")] [TestCase(new[] { "5.0.0" }, true, "5.0.0")] [TestCase(new[] { "5.0.0" }, false, "6.0.0-beta.1+0")] [TestCase(new[] { "6.0.0" }, true, "6.0.0")] [TestCase(new[] { "6.0.0" }, false, "6.1.0-beta.1+0")] [TestCase(new[] { "7.0.0" }, true, "7.0.0")] [TestCase(new[] { "7.0.0" }, false, "7.1.0-beta.1+0")] - [TestCase(new[] { "5.0.0-alpha.2" }, true, "6.0.0-beta.1+0")] - [TestCase(new[] { "5.0.0-alpha.2" }, false, "6.0.0-beta.1+0")] - [TestCase(new[] { "6.0.0-alpha.2" }, true, "6.0.0-beta.1+0")] - [TestCase(new[] { "6.0.0-alpha.2" }, false, "6.0.0-beta.1+0")] - [TestCase(new[] { "7.0.0-alpha.2" }, true, "7.0.0-beta.1+0")] - [TestCase(new[] { "7.0.0-alpha.2" }, false, "7.0.0-beta.1+0")] + [TestCase(new[] { "5.0.0-alpha.2" }, true, "6.0.0-beta.1+1")] + [TestCase(new[] { "5.0.0-alpha.2" }, false, "6.0.0-beta.1+1")] + [TestCase(new[] { "6.0.0-alpha.2" }, true, "6.0.0-beta.1+1")] + [TestCase(new[] { "6.0.0-alpha.2" }, false, "6.0.0-beta.1+1")] + [TestCase(new[] { "7.0.0-alpha.2" }, true, "7.0.0-beta.1+1")] + [TestCase(new[] { "7.0.0-alpha.2" }, false, "7.0.0-beta.1+1")] [TestCase(new[] { "5.0.0-beta.2" }, true, "5.0.0-beta.2")] [TestCase(new[] { "5.0.0-beta.2" }, false, "6.0.0-beta.1+0")] [TestCase(new[] { "6.0.0-beta.2" }, true, "6.0.0-beta.2")] @@ -1245,10 +1251,10 @@ public void EnsureVersionAfterMainIsMergedBackToDevelopIsCorrect() fixture.MergeNoFF("main"); // ✅ succeeds as expected - fixture.AssertFullSemver("1.1.0-alpha.7"); + fixture.AssertFullSemver("1.1.0-alpha.3"); } - [TestCase(false, "2.0.0-alpha.3")] + [TestCase(false, "2.0.0-alpha.2")] [TestCase(true, "2.0.0-alpha.2")] public void EnsureVersionAfterMainIsMergedBackToDevelopIsCorrectForTrunkBased(bool applyTag, string semanticVersion) { @@ -1301,4 +1307,61 @@ public void EnsureVersionAfterMainIsMergedBackToDevelopIsCorrectForGitFlow(bool // ✅ succeeds as expected fixture.AssertFullSemver(semanticVersion, configuration); } + + /// + /// see https://github.com/GitTools/GitVersion/issues/2394 + /// + [Test] + public void EnsureVersionSourceIsSetToTheRightTag() + { + // Arrange + var configuration = GitFlowConfigurationBuilder.New.Build(); + + // Act + using var fixture = new BaseGitFlowRepositoryFixture("0.1.0"); + + fixture.Checkout("main"); + fixture.MergeNoFF("develop"); + fixture.Checkout("develop"); + fixture.MakeACommit("Feature commit 1"); + fixture.BranchTo("release/0.2.0"); + fixture.MakeACommit("Release commit 1"); + fixture.Checkout("main"); + fixture.MergeNoFF("release/0.2.0"); + fixture.ApplyTag("0.2.0"); + var tag = fixture.Repository.Head.Tip; + fixture.Checkout("develop"); + fixture.MergeNoFF("main"); + var version = fixture.GetVersion(configuration); + + // Assert + version.VersionSourceSha.ShouldBe(tag.Sha); + } + + /// + /// see https://github.com/GitTools/GitVersion/issues/3689 + /// + [Test] + public void UnversionedHotfix() + { + var configuration = GitFlowConfigurationBuilder.New.Build(); + + using var fixture = new BaseGitFlowRepositoryFixture("1.2.0"); + + // create hotfix + Commands.Checkout(fixture.Repository, "main"); + Commands.Checkout(fixture.Repository, fixture.Repository.CreateBranch("hotfix/put-out-the-fire")); + fixture.Repository.MakeACommit(); + + fixture.AssertFullSemver("1.2.1-beta.1+1", configuration); + fixture.Repository.MakeACommit(); + fixture.AssertFullSemver("1.2.1-beta.1+2", configuration); + + // Merge hotfix branch to main + Commands.Checkout(fixture.Repository, "main"); + + fixture.Repository.MergeNoFF("hotfix/put-out-the-fire", Generate.SignatureNow()); + + fixture.AssertFullSemver("1.2.1-3", configuration); + } } diff --git a/src/GitVersion.Core.Tests/IntegrationTests/PullRequestScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/PullRequestScenarios.cs index 41656728e6..6754a39139 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/PullRequestScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/PullRequestScenarios.cs @@ -136,6 +136,6 @@ public void CalculatesCorrectVersionAfterReleaseBranchMergedToMain() fixture.Repository.CreatePullRequestRef("release/2.0.0", MainBranch, normalise: true); - fixture.AssertFullSemver("2.0.0-PullRequest2.3"); + fixture.AssertFullSemver("2.0.0-PullRequest2.4"); } } diff --git a/src/GitVersion.Core.Tests/IntegrationTests/ReleaseBranchScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/ReleaseBranchScenarios.cs index 315cfad80c..9a777ef127 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/ReleaseBranchScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/ReleaseBranchScenarios.cs @@ -44,11 +44,11 @@ public void NoMergeBacksToDevelopInCaseThereAreChangesInReleaseBranch() fixture.Checkout("develop"); fixture.AssertFullSemver("1.1.0-alpha.0"); fixture.Repository.MergeNoFF("release/1.0.0"); - fixture.AssertFullSemver("1.1.0-alpha.2"); + fixture.AssertFullSemver("1.1.0-alpha.1"); fixture.Repository.MakeACommit(); - fixture.AssertFullSemver("1.1.0-alpha.3"); + fixture.AssertFullSemver("1.1.0-alpha.2"); fixture.Repository.Branches.Remove("release/1.0.0"); - fixture.AssertFullSemver("1.1.0-alpha.3"); + fixture.AssertFullSemver("1.1.0-alpha.2"); } [Test] @@ -60,9 +60,9 @@ public void CanTakeVersionFromReleaseBranch() fixture.Repository.CreateBranch("release-2.0.0"); fixture.Checkout("release-2.0.0"); - fixture.AssertFullSemver("2.0.0-beta.1+0"); + fixture.AssertFullSemver("2.0.0-beta.1+5"); fixture.Repository.MakeCommits(2); - fixture.AssertFullSemver("2.0.0-beta.1+2"); + fixture.AssertFullSemver("2.0.0-beta.1+7"); } [Test] @@ -74,9 +74,9 @@ public void CanTakeVersionFromReleasesBranch() fixture.Repository.CreateBranch("releases/2.0.0"); fixture.Checkout("releases/2.0.0"); - fixture.AssertFullSemver("2.0.0-beta.1+0"); + fixture.AssertFullSemver("2.0.0-beta.1+5"); fixture.Repository.MakeCommits(2); - fixture.AssertFullSemver("2.0.0-beta.1+2"); + fixture.AssertFullSemver("2.0.0-beta.1+7"); } [Test] @@ -100,9 +100,9 @@ public void ReleaseBranchWithNextVersionSetInConfig() fixture.Repository.MakeCommits(5); fixture.BranchTo("release-2.0.0"); - fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); fixture.Repository.MakeCommits(2); - fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+7", configuration); } [Test] @@ -118,9 +118,9 @@ public void CanTakeVersionFromReleaseBranchWithLabelOverridden() fixture.Repository.CreateBranch("release-2.0.0"); fixture.Checkout("release-2.0.0"); - fixture.AssertFullSemver("2.0.0-rc.1+0", configuration); + fixture.AssertFullSemver("2.0.0-rc.1+5", configuration); fixture.Repository.MakeCommits(2); - fixture.AssertFullSemver("2.0.0-rc.1+2", configuration); + fixture.AssertFullSemver("2.0.0-rc.1+7", configuration); } [Test] @@ -133,9 +133,9 @@ public void CanHandleReleaseBranchWithStability() fixture.Repository.CreateBranch("release-2.0.0-Final"); fixture.Checkout("release-2.0.0-Final"); - fixture.AssertFullSemver("2.0.0-beta.1+0"); + fixture.AssertFullSemver("2.0.0-beta.1+5"); fixture.Repository.MakeCommits(2); - fixture.AssertFullSemver("2.0.0-beta.1+2"); + fixture.AssertFullSemver("2.0.0-beta.1+7"); } [Test] @@ -152,9 +152,9 @@ public void WhenReleaseBranchOffDevelopIsMergedIntoMainAndDevelopVersionIsTakenW fixture.Checkout(MainBranch); fixture.Repository.MergeNoFF("release-2.0.0", Generate.SignatureNow()); - fixture.AssertFullSemver("2.0.0-0"); + fixture.AssertFullSemver("2.0.0-6"); fixture.Repository.MakeCommits(2); - fixture.AssertFullSemver("2.0.0-2"); + fixture.AssertFullSemver("2.0.0-8"); } [Test] @@ -169,7 +169,7 @@ public void WhenReleaseBranchOffMainIsMergedIntoMainVersionIsTakenWithIt() fixture.Checkout(MainBranch); fixture.Repository.MergeNoFF("release-2.0.0", Generate.SignatureNow()); - fixture.AssertFullSemver("2.0.0-0"); + fixture.AssertFullSemver("2.0.0-6"); } [Test] @@ -184,9 +184,9 @@ public void MainVersioningContinuousCorrectlyAfterMergingReleaseBranch() fixture.Checkout(MainBranch); fixture.Repository.MergeNoFF("release-2.0.0", Generate.SignatureNow()); - fixture.AssertFullSemver("2.0.0-0"); + fixture.AssertFullSemver("2.0.0-6"); fixture.Repository.Branches.Remove("release-2.0.0"); - fixture.AssertFullSemver("2.0.0-0"); + fixture.AssertFullSemver("2.0.0-6"); fixture.Repository.ApplyTag("2.0.0"); fixture.Repository.MakeCommits(1); fixture.AssertFullSemver("2.0.1-1"); @@ -234,7 +234,7 @@ public void WhenReleaseBranchIsMergedIntoMainHighestVersionIsTakenWithIt() fixture.Checkout(MainBranch); fixture.Repository.MergeNoFF("release-1.0.0", Generate.SignatureNow()); - fixture.AssertFullSemver("2.0.0-5"); + fixture.AssertFullSemver("2.0.0-11"); } [Test] @@ -262,7 +262,7 @@ public void WhenReleaseBranchIsMergedIntoMainHighestVersionIsTakenWithItEvenWith fixture.Checkout(MainBranch); fixture.Repository.MergeNoFF("release-1.0.0", Generate.SignatureNow()); - fixture.AssertFullSemver("3.0.0-10"); + fixture.AssertFullSemver("3.0.0-16"); } [Test] @@ -281,7 +281,7 @@ public void WhenMergingReleaseBackToDevShouldNotResetBetaVersion() fixture.Checkout("release-2.0.0"); fixture.Repository.MakeCommits(1); - fixture.AssertFullSemver("2.0.0-beta.1+1"); + fixture.AssertFullSemver("2.0.0-beta.1+2"); //tag it to bump to beta 2 fixture.Repository.ApplyTag("2.0.0-beta1"); @@ -317,12 +317,12 @@ public void HotfixOffReleaseBranchShouldNotResetCount() fixture.Checkout("release-2.0.0"); fixture.Repository.MakeCommits(1); - fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); //tag it to bump to beta 2 fixture.Repository.MakeCommits(4); - fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+6", configuration); //merge down to develop fixture.Repository.CreateBranch("hotfix-2.0.0"); @@ -332,7 +332,7 @@ public void HotfixOffReleaseBranchShouldNotResetCount() fixture.Checkout("release-2.0.0"); fixture.Repository.MergeNoFF("hotfix-2.0.0", Generate.SignatureNow()); fixture.Repository.Branches.Remove(fixture.Repository.Branches["hotfix-2.0.0"]); - fixture.AssertFullSemver("2.0.0-beta.1+7", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+8", configuration); } [Test] @@ -354,14 +354,14 @@ public void MergeOnReleaseBranchShouldNotResetCount() fixture.Repository.CreateBranch("release/2.0.0-xxx"); fixture.Checkout("release/2.0.0-xxx"); fixture.Repository.MakeACommit(); - fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); fixture.Checkout("release/2.0.0"); fixture.Repository.MakeACommit(); - fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); fixture.Repository.MergeNoFF("release/2.0.0-xxx"); - fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); } [Test] @@ -375,12 +375,12 @@ public void CommitOnDevelopAfterReleaseBranchMergeToDevelopShouldNotResetCount() // Create release from develop fixture.BranchTo("release-2.0.0"); - fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); // Make some commits on release fixture.MakeACommit("release 1"); fixture.MakeACommit("release 2"); - fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); // First forward merge release to develop fixture.Checkout("develop"); @@ -389,24 +389,24 @@ public void CommitOnDevelopAfterReleaseBranchMergeToDevelopShouldNotResetCount() // Make some new commit on release fixture.Checkout("release-2.0.0"); fixture.Repository.MakeACommit("release 3 - after first merge"); - fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); // Make new commit on develop fixture.Checkout("develop"); // Checkout to release (no new commits) fixture.Checkout("release-2.0.0"); - fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); fixture.Checkout("develop"); fixture.Repository.MakeACommit("develop after merge"); // Checkout to release (no new commits) fixture.Checkout("release-2.0.0"); - fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); // Make some new commit on release fixture.Repository.MakeACommit("release 4"); fixture.Repository.MakeACommit("release 5"); - fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+6", configuration); // Second merge release to develop fixture.Checkout("develop"); @@ -414,7 +414,7 @@ public void CommitOnDevelopAfterReleaseBranchMergeToDevelopShouldNotResetCount() // Checkout to release (no new commits) fixture.Checkout("release-2.0.0"); - fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+6", configuration); } [Test] @@ -428,12 +428,12 @@ public void CommitBeetweenMergeReleaseToDevelopShouldNotResetCount() Commands.Checkout(fixture.Repository, "develop"); fixture.Repository.CreateBranch("release-2.0.0"); Commands.Checkout(fixture.Repository, "release-2.0.0"); - fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); // Make some commits on release var commit1 = fixture.Repository.MakeACommit(); fixture.Repository.MakeACommit(); - fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); // Merge release to develop - emulate commit between other person release commit push and this commit merge to develop Commands.Checkout(fixture.Repository, "develop"); @@ -442,12 +442,12 @@ public void CommitBeetweenMergeReleaseToDevelopShouldNotResetCount() // Check version on release after merge to develop Commands.Checkout(fixture.Repository, "release-2.0.0"); - fixture.AssertFullSemver("2.0.0-beta.1+2", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+3", configuration); // Check version on release after making some new commits fixture.Repository.MakeACommit(); fixture.Repository.MakeACommit(); - fixture.AssertFullSemver("2.0.0-beta.1+4", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+5", configuration); } [Test] @@ -505,11 +505,11 @@ public void FeatureFromReleaseBranchShouldNotResetCount() Commands.Checkout(fixture.Repository, "develop"); fixture.Repository.CreateBranch("release-2.0.0"); Commands.Checkout(fixture.Repository, "release-2.0.0"); - fixture.AssertFullSemver("2.0.0-beta.1+0", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+1", configuration); // Make some commits on release fixture.Repository.MakeCommits(10); - fixture.AssertFullSemver("2.0.0-beta.1+10", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+11", configuration); // Create feature from release fixture.BranchTo("feature/xxx"); @@ -518,9 +518,9 @@ public void FeatureFromReleaseBranchShouldNotResetCount() // Check version on release Commands.Checkout(fixture.Repository, "release-2.0.0"); - fixture.AssertFullSemver("2.0.0-beta.1+10", configuration); - fixture.Repository.MakeACommit("release 11"); fixture.AssertFullSemver("2.0.0-beta.1+11", configuration); + fixture.Repository.MakeACommit("release 11"); + fixture.AssertFullSemver("2.0.0-beta.1+12", configuration); // Make new commit on feature Commands.Checkout(fixture.Repository, "feature/xxx"); @@ -528,14 +528,14 @@ public void FeatureFromReleaseBranchShouldNotResetCount() // Checkout to release (no new commits) Commands.Checkout(fixture.Repository, "release-2.0.0"); - fixture.AssertFullSemver("2.0.0-beta.1+11", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+12", configuration); // Merge feature to release fixture.Repository.MergeNoFF("feature/xxx", Generate.SignatureNow()); - fixture.AssertFullSemver("2.0.0-beta.1+15", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+16", configuration); fixture.Repository.MakeACommit("release 13 - after feature merge"); - fixture.AssertFullSemver("2.0.0-beta.1+16", configuration); + fixture.AssertFullSemver("2.0.0-beta.1+17", configuration); } [Test] @@ -593,7 +593,7 @@ public void FeatureOnReleaseFeatureBranchDeleted() // begin the release branch fixture.Repository.CreateBranch(release450); Commands.Checkout(fixture.Repository, release450); - fixture.AssertFullSemver("4.5.0-beta.1+0", configuration); + fixture.AssertFullSemver("4.5.0-beta.1+1", configuration); fixture.Repository.CreateBranch(featureBranch); Commands.Checkout(fixture.Repository, featureBranch); @@ -602,7 +602,7 @@ public void FeatureOnReleaseFeatureBranchDeleted() fixture.Repository.MergeNoFF(featureBranch, Generate.SignatureNow()); // commit 2 fixture.Repository.Branches.Remove(featureBranch); - fixture.AssertFullSemver("4.5.0-beta.1+2", configuration); + fixture.AssertFullSemver("4.5.0-beta.1+3", configuration); } /// @@ -626,7 +626,7 @@ public void FeatureOnReleaseFeatureBranchNotDeleted() // begin the release branch fixture.Repository.CreateBranch(release450); Commands.Checkout(fixture.Repository, release450); - fixture.AssertFullSemver("4.5.0-beta.1+0", configuration); + fixture.AssertFullSemver("4.5.0-beta.1+1", configuration); fixture.Repository.CreateBranch(featureBranch); Commands.Checkout(fixture.Repository, featureBranch); @@ -634,7 +634,7 @@ public void FeatureOnReleaseFeatureBranchNotDeleted() Commands.Checkout(fixture.Repository, release450); fixture.Repository.MergeNoFF(featureBranch, Generate.SignatureNow()); // commit 2 - fixture.AssertFullSemver("4.5.0-beta.1+2", configuration); + fixture.AssertFullSemver("4.5.0-beta.1+3", configuration); } [TestCase("release/1.2.0", "1.2.0-beta.1+1", SemanticVersionFormat.Loose)] diff --git a/src/GitVersion.Core.Tests/IntegrationTests/RemoteRepositoryScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/RemoteRepositoryScenarios.cs index b41871e072..e81eb3c3a5 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/RemoteRepositoryScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/RemoteRepositoryScenarios.cs @@ -67,8 +67,8 @@ public void GivenARemoteGitRepositoryWithCommitsAndBranchesThenClonedLocalShould gitPreparer.Prepare(); - fixture.AssertFullSemver("1.0.0-beta.1+5"); - fixture.AssertFullSemver("1.0.0-beta.1+5", repository: fixture.LocalRepositoryFixture.Repository); + fixture.AssertFullSemver("1.0.0-beta.1+10"); + fixture.AssertFullSemver("1.0.0-beta.1+10", repository: fixture.LocalRepositoryFixture.Repository); } [Test] diff --git a/src/GitVersion.Core.Tests/IntegrationTests/SemVerOfAFeatureBranchStartedFromAReleaseBranchGetsDecrementedScenario.cs b/src/GitVersion.Core.Tests/IntegrationTests/SemVerOfAFeatureBranchStartedFromAReleaseBranchGetsDecrementedScenario.cs index 319acb8137..b150e366b6 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/SemVerOfAFeatureBranchStartedFromAReleaseBranchGetsDecrementedScenario.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/SemVerOfAFeatureBranchStartedFromAReleaseBranchGetsDecrementedScenario.cs @@ -19,13 +19,13 @@ public void ShouldPickUpReleaseVersionAfterCreatedFromRelease() fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.1.0-beta.1+1"); + fixture.AssertFullSemver("1.1.0-beta.1+2"); // Create a feature branch from the release/1.1.0 branch fixture.BranchTo("feature/test"); fixture.MakeACommit(); // ✅ succeeds as expected - fixture.AssertFullSemver("1.1.0-test.1+2"); + fixture.AssertFullSemver("1.1.0-test.1+3"); } } diff --git a/src/GitVersion.Core.Tests/IntegrationTests/SupportBranchScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/SupportBranchScenarios.cs index 49f8f2bf73..284077f656 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/SupportBranchScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/SupportBranchScenarios.cs @@ -38,13 +38,13 @@ public void SupportIsCalculatedCorrectly() // Create 1.2.0 release Commands.Checkout(fixture.Repository, "support/1.0.0"); fixture.Repository.MergeNoFF("release/1.2.0"); - fixture.AssertFullSemver("1.2.0-0"); + fixture.AssertFullSemver("1.2.0-2"); fixture.Repository.ApplyTag("1.2.0"); // Create 1.2.1 hotfix fixture.BranchTo("hotfix/1.2.1"); fixture.MakeACommit(); - fixture.AssertFullSemver("1.2.1-beta.1+3"); + fixture.AssertFullSemver("1.2.1-beta.1+1"); fixture.Checkout("support/1.0.0"); fixture.MergeNoFF("hotfix/1.2.1"); fixture.AssertFullSemver("1.2.1-2"); diff --git a/src/GitVersion.Core.Tests/IntegrationTests/VersionInCurrentBranchNameScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/VersionInCurrentBranchNameScenarios.cs index 1f544b7099..cf67eefaeb 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/VersionInCurrentBranchNameScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/VersionInCurrentBranchNameScenarios.cs @@ -13,7 +13,7 @@ public void TakesVersionFromNameOfReleaseBranch() using var fixture = new BaseGitFlowRepositoryFixture("1.0.0"); fixture.BranchTo("release/2.0.0"); - fixture.AssertFullSemver("2.0.0-beta.1+0"); + fixture.AssertFullSemver("2.0.0-beta.1+1"); } [Test] @@ -48,7 +48,7 @@ public void TakesVersionFromNameOfRemoteReleaseBranchInOrigin() fixture.LocalRepositoryFixture.Checkout("origin/release/2.0.0"); - fixture.LocalRepositoryFixture.AssertFullSemver("2.0.0-beta.1+1"); + fixture.LocalRepositoryFixture.AssertFullSemver("2.0.0-beta.1+6"); } [Test] diff --git a/src/GitVersion.Core.Tests/IntegrationTests/VersionInMergedBranchNameScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/VersionInMergedBranchNameScenarios.cs index f1cefe017a..77fd5129a2 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/VersionInMergedBranchNameScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/VersionInMergedBranchNameScenarios.cs @@ -64,7 +64,7 @@ public void TakesVersionFromNameOfRemoteReleaseBranchInOrigin() fixture.LocalRepositoryFixture.MergeNoFF("origin/release/2.0.0"); - fixture.LocalRepositoryFixture.AssertFullSemver("2.0.0-0"); + fixture.LocalRepositoryFixture.AssertFullSemver("2.0.0-7"); } [Test] diff --git a/src/GitVersion.Core.Tests/IntegrationTests/VersionInTagScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/VersionInTagScenarios.cs index d78735900c..f03603c417 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/VersionInTagScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/VersionInTagScenarios.cs @@ -58,7 +58,7 @@ public void TagPreReleaseWeightIsConfigured_GitFlowReleaseIsFinished_WeightedPre fixture.MakeACommit("Feature commit 1"); fixture.BranchTo("release/1.1.0"); fixture.MakeACommit("Release commit 1"); - fixture.AssertFullSemver("1.1.0-beta.1+1", configuration); + fixture.AssertFullSemver("1.1.0-beta.1+3", configuration); fixture.Checkout("main"); fixture.MergeNoFF("release/1.1.0"); @@ -85,7 +85,7 @@ public void TagPreReleaseWeightIsNotConfigured_GitFlowReleaseIsFinished_Weighted fixture.MakeACommit("Feature commit 1"); fixture.BranchTo("release/1.1.0"); fixture.MakeACommit("Release commit 1"); - fixture.AssertFullSemver("1.1.0-beta.1+1", configuration); + fixture.AssertFullSemver("1.1.0-beta.1+3", configuration); fixture.Checkout("main"); fixture.MergeNoFF("release/1.1.0"); diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitFlow+GivenADevelopBranchWithOneCommitMergedToMainWhenMergedCommitTaggedAsStable.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitFlow+GivenADevelopBranchWithOneCommitMergedToMainWhenMergedCommitTaggedAsStable.cs index b2b7c500a9..33fb2b9aef 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitFlow+GivenADevelopBranchWithOneCommitMergedToMainWhenMergedCommitTaggedAsStable.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitFlow+GivenADevelopBranchWithOneCommitMergedToMainWhenMergedCommitTaggedAsStable.cs @@ -68,25 +68,25 @@ public string GetVersionWithTrackMergeTargetOnDevelop(IncrementStrategy incremen return fixture!.GetVersion(trunkBased).FullSemVer; } - [TestCase(IncrementStrategy.None, IncrementStrategy.None, ExpectedResult = "0.0.0-alpha.1+2")] - [TestCase(IncrementStrategy.None, IncrementStrategy.Patch, ExpectedResult = "0.0.1-alpha.1+2")] - [TestCase(IncrementStrategy.None, IncrementStrategy.Minor, ExpectedResult = "0.1.0-alpha.1+2")] - [TestCase(IncrementStrategy.None, IncrementStrategy.Major, ExpectedResult = "1.0.0-alpha.1+2")] - - [TestCase(IncrementStrategy.Patch, IncrementStrategy.None, ExpectedResult = "0.0.0-alpha.1+2")] - [TestCase(IncrementStrategy.Patch, IncrementStrategy.Patch, ExpectedResult = "0.0.1-alpha.1+2")] - [TestCase(IncrementStrategy.Patch, IncrementStrategy.Minor, ExpectedResult = "0.1.0-alpha.1+2")] - [TestCase(IncrementStrategy.Patch, IncrementStrategy.Major, ExpectedResult = "1.0.0-alpha.1+2")] - - [TestCase(IncrementStrategy.Minor, IncrementStrategy.None, ExpectedResult = "0.0.0-alpha.1+2")] - [TestCase(IncrementStrategy.Minor, IncrementStrategy.Patch, ExpectedResult = "0.0.1-alpha.1+2")] - [TestCase(IncrementStrategy.Minor, IncrementStrategy.Minor, ExpectedResult = "0.1.0-alpha.1+2")] - [TestCase(IncrementStrategy.Minor, IncrementStrategy.Major, ExpectedResult = "1.0.0-alpha.1+2")] - - [TestCase(IncrementStrategy.Major, IncrementStrategy.None, ExpectedResult = "0.0.0-alpha.1+2")] - [TestCase(IncrementStrategy.Major, IncrementStrategy.Patch, ExpectedResult = "0.0.1-alpha.1+2")] - [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, ExpectedResult = "0.1.0-alpha.1+2")] - [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, ExpectedResult = "1.0.0-alpha.1+2")] + [TestCase(IncrementStrategy.None, IncrementStrategy.None, ExpectedResult = "0.0.0-alpha.1+1")] + [TestCase(IncrementStrategy.None, IncrementStrategy.Patch, ExpectedResult = "0.0.1-alpha.1+1")] + [TestCase(IncrementStrategy.None, IncrementStrategy.Minor, ExpectedResult = "0.1.0-alpha.1+1")] + [TestCase(IncrementStrategy.None, IncrementStrategy.Major, ExpectedResult = "1.0.0-alpha.1+1")] + + [TestCase(IncrementStrategy.Patch, IncrementStrategy.None, ExpectedResult = "0.0.1-alpha.1+1")] + [TestCase(IncrementStrategy.Patch, IncrementStrategy.Patch, ExpectedResult = "0.0.2-alpha.1+1")] + [TestCase(IncrementStrategy.Patch, IncrementStrategy.Minor, ExpectedResult = "0.1.0-alpha.1+1")] + [TestCase(IncrementStrategy.Patch, IncrementStrategy.Major, ExpectedResult = "1.0.0-alpha.1+1")] + + [TestCase(IncrementStrategy.Minor, IncrementStrategy.None, ExpectedResult = "0.1.0-alpha.1+1")] + [TestCase(IncrementStrategy.Minor, IncrementStrategy.Patch, ExpectedResult = "0.1.1-alpha.1+1")] + [TestCase(IncrementStrategy.Minor, IncrementStrategy.Minor, ExpectedResult = "0.2.0-alpha.1+1")] + [TestCase(IncrementStrategy.Minor, IncrementStrategy.Major, ExpectedResult = "1.0.0-alpha.1+1")] + + [TestCase(IncrementStrategy.Major, IncrementStrategy.None, ExpectedResult = "1.0.0-alpha.1+1")] + [TestCase(IncrementStrategy.Major, IncrementStrategy.Patch, ExpectedResult = "1.0.1-alpha.1+1")] + [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, ExpectedResult = "1.1.0-alpha.1+1")] + [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, ExpectedResult = "2.0.0-alpha.1+1")] public string GetVersionWithNoTrackMergeTargetOnDevelop(IncrementStrategy incrementOnMain, IncrementStrategy increment) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithAMergeCommitFromMainMergedBackToMainWhen.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithAMergeCommitFromMainMergedBackToMainWhen.cs index 6445d464cc..d5459cdbbf 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithAMergeCommitFromMainMergedBackToMainWhen.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithAMergeCommitFromMainMergedBackToMainWhen.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithAMergeCommitFromMainMergedBackToMainWhen private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New.WithLabel(null) .WithVersionStrategy(VersionStrategies.TrunkBased) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithAMergeCommitFromMainWhen.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithAMergeCommitFromMainWhen.cs index 8a794e8616..30f8101bd8 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithAMergeCommitFromMainWhen.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithAMergeCommitFromMainWhen.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithAMergeCommitFromMainWhen private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New.WithLabel(null) .WithVersionStrategy(VersionStrategies.TrunkBased) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhen.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhen.cs index 99346fb127..e96310cd18 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhen.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhen.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhen private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpMessageMajor.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpMessageMajor.cs index 79613c831f..193cc5aed3 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpMessageMajor.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpMessageMajor.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpM private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpMessageMinor.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpMessageMinor.cs index 356e1c3021..aaeaa2b476 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpMessageMinor.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpMessageMinor.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpM private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpMessagePatch.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpMessagePatch.cs index c23a133f91..969aaed852 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpMessagePatch.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpMessagePatch.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitAHasBumpM private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsPreRelease.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsPreRelease.cs index db029d830d..62e32e28ff 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsPreRelease.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsPreRelease.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAs private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsPreReleaseBar.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsPreReleaseBar.cs index 2197f87b0b..7236aacf6d 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsPreReleaseBar.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsPreReleaseBar.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAs private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsPreReleaseFoo.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsPreReleaseFoo.cs index ea7747aa59..f650c0a6cc 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsPreReleaseFoo.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsPreReleaseFoo.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAs private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsStable.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsStable.cs index 9f3fd4fca8..0c92efc643 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsStable.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAsStable.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitATaggedAs private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpMessageMajor.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpMessageMajor.cs index a43ab72ee2..009b6215d1 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpMessageMajor.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpMessageMajor.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpM private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpMessageMinor.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpMessageMinor.cs index c097da8bf1..14d9c2ccdd 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpMessageMinor.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpMessageMinor.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpM private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpMessagePatch.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpMessagePatch.cs index 7e03c0029a..5f0767ae1a 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpMessagePatch.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpMessagePatch.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBHasBumpM private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsPreRelease.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsPreRelease.cs index b0dc36582c..6013c955d6 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsPreRelease.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsPreRelease.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAs private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsPreReleaseBar.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsPreReleaseBar.cs index cf6bf5def1..138761ab33 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsPreReleaseBar.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsPreReleaseBar.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAs private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsPreReleaseFoo.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsPreReleaseFoo.cs index 88f4b0c92e..39f9620be2 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsPreReleaseFoo.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsPreReleaseFoo.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAs private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsStable.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsStable.cs index 12ea448041..88ff5cce5f 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsStable.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAsStable.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitBranchedFromMainWhenCommitBTaggedAs private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() @@ -231,13 +233,12 @@ public string GetVersionWithNoLabelOnMain( [TestCase(IncrementStrategy.Major, IncrementStrategy.Patch, "{BranchName}", ExpectedResult = "0.0.1-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "0.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] - public string GetVersionWithNoLabelAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithNoLabelOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel(null)) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -440,13 +441,12 @@ public string GetVersionWithEmptyLabelOnMain( [TestCase(IncrementStrategy.Major, IncrementStrategy.Patch, "{BranchName}", ExpectedResult = "0.0.1-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "0.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] - public string GetVersionWithEmptyLabelAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithEmptyLabelOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel(string.Empty)) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -649,13 +649,12 @@ public string GetVersionWithLabelFooOnMain( [TestCase(IncrementStrategy.Major, IncrementStrategy.Patch, "{BranchName}", ExpectedResult = "0.0.1-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "0.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] - public string GetVersionWithLabelFooAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithLabelFooOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel("foo")) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -858,13 +857,12 @@ public string GetVersionWithLabelBarOnMain( [TestCase(IncrementStrategy.Major, IncrementStrategy.Patch, "{BranchName}", ExpectedResult = "0.0.1-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "0.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] - public string GetVersionWithLabelBarAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithLabelBarOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel("bar")) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhen.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhen.cs index 8b7808d63f..9b6b561af9 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhen.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhen.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitMergedToMainWhen private static GitFlowConfigurationBuilder TrunkBasedBuilder => GitFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreRelease.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreRelease.cs index d7c028d45c..92fbe59dc1 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreRelease.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreRelease.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreR private static GitFlowConfigurationBuilder TrunkBasedBuilder => GitFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreReleaseBar.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreReleaseBar.cs index 8711eaea64..20c386ca0c 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreReleaseBar.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreReleaseBar.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreR private static GitFlowConfigurationBuilder TrunkBasedBuilder => GitFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreReleaseFoo.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreReleaseFoo.cs index 8ccdca3a5c..1527f08305 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreReleaseFoo.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreReleaseFoo.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsPreR private static GitFlowConfigurationBuilder TrunkBasedBuilder => GitFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsStable.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsStable.cs index 318456a731..5a353777d3 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsStable.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsStable.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitMergedToMainWhenCommitBTaggedAsStab private static GitFlowConfigurationBuilder TrunkBasedBuilder => GitFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWithOneCommitBranchedToFeatureWhen.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWithOneCommitBranchedToFeatureWhen.cs index d66ed5eea3..f229797b48 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWithOneCommitBranchedToFeatureWhen.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitMergedToMainWithOneCommitBranchedToFeatureWhen.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithOneCommitMergedToMainWithOneCommitBranchedTo private static GitFlowConfigurationBuilder TrunkBasedBuilder => GitFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhen.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhen.cs index d1b5c57edc..8f8ef2bbfc 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhen.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhen.cs @@ -14,7 +14,7 @@ public class GivenAFeatureBranchWithOneCommitWhen private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessageMajor.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessageMajor.cs index c6ba38b315..d12165d239 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessageMajor.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessageMajor.cs @@ -14,7 +14,7 @@ public class GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessageMajor private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessageMinor.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessageMinor.cs index aad3baade1..3f84dc2f66 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessageMinor.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessageMinor.cs @@ -14,7 +14,7 @@ public class GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessageMinor private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessagePatch.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessagePatch.cs index 79badbe5df..9a876cf5f0 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessagePatch.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessagePatch.cs @@ -14,7 +14,7 @@ public class GivenAFeatureBranchWithOneCommitWhenCommitHasBumpMessagePatch private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreRelease.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreRelease.cs index 4040ad96dd..9842379241 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreRelease.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreRelease.cs @@ -14,7 +14,9 @@ public class GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreRelease private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() @@ -80,8 +82,7 @@ public string GetVersion(IncrementStrategy increment, string? label) public string GetVersionWithPreventIncrementWhenCurrentCommitTaggedFalse(IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreReleaseBar.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreReleaseBar.cs index 156234a55a..5abbaf3580 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreReleaseBar.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreReleaseBar.cs @@ -14,7 +14,9 @@ public class GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreReleaseBar private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() @@ -80,8 +82,7 @@ public string GetVersion(IncrementStrategy increment, string? label) public string GetVersionWithPreventIncrementWhenCurrentCommitTaggedFalse(IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreReleaseFoo.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreReleaseFoo.cs index ea3a375d5f..9fae774544 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreReleaseFoo.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreReleaseFoo.cs @@ -14,7 +14,9 @@ public class GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsPreReleaseFoo private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() @@ -80,8 +82,7 @@ public string GetVersion(IncrementStrategy increment, string? label) public string GetVersionWithPreventIncrementWhenCurrentCommitTaggedFalse(IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsStable.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsStable.cs index a75ab7755e..fb3d3dac19 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsStable.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsStable.cs @@ -14,7 +14,9 @@ public class GivenAFeatureBranchWithOneCommitWhenCommitTaggedAsStable private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() @@ -80,8 +82,7 @@ public string GetVersion(IncrementStrategy increment, string? label) public string GetVersionWithPreventIncrementWhenCurrentCommitTaggedFalse(IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithThreeCommitsBranchedFromMainWhen.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithThreeCommitsBranchedFromMainWhen.cs index fad5196b3a..67b15775fa 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithThreeCommitsBranchedFromMainWhen.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithThreeCommitsBranchedFromMainWhen.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithThreeCommitsBranchedFromMainWhen private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithThreeCommitsMergedToMainWhen.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithThreeCommitsMergedToMainWhen.cs index 18060a587a..772986b48c 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithThreeCommitsMergedToMainWhen.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithThreeCommitsMergedToMainWhen.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithThreeCommitsMergedToMainWhen private static GitFlowConfigurationBuilder TrunkBasedBuilder => GitFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithThreeCommitsWhen.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithThreeCommitsWhen.cs index 27ba0c4a96..97c751018b 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithThreeCommitsWhen.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithThreeCommitsWhen.cs @@ -14,7 +14,9 @@ public class GivenAFeatureBranchWithThreeCommitsWhen private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsBranchedFromMainWhen.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsBranchedFromMainWhen.cs index d734f91b1b..c0b100c769 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsBranchedFromMainWhen.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsBranchedFromMainWhen.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithTwoCommitsBranchedFromMainWhen private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsMergedToMainWhen.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsMergedToMainWhen.cs index 96ff7c1d99..101414163d 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsMergedToMainWhen.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsMergedToMainWhen.cs @@ -15,7 +15,9 @@ public class GivenAFeatureBranchWithTwoCommitsMergedToMainWhen private static GitFlowConfigurationBuilder TrunkBasedBuilder => GitFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreRelease.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreRelease.cs index 5ca91c660d..b8bea24527 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreRelease.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreRelease.cs @@ -14,7 +14,9 @@ public class GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreRelease private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreReleaseBar.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreReleaseBar.cs index 9712a5cc7e..50ccd86281 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreReleaseBar.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreReleaseBar.cs @@ -14,7 +14,9 @@ public class GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreReleaseB private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreReleaseFoo.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreReleaseFoo.cs index 8001fbe161..67d7c20c26 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreReleaseFoo.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreReleaseFoo.cs @@ -14,7 +14,9 @@ public class GivenAFeatureBranchWithTwoCommitsWhenFirstCommitTaggedAsPreReleaseF private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhen.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhen.cs index dd13044296..89bf9b3e06 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhen.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhen.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithOneCommitBranchedToFeatureWhen private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMessageMajor.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMessageMajor.cs index 342e335655..d8156e59d0 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMessageMajor.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMessageMajor.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMess private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMessageMinor.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMessageMinor.cs index a8bc27b841..4019639f51 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMessageMinor.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMessageMinor.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMess private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMessagePatch.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMessagePatch.cs index 1b53dcd4e1..62e5d6ff53 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMessagePatch.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMessagePatch.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitHasBumpMess private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPreRelease.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPreRelease.cs index cf22d83b58..a50c1a162b 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPreRelease.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPreRelease.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPre private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() @@ -248,13 +250,12 @@ public string GetVersionWithNoLabelOnMain(IncrementStrategy incrementOnMain, Inc [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "1.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] - public string GetVersionWithNoLabelAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithNoLabelOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel(null)) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -476,13 +477,12 @@ public string GetVersionWithEmptyLabelOnMain(IncrementStrategy incrementOnMain, [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "1.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] - public string GetVersionWithEmptyLabelAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithEmptyLabelOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel(string.Empty)) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -704,13 +704,12 @@ public string GetVersionWithLabelFooOnMain(IncrementStrategy incrementOnMain, In [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "1.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] - public string GetVersionWithLabelFooAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithLabelFooOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel("foo")) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -932,13 +931,12 @@ public string GetVersionWithLabelBarOnMain(IncrementStrategy incrementOnMain, In [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "1.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] - public string GetVersionWithLabelBarAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithLabelBarOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel("bar")) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPreReleaseBar.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPreReleaseBar.cs index d6b5e15637..25b6ad9987 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPreReleaseBar.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPreReleaseBar.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPre private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() @@ -248,13 +250,12 @@ public string GetVersionWithNoLabelOnMain(IncrementStrategy incrementOnMain, Inc [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "1.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] - public string GetVersionWithNoLabelAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithNoLabelOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel(null)) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -476,13 +477,12 @@ public string GetVersionWithEmptyLabelOnMain(IncrementStrategy incrementOnMain, [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "1.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] - public string GetVersionWithEmptyLabelAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithEmptyLabelOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel(string.Empty)) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -704,13 +704,12 @@ public string GetVersionWithLabelFooOnMain(IncrementStrategy incrementOnMain, In [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "1.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] - public string GetVersionWithLabelFooAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithLabelFooOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel("foo")) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -932,13 +931,12 @@ public string GetVersionWithLabelBarOnMain(IncrementStrategy incrementOnMain, In [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "1.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "2.0.0-foo.1+0")] - public string GetVersionWithLabelBarAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithLabelBarOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel("bar")) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPreReleaseFoo.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPreReleaseFoo.cs index 883c900658..f663364bc2 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPreReleaseFoo.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPreReleaseFoo.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsPre private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() @@ -248,13 +250,12 @@ public string GetVersionWithNoLabelOnMain(IncrementStrategy incrementOnMain, Inc [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "0.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] - public string GetVersionWithNoLabelAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithNoLabelOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel(null)) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -476,13 +477,12 @@ public string GetVersionWithEmptyLabelOnMain(IncrementStrategy incrementOnMain, [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "0.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] - public string GetVersionWithEmptyLabelAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithEmptyLabelOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel(string.Empty)) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -704,13 +704,12 @@ public string GetVersionWithLabelFooOnMain(IncrementStrategy incrementOnMain, In [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "0.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] - public string GetVersionWithLabelFooAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithLabelFooOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel("foo")) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -932,13 +931,12 @@ public string GetVersionWithLabelBarOnMain(IncrementStrategy incrementOnMain, In [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "0.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] - public string GetVersionWithLabelBarAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithLabelBarOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel("bar")) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsStable.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsStable.cs index a46910e703..ecef9b1c3d 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsStable.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsStable.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithOneCommitBranchedToFeatureWhenCommitTaggedAsSta private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() @@ -248,13 +250,12 @@ public string GetVersionWithNoLabelOnMain(IncrementStrategy incrementOnMain, Inc [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "0.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] - public string GetVersionWithNoLabelAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithNoLabelOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel(null)) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -476,13 +477,12 @@ public string GetVersionWithEmptyLabelOnMain(IncrementStrategy incrementOnMain, [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "0.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] - public string GetVersionWithEmptyLabelAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithEmptyLabelOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel(string.Empty)) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -704,13 +704,12 @@ public string GetVersionWithLabelFooOnMain(IncrementStrategy incrementOnMain, In [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "0.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] - public string GetVersionWithLabelFooAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithLabelFooOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel("foo")) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; @@ -932,13 +931,12 @@ public string GetVersionWithLabelBarOnMain(IncrementStrategy incrementOnMain, In [TestCase(IncrementStrategy.Major, IncrementStrategy.Minor, "{BranchName}", ExpectedResult = "0.1.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Major, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] [TestCase(IncrementStrategy.Major, IncrementStrategy.Inherit, "{BranchName}", ExpectedResult = "1.0.0-foo.1+0")] - public string GetVersionWithLabelBarAndPreventIncrementWhenCurrentCommitTaggedFalseOnMain( + public string GetVersionWithLabelBarOnMainAndPreventIncrementWhenCurrentCommitTaggedFalseOnFeature( IncrementStrategy incrementOnMain, IncrementStrategy increment, string? label) { IGitVersionConfiguration trunkBased = TrunkBasedBuilder - .WithPreventIncrementWhenCurrentCommitTagged(false) .WithBranch("main", _ => _.WithIncrement(incrementOnMain).WithLabel("bar")) - .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label)) + .WithBranch("feature", _ => _.WithIncrement(increment).WithLabel(label).WithPreventIncrementWhenCurrentCommitTagged(false)) .Build(); return fixture!.GetVersion(trunkBased).FullSemVer; diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhen.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhen.cs index 47f2826def..daa7518428 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhen.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhen.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithTwoCommitsBranchedToFeatureWhen private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBumpMessageMajor.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBumpMessageMajor.cs index cae332c393..f00c2d00ee 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBumpMessageMajor.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBumpMessageMajor.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBu private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBumpMessageMinor.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBumpMessageMinor.cs index 5e13f68ce1..53ddc84c9e 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBumpMessageMinor.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBumpMessageMinor.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBu private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBumpMessagePatch.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBumpMessagePatch.cs index 6c806e5549..44eb2c83a2 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBumpMessagePatch.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBumpMessagePatch.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitHasBu private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsPreRelease.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsPreRelease.cs index de3cb67f98..47ce985b4f 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsPreRelease.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsPreRelease.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTagge private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsPreReleaseBar.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsPreReleaseBar.cs index cf89dbbf1f..5077a32f32 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsPreReleaseBar.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsPreReleaseBar.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTagge private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsPreReleaseFoo.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsPreReleaseFoo.cs index 21aa63002b..c398abf1be 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsPreReleaseFoo.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsPreReleaseFoo.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTagge private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsStable.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsStable.cs index 92fb7f6e77..5f93545dc7 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsStable.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTaggedAsStable.cs @@ -15,7 +15,9 @@ public class GivenAMainBranchWithTwoCommitsBranchedToFeatureWhenFirstCommitTagge private static GitHubFlowConfigurationBuilder TrunkBasedBuilder => GitHubFlowConfigurationBuilder.New .WithVersionStrategy(VersionStrategies.TrunkBased).WithLabel(null) .WithBranch("main", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment)) - .WithBranch("feature", _ => _.WithDeploymentMode(DeploymentMode.ManualDeployment).WithIsMainBranch(false)); + .WithBranch("feature", _ => _ + .WithDeploymentMode(DeploymentMode.ManualDeployment).WithPreventIncrementWhenCurrentCommitTagged(true) + ); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsWhenSecondCommitTaggedAsPreRelease.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsWhenSecondCommitTaggedAsPreRelease.cs index 6db3b80029..5aa0122b0c 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsWhenSecondCommitTaggedAsPreRelease.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsWhenSecondCommitTaggedAsPreRelease.cs @@ -42,12 +42,12 @@ public void OneTimeSetUp() [TestCase(IncrementStrategy.Minor, "", ExpectedResult = "0.2.0-4")] [TestCase(IncrementStrategy.Major, "", ExpectedResult = "0.2.0-4")] - [TestCase(IncrementStrategy.None, "foo", ExpectedResult = "0.2.0-foo.2+1")] + [TestCase(IncrementStrategy.None, "foo", ExpectedResult = "0.2.0-foo.1+1")] [TestCase(IncrementStrategy.Patch, "foo", ExpectedResult = "0.2.0-foo.1+1")] [TestCase(IncrementStrategy.Minor, "foo", ExpectedResult = "0.2.0-foo.1+1")] [TestCase(IncrementStrategy.Major, "foo", ExpectedResult = "2.0.0-foo.1+1")] - [TestCase(IncrementStrategy.None, "bar", ExpectedResult = "0.2.0-bar.2+1")] + [TestCase(IncrementStrategy.None, "bar", ExpectedResult = "0.2.0-bar.1+1")] [TestCase(IncrementStrategy.Patch, "bar", ExpectedResult = "0.2.0-bar.1+1")] [TestCase(IncrementStrategy.Minor, "bar", ExpectedResult = "0.2.0-bar.1+1")] [TestCase(IncrementStrategy.Major, "bar", ExpectedResult = "2.0.0-bar.1+1")] diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsWhenSecondCommitTaggedAsPreReleaseBar.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsWhenSecondCommitTaggedAsPreReleaseBar.cs index d561e33b67..15e7652db3 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsWhenSecondCommitTaggedAsPreReleaseBar.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsWhenSecondCommitTaggedAsPreReleaseBar.cs @@ -37,12 +37,12 @@ public void OneTimeSetUp() [TestCase(IncrementStrategy.Minor, null, ExpectedResult = "0.2.0-bar")] [TestCase(IncrementStrategy.Major, null, ExpectedResult = "0.2.0-bar")] - [TestCase(IncrementStrategy.None, "", ExpectedResult = "0.2.0-2+1")] + [TestCase(IncrementStrategy.None, "", ExpectedResult = "0.2.0-1+1")] [TestCase(IncrementStrategy.Patch, "", ExpectedResult = "0.2.0-1+1")] [TestCase(IncrementStrategy.Minor, "", ExpectedResult = "0.2.0-1+1")] [TestCase(IncrementStrategy.Major, "", ExpectedResult = "2.0.0-1+1")] - [TestCase(IncrementStrategy.None, "foo", ExpectedResult = "0.2.0-foo.2+1")] + [TestCase(IncrementStrategy.None, "foo", ExpectedResult = "0.2.0-foo.1+1")] [TestCase(IncrementStrategy.Patch, "foo", ExpectedResult = "0.2.0-foo.1+1")] [TestCase(IncrementStrategy.Minor, "foo", ExpectedResult = "0.2.0-foo.1+1")] [TestCase(IncrementStrategy.Major, "foo", ExpectedResult = "2.0.0-foo.1+1")] diff --git a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsWhenSecondCommitTaggedAsPreReleaseFoo.cs b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsWhenSecondCommitTaggedAsPreReleaseFoo.cs index 13e4d8f0fb..be2b625fb9 100644 --- a/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsWhenSecondCommitTaggedAsPreReleaseFoo.cs +++ b/src/GitVersion.Core.Tests/TrunkBased/TrunkBasedScenariosWithAGitHubFlow+GivenAMainBranchWithTwoCommitsWhenSecondCommitTaggedAsPreReleaseFoo.cs @@ -37,7 +37,7 @@ public void OneTimeSetUp() [TestCase(IncrementStrategy.Minor, null, ExpectedResult = "0.2.0-foo.4")] [TestCase(IncrementStrategy.Major, null, ExpectedResult = "0.2.0-foo.4")] - [TestCase(IncrementStrategy.None, "", ExpectedResult = "0.2.0-2+1")] + [TestCase(IncrementStrategy.None, "", ExpectedResult = "0.2.0-1+1")] [TestCase(IncrementStrategy.Patch, "", ExpectedResult = "0.2.0-1+1")] [TestCase(IncrementStrategy.Minor, "", ExpectedResult = "0.2.0-1+1")] [TestCase(IncrementStrategy.Major, "", ExpectedResult = "2.0.0-1+1")] @@ -47,7 +47,7 @@ public void OneTimeSetUp() [TestCase(IncrementStrategy.Minor, "foo", ExpectedResult = "0.2.0-foo.4")] [TestCase(IncrementStrategy.Major, "foo", ExpectedResult = "0.2.0-foo.4")] - [TestCase(IncrementStrategy.None, "bar", ExpectedResult = "0.2.0-bar.2+1")] + [TestCase(IncrementStrategy.None, "bar", ExpectedResult = "0.2.0-bar.1+1")] [TestCase(IncrementStrategy.Patch, "bar", ExpectedResult = "0.2.0-bar.1+1")] [TestCase(IncrementStrategy.Minor, "bar", ExpectedResult = "0.2.0-bar.1+1")] [TestCase(IncrementStrategy.Major, "bar", ExpectedResult = "2.0.0-bar.1+1")] diff --git a/src/GitVersion.Core/Configuration/EffectiveConfiguration.cs b/src/GitVersion.Core/Configuration/EffectiveConfiguration.cs index 9505fb4383..9708f95329 100644 --- a/src/GitVersion.Core/Configuration/EffectiveConfiguration.cs +++ b/src/GitVersion.Core/Configuration/EffectiveConfiguration.cs @@ -10,13 +10,21 @@ namespace GitVersion.Configuration; /// public record EffectiveConfiguration { - public EffectiveConfiguration(IGitVersionConfiguration configuration, IBranchConfiguration branchConfiguration) + public EffectiveConfiguration(IGitVersionConfiguration configuration, IBranchConfiguration branchConfiguration, + EffectiveConfiguration? fallbackConfiguration = null) { configuration.NotNull(); branchConfiguration.NotNull(); - var fallbackBranchConfiguration = configuration.GetFallbackBranchConfiguration(); - branchConfiguration = branchConfiguration.Inherit(fallbackBranchConfiguration); + if (fallbackConfiguration is null) + { + var fallbackBranchConfiguration = configuration.GetFallbackBranchConfiguration(); + branchConfiguration = branchConfiguration.Inherit(fallbackBranchConfiguration); + } + else + { + branchConfiguration = branchConfiguration.Inherit(fallbackConfiguration); + } if (!branchConfiguration.DeploymentMode.HasValue) throw new("Configuration value for 'Deployment mode' has no value. (this should not happen, please report an issue)"); diff --git a/src/GitVersion.Core/Configuration/IBranchConfiguration.cs b/src/GitVersion.Core/Configuration/IBranchConfiguration.cs index 0d1bb62da8..52d05a612f 100644 --- a/src/GitVersion.Core/Configuration/IBranchConfiguration.cs +++ b/src/GitVersion.Core/Configuration/IBranchConfiguration.cs @@ -26,6 +26,10 @@ public interface IBranchConfiguration public bool IsMatch(string branchName) => RegularExpression != null && Regex.IsMatch(branchName, RegularExpression, RegexOptions.IgnoreCase); + IReadOnlyCollection SourceBranches { get; } + + IReadOnlyCollection IsSourceBranchFor { get; } + bool? TracksReleaseBranches { get; } bool? IsReleaseBranch { get; } @@ -34,9 +38,7 @@ public bool IsMatch(string branchName) int? PreReleaseWeight { get; } - IReadOnlyCollection SourceBranches { get; } - - IReadOnlyCollection IsSourceBranchFor { get; } - IBranchConfiguration Inherit(IBranchConfiguration configuration); + + IBranchConfiguration Inherit(EffectiveConfiguration configuration); } diff --git a/src/GitVersion.Core/Configuration/ReferenceNameExtensions.cs b/src/GitVersion.Core/Configuration/ReferenceNameExtensions.cs new file mode 100644 index 0000000000..6930689188 --- /dev/null +++ b/src/GitVersion.Core/Configuration/ReferenceNameExtensions.cs @@ -0,0 +1,15 @@ +using System.Diagnostics.CodeAnalysis; +using GitVersion.Git; + +namespace GitVersion.Configuration; + +public static class ReferenceNameExtensions +{ + public static bool TryGetSemanticVersion( + this ReferenceName source, [NotNullWhen(true)] out (SemanticVersion Value, string? Name) result, IGitVersionConfiguration configuration) + => source.TryGetSemanticVersion(out result, configuration.VersionInBranchRegex, configuration.TagPrefix, configuration.SemanticVersionFormat); + + public static bool TryGetSemanticVersion( + this ReferenceName source, [NotNullWhen(true)] out (SemanticVersion Value, string? Name) result, EffectiveConfiguration configuration) + => source.TryGetSemanticVersion(out result, configuration.VersionInBranchRegex, configuration.TagPrefix, configuration.SemanticVersionFormat); +} diff --git a/src/GitVersion.Core/Extensions/ConfigurationExtensions.cs b/src/GitVersion.Core/Extensions/ConfigurationExtensions.cs index 9c5bb4ffec..f580c31840 100644 --- a/src/GitVersion.Core/Extensions/ConfigurationExtensions.cs +++ b/src/GitVersion.Core/Extensions/ConfigurationExtensions.cs @@ -8,16 +8,23 @@ namespace GitVersion.Configuration; internal static class ConfigurationExtensions { - public static EffectiveBranchConfiguration GetEffectiveBranchConfiguration(this IGitVersionConfiguration configuration, IBranch branch) + public static EffectiveBranchConfiguration GetEffectiveBranchConfiguration( + this IGitVersionConfiguration configuration, IBranch branch, EffectiveConfiguration? parentConfiguration = null) { - var effectiveConfiguration = GetEffectiveConfiguration(configuration, branch.Name); - return new(effectiveConfiguration, branch); + var effectiveConfiguration = GetEffectiveConfiguration(configuration, branch.Name, parentConfiguration); + return new EffectiveBranchConfiguration(effectiveConfiguration, branch); } - public static EffectiveConfiguration GetEffectiveConfiguration(this IGitVersionConfiguration configuration, ReferenceName branchName) + public static EffectiveConfiguration GetEffectiveConfiguration( + this IGitVersionConfiguration configuration, ReferenceName branchName, EffectiveConfiguration? parentConfiguration = null) { var branchConfiguration = configuration.GetBranchConfiguration(branchName); - return new(configuration, branchConfiguration); + EffectiveConfiguration? fallbackConfiguration = null; + if (branchConfiguration.Increment == IncrementStrategy.Inherit) + { + fallbackConfiguration = parentConfiguration; + } + return new EffectiveConfiguration(configuration, branchConfiguration, fallbackConfiguration); } public static IBranchConfiguration GetBranchConfiguration(this IGitVersionConfiguration configuration, IBranch branch) diff --git a/src/GitVersion.Core/PublicAPI.Unshipped.txt b/src/GitVersion.Core/PublicAPI.Unshipped.txt index b5b8f6ba18..b4d09ebd0f 100644 --- a/src/GitVersion.Core/PublicAPI.Unshipped.txt +++ b/src/GitVersion.Core/PublicAPI.Unshipped.txt @@ -61,7 +61,7 @@ GitVersion.Configuration.EffectiveConfiguration.AssemblyInformationalFormat.get GitVersion.Configuration.EffectiveConfiguration.AssemblyVersioningFormat.get -> string? GitVersion.Configuration.EffectiveConfiguration.AssemblyVersioningScheme.get -> GitVersion.Configuration.AssemblyVersioningScheme GitVersion.Configuration.EffectiveConfiguration.DeploymentMode.get -> GitVersion.VersionCalculation.DeploymentMode -GitVersion.Configuration.EffectiveConfiguration.EffectiveConfiguration(GitVersion.Configuration.IGitVersionConfiguration! configuration, GitVersion.Configuration.IBranchConfiguration! branchConfiguration) -> void +GitVersion.Configuration.EffectiveConfiguration.EffectiveConfiguration(GitVersion.Configuration.IGitVersionConfiguration! configuration, GitVersion.Configuration.IBranchConfiguration! branchConfiguration, GitVersion.Configuration.EffectiveConfiguration? fallbackConfiguration = null) -> void GitVersion.Configuration.EffectiveConfiguration.Ignore.get -> GitVersion.Configuration.IIgnoreConfiguration! GitVersion.Configuration.EffectiveConfiguration.PreventIncrementOfMergedBranch.get -> bool GitVersion.Configuration.EffectiveConfiguration.PreventIncrementWhenBranchMerged.get -> bool @@ -94,6 +94,7 @@ GitVersion.Configuration.IBranchConfiguration GitVersion.Configuration.IBranchConfiguration.CommitMessageIncrementing.get -> GitVersion.VersionCalculation.CommitMessageIncrementMode? GitVersion.Configuration.IBranchConfiguration.DeploymentMode.get -> GitVersion.VersionCalculation.DeploymentMode? GitVersion.Configuration.IBranchConfiguration.Increment.get -> GitVersion.IncrementStrategy +GitVersion.Configuration.IBranchConfiguration.Inherit(GitVersion.Configuration.EffectiveConfiguration! configuration) -> GitVersion.Configuration.IBranchConfiguration! GitVersion.Configuration.IBranchConfiguration.Inherit(GitVersion.Configuration.IBranchConfiguration! configuration) -> GitVersion.Configuration.IBranchConfiguration! GitVersion.Configuration.IBranchConfiguration.IsMainBranch.get -> bool? GitVersion.Configuration.IBranchConfiguration.IsMatch(string! branchName) -> bool @@ -145,6 +146,7 @@ GitVersion.Configuration.IPreventIncrementConfiguration GitVersion.Configuration.IPreventIncrementConfiguration.OfMergedBranch.get -> bool? GitVersion.Configuration.IPreventIncrementConfiguration.WhenBranchMerged.get -> bool? GitVersion.Configuration.IPreventIncrementConfiguration.WhenCurrentCommitTagged.get -> bool? +GitVersion.Configuration.ReferenceNameExtensions GitVersion.ConfigurationInfo GitVersion.ConfigurationInfo.ConfigurationFile -> string? GitVersion.ConfigurationInfo.OverrideConfiguration -> System.Collections.Generic.IReadOnlyDictionary? @@ -499,9 +501,9 @@ GitVersion.SemanticVersion.BuildMetaData.init -> void GitVersion.SemanticVersion.CompareTo(GitVersion.SemanticVersion? value) -> int GitVersion.SemanticVersion.CompareTo(GitVersion.SemanticVersion? value, bool includePreRelease) -> int GitVersion.SemanticVersion.Equals(GitVersion.SemanticVersion? obj) -> bool -GitVersion.SemanticVersion.Increment(GitVersion.VersionField increment, string? label) -> GitVersion.SemanticVersion! -GitVersion.SemanticVersion.Increment(GitVersion.VersionField increment, string? label, bool forceIncrement) -> GitVersion.SemanticVersion! -GitVersion.SemanticVersion.Increment(GitVersion.VersionField increment, string? label, GitVersion.SemanticVersion.IncrementMode mode) -> GitVersion.SemanticVersion! +GitVersion.SemanticVersion.Increment(GitVersion.VersionField increment, string? label, bool forceIncrement, params GitVersion.SemanticVersion?[]! alternativeSemanticVersions) -> GitVersion.SemanticVersion! +GitVersion.SemanticVersion.Increment(GitVersion.VersionField increment, string? label, GitVersion.SemanticVersion.IncrementMode mode, params GitVersion.SemanticVersion?[]! alternativeSemanticVersions) -> GitVersion.SemanticVersion! +GitVersion.SemanticVersion.Increment(GitVersion.VersionField increment, string? label, params GitVersion.SemanticVersion?[]! alternativeSemanticVersions) -> GitVersion.SemanticVersion! GitVersion.SemanticVersion.IncrementMode GitVersion.SemanticVersion.IncrementMode.EnsureIntegrity = 2 -> GitVersion.SemanticVersion.IncrementMode GitVersion.SemanticVersion.IncrementMode.Force = 1 -> GitVersion.SemanticVersion.IncrementMode @@ -527,6 +529,7 @@ GitVersion.SemanticVersion.SemanticVersion(GitVersion.SemanticVersion! semanticV GitVersion.SemanticVersion.SemanticVersion(long major = 0, long minor = 0, long patch = 0) -> void GitVersion.SemanticVersion.ToString(string! format) -> string! GitVersion.SemanticVersion.ToString(string? format, System.IFormatProvider? formatProvider) -> string! +GitVersion.SemanticVersion.WithLabel(string? label) -> GitVersion.SemanticVersion! GitVersion.SemanticVersionBuildMetaData GitVersion.SemanticVersionBuildMetaData.Branch.get -> string? GitVersion.SemanticVersionBuildMetaData.Branch.init -> void @@ -670,7 +673,7 @@ GitVersion.VersionCalculation.IEffectiveBranchConfigurationFinder GitVersion.VersionCalculation.IEffectiveBranchConfigurationFinder.GetConfigurations(GitVersion.Git.IBranch! branch, GitVersion.Configuration.IGitVersionConfiguration! configuration) -> System.Collections.Generic.IEnumerable! GitVersion.VersionCalculation.IIncrementStrategyFinder GitVersion.VersionCalculation.IIncrementStrategyFinder.DetermineIncrementedField(GitVersion.Git.ICommit! currentCommit, GitVersion.Git.ICommit? baseVersionSource, bool shouldIncrement, GitVersion.Configuration.EffectiveConfiguration! configuration, string? label) -> GitVersion.VersionField -GitVersion.VersionCalculation.IIncrementStrategyFinder.GetIncrementForcedByCommit(GitVersion.Git.ICommit! commit, GitVersion.Configuration.EffectiveConfiguration! configuration) -> GitVersion.VersionField +GitVersion.VersionCalculation.IIncrementStrategyFinder.GetIncrementForcedByCommit(GitVersion.Git.ICommit! commit, GitVersion.Configuration.IGitVersionConfiguration! configuration) -> GitVersion.VersionField GitVersion.VersionCalculation.IIncrementStrategyFinder.GetIncrementForCommits(string? majorVersionBumpMessage, string? minorVersionBumpMessage, string? patchVersionBumpMessage, string? noBumpMessage, GitVersion.Git.ICommit![]! commits) -> GitVersion.VersionField? GitVersion.VersionCalculation.IIncrementStrategyFinder.GetMergedCommits(GitVersion.Git.ICommit! mergeCommit, int index, GitVersion.Configuration.IIgnoreConfiguration! ignore) -> System.Collections.Generic.IEnumerable! GitVersion.VersionCalculation.INextVersionCalculator @@ -732,9 +735,13 @@ override GitVersion.SemanticVersionPreReleaseTag.GetHashCode() -> int override GitVersion.SemanticVersionPreReleaseTag.ToString() -> string! override GitVersion.SemanticVersionWithTag.ToString() -> string! override GitVersion.VersionCalculation.BaseVersion.ToString() -> string! +override GitVersion.VersionCalculation.BaseVersionOperand.ToString() -> string! +override GitVersion.VersionCalculation.BaseVersionOperator.ToString() -> string! override GitVersion.VersionCalculation.NextVersion.Equals(object? other) -> bool override GitVersion.VersionCalculation.NextVersion.GetHashCode() -> int override GitVersion.VersionCalculation.NextVersion.ToString() -> string! +static GitVersion.Configuration.ReferenceNameExtensions.TryGetSemanticVersion(this GitVersion.Git.ReferenceName! source, out (GitVersion.SemanticVersion! Value, string? Name) result, GitVersion.Configuration.EffectiveConfiguration! configuration) -> bool +static GitVersion.Configuration.ReferenceNameExtensions.TryGetSemanticVersion(this GitVersion.Git.ReferenceName! source, out (GitVersion.SemanticVersion! Value, string? Name) result, GitVersion.Configuration.IGitVersionConfiguration! configuration) -> bool static GitVersion.Extensions.AssemblyVersionsGeneratorExtensions.GetAssemblyFileVersion(this GitVersion.SemanticVersion! sv, GitVersion.Configuration.AssemblyFileVersioningScheme scheme) -> string? static GitVersion.Extensions.AssemblyVersionsGeneratorExtensions.GetAssemblyVersion(this GitVersion.SemanticVersion! sv, GitVersion.Configuration.AssemblyVersioningScheme scheme) -> string? static GitVersion.Extensions.CommonExtensions.NotNull(this T? value, string! name = "") -> T! diff --git a/src/GitVersion.Core/SemVer/SemanticVersion.cs b/src/GitVersion.Core/SemVer/SemanticVersion.cs index d889176b15..130d21d72e 100644 --- a/src/GitVersion.Core/SemVer/SemanticVersion.cs +++ b/src/GitVersion.Core/SemVer/SemanticVersion.cs @@ -62,7 +62,11 @@ public bool Equals(SemanticVersion? obj) { return false; } - return this.Major == obj.Major && this.Minor == obj.Minor && this.Patch == obj.Patch && this.PreReleaseTag == obj.PreReleaseTag && this.BuildMetaData == obj.BuildMetaData; + return this.Major == obj.Major + && this.Minor == obj.Minor + && this.Patch == obj.Patch + && this.PreReleaseTag == obj.PreReleaseTag + && this.BuildMetaData == obj.BuildMetaData; } public bool IsEmpty() => Equals(Empty); @@ -329,13 +333,18 @@ public string ToString(string? format, IFormatProvider? formatProvider) } } - public SemanticVersion Increment(VersionField increment, string? label) - => Increment(increment, label, mode: IncrementMode.Standard); + public SemanticVersion WithLabel(string? label) => Increment(VersionField.None, label, mode: IncrementMode.Standard); - public SemanticVersion Increment(VersionField increment, string? label, bool forceIncrement) - => Increment(increment, label, mode: forceIncrement ? IncrementMode.Force : IncrementMode.Standard); + public SemanticVersion Increment( + VersionField increment, string? label, params SemanticVersion?[] alternativeSemanticVersions) + => Increment(increment, label, mode: IncrementMode.Standard, alternativeSemanticVersions); - public SemanticVersion Increment(VersionField increment, string? label, IncrementMode mode) + public SemanticVersion Increment( + VersionField increment, string? label, bool forceIncrement, params SemanticVersion?[] alternativeSemanticVersions) + => Increment(increment, label, mode: forceIncrement ? IncrementMode.Force : IncrementMode.Standard, alternativeSemanticVersions); + + public SemanticVersion Increment( + VersionField increment, string? label, IncrementMode mode, params SemanticVersion?[] alternativeSemanticVersions) { long major = Major; long minor = Minor; @@ -396,6 +405,27 @@ public SemanticVersion Increment(VersionField increment, string? label, Incremen throw new ArgumentOutOfRangeException(nameof(increment)); } + SemanticVersion semanticVersion = new(major, minor, patch); + + bool foundAlternativeSemanticVersion = false; + foreach (var alternativeSemanticVersion in alternativeSemanticVersions) + { + if (semanticVersion.IsLessThan(alternativeSemanticVersion, includePreRelease: false)) + { + semanticVersion = alternativeSemanticVersion!; + foundAlternativeSemanticVersion = true; + } + } + + major = semanticVersion.Major; + minor = semanticVersion.Minor; + patch = semanticVersion.Patch; + + if (foundAlternativeSemanticVersion && increment == VersionField.None) + { + preReleaseNumber = 1; + } + string preReleaseTagName; if (hasPreReleaseTag) { @@ -418,7 +448,7 @@ public SemanticVersion Increment(VersionField increment, string? label, Incremen Major = major, Minor = minor, Patch = patch, - PreReleaseTag = new(preReleaseTagName, preReleaseNumber, true) + PreReleaseTag = new SemanticVersionPreReleaseTag(preReleaseTagName, preReleaseNumber, true) }; } diff --git a/src/GitVersion.Core/VersionCalculation/Abstractions/IIncrementStrategyFinder.cs b/src/GitVersion.Core/VersionCalculation/Abstractions/IIncrementStrategyFinder.cs index 2c34ed344a..5bd1ce41eb 100644 --- a/src/GitVersion.Core/VersionCalculation/Abstractions/IIncrementStrategyFinder.cs +++ b/src/GitVersion.Core/VersionCalculation/Abstractions/IIncrementStrategyFinder.cs @@ -15,5 +15,5 @@ ICommit[] commits IEnumerable GetMergedCommits(ICommit mergeCommit, int index, IIgnoreConfiguration ignore); - VersionField GetIncrementForcedByCommit(ICommit commit, EffectiveConfiguration configuration); + VersionField GetIncrementForcedByCommit(ICommit commit, IGitVersionConfiguration configuration); } diff --git a/src/GitVersion.Core/VersionCalculation/EffectiveBranchConfigurationFinder.cs b/src/GitVersion.Core/VersionCalculation/EffectiveBranchConfigurationFinder.cs index 561ddf7b80..95b7ab6703 100644 --- a/src/GitVersion.Core/VersionCalculation/EffectiveBranchConfigurationFinder.cs +++ b/src/GitVersion.Core/VersionCalculation/EffectiveBranchConfigurationFinder.cs @@ -6,12 +6,12 @@ namespace GitVersion.VersionCalculation; -internal class EffectiveBranchConfigurationFinder(ILog log, IRepositoryStore repositoryStore) : IEffectiveBranchConfigurationFinder +internal sealed class EffectiveBranchConfigurationFinder(ILog log, IRepositoryStore repositoryStore) : IEffectiveBranchConfigurationFinder { private readonly ILog log = log.NotNull(); private readonly IRepositoryStore repositoryStore = repositoryStore.NotNull(); - public virtual IEnumerable GetConfigurations(IBranch branch, IGitVersionConfiguration configuration) + public IEnumerable GetConfigurations(IBranch branch, IGitVersionConfiguration configuration) { branch.NotNull(); configuration.NotNull(); diff --git a/src/GitVersion.Core/VersionCalculation/IncrementStrategyFinder.cs b/src/GitVersion.Core/VersionCalculation/IncrementStrategyFinder.cs index c22d218a5f..c48e070785 100644 --- a/src/GitVersion.Core/VersionCalculation/IncrementStrategyFinder.cs +++ b/src/GitVersion.Core/VersionCalculation/IncrementStrategyFinder.cs @@ -237,7 +237,7 @@ private static ICommit GetMergedHead(ICommit mergeCommit) return parents.Single(); } - public VersionField GetIncrementForcedByCommit(ICommit commit, EffectiveConfiguration configuration) + public VersionField GetIncrementForcedByCommit(ICommit commit, IGitVersionConfiguration configuration) { commit.NotNull(); configuration.NotNull(); diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/EnrichIncrement.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/EnrichIncrement.cs index d22b319014..3f9b5992fb 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/EnrichIncrement.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/EnrichIncrement.cs @@ -1,5 +1,7 @@ +using System.ComponentModel; using GitVersion.Configuration; using GitVersion.Extensions; +using GitVersion.Git; namespace GitVersion.VersionCalculation.TrunkBased; @@ -7,16 +9,38 @@ internal sealed class EnrichIncrement : ITrunkBasedContextPreEnricher { public void Enrich(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) { - var incrementForcedByBranch = commit.GetIncrementForcedByBranch(); - var incrementForcedByCommit = commit.Increment; + var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); + var incrementForcedByBranch = effectiveConfiguration.Increment.ToVersionField(); + var incrementForcedByCommit = GetIncrementForcedByCommit(context, commit.Value, effectiveConfiguration); + commit.Increment = incrementForcedByCommit; context.Increment = context.Increment.Consolidate(incrementForcedByBranch, incrementForcedByCommit); if (commit.Predecessor is not null && commit.Predecessor.BranchName != commit.BranchName) context.Label = null; - context.Label ??= commit.Configuration.GetBranchSpecificLabel(commit.BranchName, null); + context.Label ??= effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null); - if (commit.Configuration.IsMainBranch) + if (effectiveConfiguration.IsMainBranch) context.BaseVersionSource = commit.Predecessor?.Value; - context.ForceIncrement |= commit.Configuration.IsMainBranch || commit.IsPredecessorTheLastCommitOnTrunk; + context.ForceIncrement |= effectiveConfiguration.IsMainBranch || commit.IsPredecessorTheLastCommitOnTrunk(context.Configuration); + } + + private static VersionField GetIncrementForcedByCommit( + TrunkBasedContext context, ICommit commit, EffectiveConfiguration configuration) + { + context.NotNull(); + commit.NotNull(); + configuration.NotNull(); + + return configuration.CommitMessageIncrementing switch + { + CommitMessageIncrementMode.Enabled + => context.IncrementStrategyFinder.GetIncrementForcedByCommit(commit, context.Configuration), + CommitMessageIncrementMode.Disabled => VersionField.None, + CommitMessageIncrementMode.MergeMessageOnly => commit.IsMergeCommit() + ? context.IncrementStrategyFinder.GetIncrementForcedByCommit(commit, context.Configuration) : VersionField.None, + _ => throw new InvalidEnumArgumentException( + nameof(configuration.CommitMessageIncrementing), (int)configuration.CommitMessageIncrementing, typeof(CommitMessageIncrementMode) + ) + }; } } diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/EnrichSemanticVersion.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/EnrichSemanticVersion.cs index 55a3c58213..41c0af40e0 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/EnrichSemanticVersion.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/EnrichSemanticVersion.cs @@ -8,8 +8,10 @@ internal sealed class EnrichSemanticVersion : ITrunkBasedContextPreEnricher public void Enrich(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) { var branchSpecificLabel = context.TargetLabel; - branchSpecificLabel ??= iteration.Configuration.GetBranchSpecificLabel(commit.BranchName, null); - branchSpecificLabel ??= commit.Configuration.GetBranchSpecificLabel(commit.BranchName, null); + branchSpecificLabel ??= iteration.GetEffectiveConfiguration(context.Configuration) + .GetBranchSpecificLabel(commit.BranchName, null); + branchSpecificLabel ??= commit.GetEffectiveConfiguration(context.Configuration) + .GetBranchSpecificLabel(commit.BranchName, null); var semanticVersions = commit.SemanticVersions.Where( element => element.IsMatchForBranchSpecificLabel(branchSpecificLabel) diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunk.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunk.cs index ea937bec17..dea1beb8bc 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunk.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunk.cs @@ -11,14 +11,18 @@ internal sealed class CommitOnNonTrunk : ITrunkBasedIncrementer // A 58 minutes ago public bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) - => commit is { HasChildIteration: false, Configuration.IsMainBranch: false } && context.SemanticVersion is null; + => !commit.HasChildIteration + && !commit.GetEffectiveConfiguration(context.Configuration).IsMainBranch + && context.SemanticVersion is null; public IEnumerable GetIncrements( TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) { if (commit.Predecessor is not null && commit.Predecessor.BranchName != commit.BranchName) context.Label = null; - context.Label ??= commit.Configuration.GetBranchSpecificLabel(commit.BranchName, null); + + var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); + context.Label ??= effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null); if (commit.Successor is null) { @@ -33,6 +37,7 @@ public IEnumerable GetIncrements( }; context.BaseVersionSource = commit.Value; + context.ForceIncrement = false; } } } diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkBranchedBase.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkBranchedBase.cs index 076ce28c5a..2fce545d32 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkBranchedBase.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkBranchedBase.cs @@ -6,7 +6,9 @@ namespace GitVersion.VersionCalculation.TrunkBased.NonTrunk; internal abstract class CommitOnNonTrunkBranchedBase : ITrunkBasedIncrementer { public virtual bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) - => !commit.Configuration.IsMainBranch && commit.BranchName != iteration.BranchName && commit.Successor is null; + => !commit.GetEffectiveConfiguration(context.Configuration).IsMainBranch + && commit.BranchName != iteration.BranchName + && commit.Successor is null; public virtual IEnumerable GetIncrements( TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) @@ -14,10 +16,12 @@ public virtual IEnumerable GetIncrements( context.BaseVersionSource = commit.Value; var incrementForcedByBranch = iteration.Configuration.Increment == IncrementStrategy.Inherit - ? commit.GetIncrementForcedByBranch() : iteration.Configuration.Increment.ToVersionField(); + ? commit.GetIncrementForcedByBranch(context.Configuration) + : iteration.Configuration.Increment.ToVersionField(); context.Increment = context.Increment.Consolidate(incrementForcedByBranch); - context.Label = iteration.Configuration.GetBranchSpecificLabel(iteration.BranchName, null) ?? context.Label; + var iterationEffectiveConfiguration = iteration.GetEffectiveConfiguration(context.Configuration); + context.Label = iterationEffectiveConfiguration.GetBranchSpecificLabel(iteration.BranchName, null) ?? context.Label; context.ForceIncrement = true; yield return new BaseVersionOperator() diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkBranchedToNonTrunk.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkBranchedToNonTrunk.cs index 075a104070..c870cd297c 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkBranchedToNonTrunk.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkBranchedToNonTrunk.cs @@ -14,5 +14,6 @@ internal sealed class CommitOnNonTrunkBranchedToNonTrunk : CommitOnNonTrunkBranc // A 58 minutes ago <<-- public override bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) - => base.MatchPrecondition(iteration, commit, context) && !iteration.Configuration.IsMainBranch; + => base.MatchPrecondition(iteration, commit, context) + && !iteration.GetEffectiveConfiguration(context.Configuration).IsMainBranch; } diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkBranchedToTrunk.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkBranchedToTrunk.cs index ddfa42b371..22ff874504 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkBranchedToTrunk.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkBranchedToTrunk.cs @@ -14,5 +14,6 @@ internal sealed class CommitOnNonTrunkBranchedToTrunk : CommitOnNonTrunkBranched // A 58 minutes ago <<-- public override bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) - => base.MatchPrecondition(iteration, commit, context) && iteration.Configuration.IsMainBranch; + => base.MatchPrecondition(iteration, commit, context) + && iteration.GetEffectiveConfiguration(context.Configuration).IsMainBranch; } diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkWithPreReleaseTagBase.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkWithPreReleaseTagBase.cs index ed39b3c745..ba31a411b7 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkWithPreReleaseTagBase.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkWithPreReleaseTagBase.cs @@ -6,7 +6,8 @@ namespace GitVersion.VersionCalculation.TrunkBased.NonTrunk; internal abstract class CommitOnNonTrunkWithPreReleaseTagBase : ITrunkBasedIncrementer { public virtual bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) - => commit is { HasChildIteration: false, Configuration.IsMainBranch: false } + => !commit.HasChildIteration + && !commit.GetEffectiveConfiguration(context.Configuration).IsMainBranch && context.SemanticVersion?.IsPreRelease == true; public virtual IEnumerable GetIncrements( @@ -21,7 +22,9 @@ public virtual IEnumerable GetIncrements( SemanticVersion = context.SemanticVersion.NotNull() }; - context.Increment = commit.GetIncrementForcedByBranch(); - context.Label = commit.Configuration.GetBranchSpecificLabel(commit.BranchName, null); + context.Increment = commit.GetIncrementForcedByBranch(context.Configuration); + var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); + context.Label = effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null); + context.ForceIncrement = false; } } diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkWithStableTagBase.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkWithStableTagBase.cs index 30c46d0850..65be56f8ec 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkWithStableTagBase.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/CommitOnNonTrunkWithStableTagBase.cs @@ -6,8 +6,9 @@ namespace GitVersion.VersionCalculation.TrunkBased.NonTrunk; internal abstract class CommitOnNonTrunkWithStableTagBase : ITrunkBasedIncrementer { public virtual bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) - => !commit.Configuration.IsMainBranch && !commit.HasChildIteration - && context.SemanticVersion?.IsPreRelease == false; + => !commit.GetEffectiveConfiguration(context.Configuration).IsMainBranch + && !commit.HasChildIteration + && context.SemanticVersion?.IsPreRelease == false; public virtual IEnumerable GetIncrements( TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) @@ -21,7 +22,8 @@ public virtual IEnumerable GetIncrements( SemanticVersion = context.SemanticVersion.NotNull() }; - context.Increment = commit.GetIncrementForcedByBranch(); - context.Label = commit.Configuration.GetBranchSpecificLabel(commit.BranchName, null); + context.Increment = commit.GetIncrementForcedByBranch(context.Configuration); + var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); + context.Label = effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null); } } diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/FirstCommitOnRelease.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/FirstCommitOnRelease.cs new file mode 100644 index 0000000000..65d3d56fb6 --- /dev/null +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/FirstCommitOnRelease.cs @@ -0,0 +1,39 @@ +using GitVersion.Configuration; + +namespace GitVersion.VersionCalculation.TrunkBased.NonTrunk; + +/// +/// This incrementer identifies the first commit on a branch marked with IsReleaseBranch true and appends the version number for +/// instance 1.0.0 (extracted from the branch name) as an alternative semantic version to the context. This information will be +/// used later to bump the version number to a higher value if necessary. +/// +internal sealed class FirstCommitOnRelease : ITrunkBasedIncrementer +{ + // B 57 minutes ago (HEAD -> release/1.0.0) + // A 58 minutes ago <<-- + + // A 58 minutes ago (HEAD -> release/1.0.0) <<-- + + // C 56 minutes ago (HEAD -> release/1.0.0) + // B 57 minutes ago <<-- + // A 58 minutes ago (main) + + public bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) + => !commit.HasChildIteration + && !commit.GetEffectiveConfiguration(context.Configuration).IsMainBranch + && commit.GetEffectiveConfiguration(context.Configuration).IsReleaseBranch + && context.SemanticVersion is null + && (commit.Predecessor is null + || commit.Predecessor?.BranchName != commit.BranchName); + + public IEnumerable GetIncrements( + TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) + { + var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); + if (commit.BranchName.TryGetSemanticVersion(out var element, effectiveConfiguration)) + { + context.AlternativeSemanticVersions.Add(element.Value); + yield break; + } + } +} diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/MergeCommitOnNonTrunkBase.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/MergeCommitOnNonTrunkBase.cs index e09a8308f0..1479cb33cb 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/MergeCommitOnNonTrunkBase.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/NonTrunk/MergeCommitOnNonTrunkBase.cs @@ -5,7 +5,9 @@ namespace GitVersion.VersionCalculation.TrunkBased.NonTrunk; internal abstract class MergeCommitOnNonTrunkBase : ITrunkBasedIncrementer { public virtual bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) - => commit is { HasChildIteration: true, Configuration.IsMainBranch: false } && context.SemanticVersion is null; + => commit.HasChildIteration + && !commit.GetEffectiveConfiguration(context.Configuration).IsMainBranch + && context.SemanticVersion is null; public virtual IEnumerable GetIncrements( TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) @@ -14,21 +16,26 @@ public virtual IEnumerable GetIncrements( var baseVersion = TrunkBasedVersionStrategy.DetermineBaseVersionRecursive( iteration: commit.ChildIteration, - targetLabel: context.TargetLabel + targetLabel: context.TargetLabel, + incrementStrategyFinder: context.IncrementStrategyFinder, + configuration: context.Configuration ); context.Label ??= baseVersion.Operator?.Label; + var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); var increment = VersionField.None; - if (!commit.Configuration.PreventIncrementOfMergedBranch) + if (!effectiveConfiguration.PreventIncrementOfMergedBranch) { increment = increment.Consolidate(context.Increment); } - if (!commit.ChildIteration.Configuration.PreventIncrementWhenBranchMerged) + + if (!effectiveConfiguration.PreventIncrementWhenBranchMerged) { increment = increment.Consolidate(baseVersion.Operator?.Increment); } - if (commit.Configuration.CommitMessageIncrementing != CommitMessageIncrementMode.Disabled) + + if (effectiveConfiguration.CommitMessageIncrementing != CommitMessageIncrementMode.Disabled) { increment = increment.Consolidate(commit.Increment); } @@ -39,9 +46,17 @@ public virtual IEnumerable GetIncrements( context.BaseVersionSource = baseVersion.BaseVersionSource; context.SemanticVersion = baseVersion.SemanticVersion; } - else if (baseVersion.Operator?.AlternativeSemanticVersion is not null) + else { - context.AlternativeSemanticVersions.Add(baseVersion.Operator.AlternativeSemanticVersion); + if (baseVersion.SemanticVersion != SemanticVersion.Empty) + { + context.AlternativeSemanticVersions.Add(baseVersion.SemanticVersion); + } + + if (baseVersion.Operator?.AlternativeSemanticVersion is not null) + { + context.AlternativeSemanticVersions.Add(baseVersion.Operator.AlternativeSemanticVersion); + } } yield break; diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/RemoveIncrement.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/RemoveIncrement.cs index bdcc596329..8e22515998 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/RemoveIncrement.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/RemoveIncrement.cs @@ -4,7 +4,7 @@ internal sealed class RemoveIncrement : ITrunkBasedContextPostEnricher { public void Enrich(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) { - if (commit.Configuration.IsMainBranch) + if (commit.GetEffectiveConfiguration(context.Configuration).IsMainBranch) { context.Increment = VersionField.None; context.Label = null; diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunk.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunk.cs index 9c20645c01..d06c22f112 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunk.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunk.cs @@ -11,14 +11,17 @@ internal sealed class CommitOnTrunk : ITrunkBasedIncrementer // A 58 minutes ago <<-- public bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) - => !commit.HasChildIteration && commit.Configuration.IsMainBranch && context.SemanticVersion is null; + => !commit.HasChildIteration + && commit.GetEffectiveConfiguration(context.Configuration).IsMainBranch && context.SemanticVersion is null; public IEnumerable GetIncrements( TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) { if (commit.Predecessor is not null && commit.Predecessor.BranchName != commit.BranchName) context.Label = null; - context.Label ??= commit.Configuration.GetBranchSpecificLabel(commit.BranchName, null); + + var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); + context.Label ??= effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null); context.ForceIncrement = true; yield return new BaseVersionOperator() diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkBranchedBase.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkBranchedBase.cs index af8b2f8ff6..ed2a4831e1 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkBranchedBase.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkBranchedBase.cs @@ -6,18 +6,29 @@ namespace GitVersion.VersionCalculation.TrunkBased.Trunk; internal abstract class CommitOnTrunkBranchedBase : ITrunkBasedIncrementer { public virtual bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) - => commit.Configuration.IsMainBranch && commit.BranchName != iteration.BranchName && commit.Successor is null; + => commit.GetEffectiveConfiguration(context.Configuration).IsMainBranch + && commit.BranchName != iteration.BranchName + && commit.Successor is null; public virtual IEnumerable GetIncrements( TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) { context.BaseVersionSource = commit.Value; + var effectiveConfiguration = iteration.GetEffectiveConfiguration(context.Configuration); + if (iteration.GetEffectiveConfiguration(context.Configuration).IsReleaseBranch + && iteration.BranchName.TryGetSemanticVersion(out var element, effectiveConfiguration)) + { + context.AlternativeSemanticVersions.Add(element.Value); + } + var incrementForcedByBranch = iteration.Configuration.Increment == IncrementStrategy.Inherit - ? commit.GetIncrementForcedByBranch() : iteration.Configuration.Increment.ToVersionField(); + ? commit.GetIncrementForcedByBranch(context.Configuration) + : iteration.Configuration.Increment.ToVersionField(); context.Increment = incrementForcedByBranch; - context.Label = iteration.Configuration.GetBranchSpecificLabel(iteration.BranchName, null) ?? context.Label; + var iterationEffectiveConfiguration = iteration.GetEffectiveConfiguration(context.Configuration); + context.Label = iterationEffectiveConfiguration.GetBranchSpecificLabel(iteration.BranchName, null) ?? context.Label; context.ForceIncrement = true; yield return new BaseVersionOperator() diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkBranchedToNonTrunk.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkBranchedToNonTrunk.cs index 7d3fada9ed..cc71df969a 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkBranchedToNonTrunk.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkBranchedToNonTrunk.cs @@ -14,5 +14,6 @@ internal sealed class CommitOnTrunkBranchedToNonTrunk : CommitOnTrunkBranchedBas // A 58 minutes ago <<-- public override bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) - => base.MatchPrecondition(iteration, commit, context) && !iteration.Configuration.IsMainBranch; + => base.MatchPrecondition(iteration, commit, context) + && !iteration.GetEffectiveConfiguration(context.Configuration).IsMainBranch; } diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkBranchedToTrunk.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkBranchedToTrunk.cs index 4a7b5ac008..059fe28941 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkBranchedToTrunk.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkBranchedToTrunk.cs @@ -14,5 +14,6 @@ internal sealed class CommitOnTrunkBranchedToTrunk : CommitOnTrunkBranchedBase // A 58 minutes ago <<-- public override bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) - => base.MatchPrecondition(iteration, commit, context) && iteration.Configuration.IsMainBranch; + => base.MatchPrecondition(iteration, commit, context) + && iteration.GetEffectiveConfiguration(context.Configuration).IsMainBranch; } diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkWithPreReleaseTagBase.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkWithPreReleaseTagBase.cs index 953ebc3f9d..3168ed4518 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkWithPreReleaseTagBase.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkWithPreReleaseTagBase.cs @@ -5,7 +5,7 @@ namespace GitVersion.VersionCalculation.TrunkBased.Trunk; internal abstract class CommitOnTrunkWithPreReleaseTagBase : ITrunkBasedIncrementer { public virtual bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) - => commit.Configuration.IsMainBranch && !commit.HasChildIteration + => commit.GetEffectiveConfiguration(context.Configuration).IsMainBranch && !commit.HasChildIteration && context.SemanticVersion?.IsPreRelease == true; public virtual IEnumerable GetIncrements( diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkWithStableTagBase.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkWithStableTagBase.cs index 65de504abc..b96aa7097d 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkWithStableTagBase.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/CommitOnTrunkWithStableTagBase.cs @@ -6,7 +6,7 @@ namespace GitVersion.VersionCalculation.TrunkBased.Trunk; internal abstract class CommitOnTrunkWithStableTagBase : ITrunkBasedIncrementer { public virtual bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) - => commit.Configuration.IsMainBranch && !commit.HasChildIteration + => commit.GetEffectiveConfiguration(context.Configuration).IsMainBranch && !commit.HasChildIteration && context.SemanticVersion?.IsPreRelease == false; public virtual IEnumerable GetIncrements( @@ -21,6 +21,7 @@ public virtual IEnumerable GetIncrements( BaseVersionSource = context.BaseVersionSource }; - context.Label = commit.Configuration.GetBranchSpecificLabel(commit.BranchName, null); + var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); + context.Label = effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null); } } diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/LastCommitOnTrunkWithPreReleaseTag.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/LastCommitOnTrunkWithPreReleaseTag.cs index 2924d8fc1e..91e8407ce5 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/LastCommitOnTrunkWithPreReleaseTag.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/LastCommitOnTrunkWithPreReleaseTag.cs @@ -18,10 +18,12 @@ public override IEnumerable GetIncrements( yield return item; } - if (iteration.Configuration.IsMainBranch) + if (iteration.GetEffectiveConfiguration(context.Configuration).IsMainBranch) { - context.Increment = commit.GetIncrementForcedByBranch(); - context.Label = commit.Configuration.GetBranchSpecificLabel(commit.BranchName, null); + context.Increment = commit.GetIncrementForcedByBranch(context.Configuration); + + var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); + context.Label = effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null); context.ForceIncrement = false; yield return new BaseVersionOperator() diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/LastCommitOnTrunkWithStableTag.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/LastCommitOnTrunkWithStableTag.cs index 7ec910b0f5..16e32a59a6 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/LastCommitOnTrunkWithStableTag.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/LastCommitOnTrunkWithStableTag.cs @@ -16,7 +16,7 @@ public override IEnumerable GetIncrements( yield return item; } - if (iteration.Configuration.IsMainBranch) + if (iteration.GetEffectiveConfiguration(context.Configuration).IsMainBranch) { context.ForceIncrement = true; diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/LastMergeCommitOnTrunk.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/LastMergeCommitOnTrunk.cs index 4e8e72001a..d18db2846c 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/LastMergeCommitOnTrunk.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/LastMergeCommitOnTrunk.cs @@ -1,3 +1,4 @@ + namespace GitVersion.VersionCalculation.TrunkBased.Trunk; internal sealed class LastMergeCommitOnTrunk : MergeCommitOnTrunkBase diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/MergeCommitOnTrunkBase.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/MergeCommitOnTrunkBase.cs index 165984cdcc..d9d6ecaad8 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/MergeCommitOnTrunkBase.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/Trunk/MergeCommitOnTrunkBase.cs @@ -5,7 +5,7 @@ namespace GitVersion.VersionCalculation.TrunkBased.Trunk; internal abstract class MergeCommitOnTrunkBase : ITrunkBasedIncrementer { public virtual bool MatchPrecondition(TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) - => commit.HasChildIteration && commit.Configuration.IsMainBranch && context.SemanticVersion is null; + => commit.HasChildIteration && commit.GetEffectiveConfiguration(context.Configuration).IsMainBranch && context.SemanticVersion is null; public virtual IEnumerable GetIncrements( TrunkBasedIteration iteration, TrunkBasedCommit commit, TrunkBasedContext context) @@ -14,21 +14,26 @@ public virtual IEnumerable GetIncrements( var baseVersion = TrunkBasedVersionStrategy.DetermineBaseVersionRecursive( iteration: commit.ChildIteration!, - targetLabel: context.TargetLabel + targetLabel: context.TargetLabel, + incrementStrategyFinder: context.IncrementStrategyFinder, + configuration: context.Configuration ); context.Label ??= baseVersion.Operator?.Label; var increment = VersionField.None; - if (!commit.Configuration.PreventIncrementOfMergedBranch) + + if (!commit.GetEffectiveConfiguration(context.Configuration).PreventIncrementOfMergedBranch) { increment = increment.Consolidate(context.Increment); } - if (!commit.ChildIteration.Configuration.PreventIncrementWhenBranchMerged) + + if (!commit.ChildIteration.GetEffectiveConfiguration(context.Configuration).PreventIncrementWhenBranchMerged) { increment = increment.Consolidate(baseVersion.Operator?.Increment); } - if (commit.Configuration.CommitMessageIncrementing != CommitMessageIncrementMode.Disabled) + + if (commit.GetEffectiveConfiguration(context.Configuration).CommitMessageIncrementing != CommitMessageIncrementMode.Disabled) { increment = increment.Consolidate(commit.Increment); } diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/TrunkBasedCommit.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/TrunkBasedCommit.cs index 31d139af01..ad3f515387 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/TrunkBasedCommit.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/TrunkBasedCommit.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using GitVersion.Configuration; using GitVersion.Extensions; using GitVersion.Git; @@ -9,16 +10,18 @@ namespace GitVersion.VersionCalculation.TrunkBased; "HasSuccessor = {" + nameof(HasSuccessor) + "}, HasPredecessor = {" + nameof(HasPredecessor) + "}, " + "HasChildIteration = {" + nameof(HasChildIteration) + "}, Message = {" + nameof(Message) + @"} \}" )] -internal record TrunkBasedCommit(TrunkBasedIteration Iteration, ICommit Value, ReferenceName BranchName, EffectiveConfiguration Configuration, VersionField Increment) +internal record TrunkBasedCommit(TrunkBasedIteration Iteration, ICommit Value, ReferenceName BranchName, IBranchConfiguration Configuration) { - public bool IsPredecessorTheLastCommitOnTrunk - => !Configuration.IsMainBranch && Predecessor?.Configuration.IsMainBranch == true; + public bool IsPredecessorTheLastCommitOnTrunk(IGitVersionConfiguration configuration) + => !GetEffectiveConfiguration(configuration).IsMainBranch && Predecessor?.GetEffectiveConfiguration(configuration).IsMainBranch == true; + + public VersionField Increment { get; set; } public TrunkBasedIteration Iteration { get; } = Iteration.NotNull(); public ReferenceName BranchName { get; } = BranchName.NotNull(); - public EffectiveConfiguration Configuration { get; } = Configuration.NotNull(); + private IBranchConfiguration Configuration { get; } = Configuration.NotNull(); public bool HasSuccessor => Successor is not null; @@ -34,36 +37,54 @@ public bool IsPredecessorTheLastCommitOnTrunk public TrunkBasedIteration? ChildIteration { get; private set; } + [MemberNotNullWhen(true, nameof(ChildIteration))] public bool HasChildIteration => ChildIteration is not null && ChildIteration.Commits.Count != 0; + public TrunkBasedIteration? ParentIteration => Iteration.ParentIteration; + + public TrunkBasedCommit? ParentCommit => Iteration.ParentCommit; + + [MemberNotNullWhen(true, nameof(ParentIteration), nameof(ParentCommit))] + public bool HasParentIteration => Iteration.ParentIteration is not null && Iteration.ParentCommit is not null; + public IReadOnlyCollection SemanticVersions => semanticVersions; private readonly HashSet semanticVersions = []; - public VersionField GetIncrementForcedByBranch() + private EffectiveConfiguration? effectiveConfiguration; + + public EffectiveConfiguration GetEffectiveConfiguration(IGitVersionConfiguration configuration) { - ICommit lastCommit = null!; + if (effectiveConfiguration is not null) return effectiveConfiguration; + + IBranchConfiguration branchConfiguration = Configuration; + + IBranchConfiguration? last = Configuration; for (var i = this; i is not null; i = i.Predecessor) { - if (i.Configuration.Increment != IncrementStrategy.Inherit) - return i.Configuration.Increment.ToVersionField(); - lastCommit = i.Value; - } + if (branchConfiguration.Increment != IncrementStrategy.Inherit) break; - if (Iteration.Parent is not null && lastCommit.Parents.FirstOrDefault() is ICommit commit) - { - var trunkCommit = Iteration.Parent.FindCommit(commit); - if (trunkCommit is not null) - return trunkCommit.GetIncrementForcedByBranch(); + if (i.Configuration != last) + { + branchConfiguration = branchConfiguration.Inherit(i.Configuration); + } + + last = i.Configuration; } - for (var i = Iteration; i is not null; i = i.Parent) + if (branchConfiguration.Increment == IncrementStrategy.Inherit && HasParentIteration) { - if (i.Configuration.Increment != IncrementStrategy.Inherit) - return i.Configuration.Increment.ToVersionField(); + var parentConfiguration = ParentCommit.GetEffectiveConfiguration(configuration); + branchConfiguration = branchConfiguration.Inherit(parentConfiguration); } - return VersionField.None; + return effectiveConfiguration = new EffectiveConfiguration(configuration, branchConfiguration); + } + + public VersionField GetIncrementForcedByBranch(IGitVersionConfiguration configuration) + { + var result = GetEffectiveConfiguration(configuration); + return result.Increment.ToVersionField(); } public void AddSemanticVersions(params SemanticVersion[] values) @@ -80,11 +101,11 @@ public void AddSemanticVersions(IEnumerable values) public void AddChildIteration(TrunkBasedIteration iteration) => ChildIteration = iteration.NotNull(); public TrunkBasedCommit Append( - ICommit value, ReferenceName branchName, EffectiveConfiguration configuration, VersionField increment) + ICommit value, ReferenceName branchName, IBranchConfiguration configuration) { if (HasPredecessor) throw new InvalidOperationException(); - TrunkBasedCommit commit = new(Iteration, value, branchName, configuration, increment); + TrunkBasedCommit commit = new(Iteration, value, branchName, configuration); Predecessor = commit; commit.Successor = this; diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/TrunkBasedContext.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/TrunkBasedContext.cs index 8386762d05..8dbd7712c8 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/TrunkBasedContext.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/TrunkBasedContext.cs @@ -1,9 +1,15 @@ +using GitVersion.Configuration; +using GitVersion.Extensions; using GitVersion.Git; namespace GitVersion.VersionCalculation.TrunkBased; -internal record TrunkBasedContext +internal record TrunkBasedContext(IIncrementStrategyFinder IncrementStrategyFinder, IGitVersionConfiguration Configuration) { + public IIncrementStrategyFinder IncrementStrategyFinder { get; } = IncrementStrategyFinder.NotNull(); + + public IGitVersionConfiguration Configuration { get; } = Configuration.NotNull(); + public string? TargetLabel { get; init; } public SemanticVersion? SemanticVersion { get; set; } diff --git a/src/GitVersion.Core/VersionCalculation/TrunkBased/TrunkBasedIteration.cs b/src/GitVersion.Core/VersionCalculation/TrunkBased/TrunkBasedIteration.cs index b8ec6f9673..a0c910ed55 100644 --- a/src/GitVersion.Core/VersionCalculation/TrunkBased/TrunkBasedIteration.cs +++ b/src/GitVersion.Core/VersionCalculation/TrunkBased/TrunkBasedIteration.cs @@ -5,13 +5,38 @@ namespace GitVersion.VersionCalculation.TrunkBased; [DebuggerDisplay( - @"\{ Id = {" + nameof(Id) + "}, BranchName = {" + nameof(BranchName) + "}, Depth = {" + nameof(Depth) + "}, NumberOfCommits = {" + nameof(NumberOfCommits) + "}" + @"} \}" + @"\{ Id = {" + nameof(Id) + "}, " + + "BranchName = {" + nameof(BranchName) + "}, " + + "Depth = {" + nameof(Depth) + "}, " + + "NumberOfCommits = {" + nameof(NumberOfCommits) + "}" + @"} \}" )] internal record TrunkBasedIteration { - public EffectiveConfiguration Configuration { get; } + public IBranchConfiguration Configuration { get; } - public TrunkBasedIteration? Parent { get; } + private EffectiveConfiguration? effectiveConfiguration; + + public EffectiveConfiguration GetEffectiveConfiguration(IGitVersionConfiguration configuration) + { + if (this.effectiveConfiguration is not null) + { + return this.effectiveConfiguration; + } + + IBranchConfiguration branchConfiguration = Configuration; + + if (branchConfiguration.Increment == IncrementStrategy.Inherit && Commits.FirstOrDefault() is TrunkBasedCommit commit) + { + var parentConfiguration = commit.GetEffectiveConfiguration(configuration); + branchConfiguration = branchConfiguration.Inherit(parentConfiguration); + } + + return this.effectiveConfiguration = new EffectiveConfiguration(configuration, branchConfiguration); + } + + public TrunkBasedIteration? ParentIteration { get; } + + public TrunkBasedCommit? ParentCommit { get; } public string Id { get; } @@ -26,24 +51,26 @@ internal record TrunkBasedIteration private readonly Dictionary commitLookup = []; - public TrunkBasedIteration(string id, ReferenceName branchName, EffectiveConfiguration configuration, TrunkBasedIteration? parent) + public TrunkBasedIteration(string id, ReferenceName branchName, IBranchConfiguration configuration, + TrunkBasedIteration? parentIteration, TrunkBasedCommit? parentCommit) { Id = id.NotNullOrEmpty(); - Depth = parent?.Depth ?? 0 + 1; + Depth = parentIteration?.Depth ?? 0 + 1; BranchName = branchName.NotNull(); Configuration = configuration.NotNull(); - Parent = parent; + ParentIteration = parentIteration; + ParentCommit = parentCommit; } public TrunkBasedCommit CreateCommit( - ICommit value, ReferenceName branchName, EffectiveConfiguration configuration, VersionField increment) + ICommit value, ReferenceName branchName, IBranchConfiguration configuration) { TrunkBasedCommit commit; if (commits.Count != 0) - commit = commits.Peek().Append(value, branchName, configuration, increment); + commit = commits.Peek().Append(value, branchName, configuration); //, increment); else { - commit = new(this, value, branchName, configuration, increment); + commit = new TrunkBasedCommit(this, value, branchName, configuration); //, increment); } commits.Push(commit); commitLookup.Add(value, commit); diff --git a/src/GitVersion.Core/VersionCalculation/VersionCalculators/NextVersionCalculator.cs b/src/GitVersion.Core/VersionCalculation/VersionCalculators/NextVersionCalculator.cs index 2839d46878..ede42d8b06 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionCalculators/NextVersionCalculator.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionCalculators/NextVersionCalculator.cs @@ -215,16 +215,16 @@ private NextVersion CalculateNextVersion(IBranch branch, IGitVersionConfiguratio return new(maxVersion.IncrementedVersion, calculatedBase, maxVersion.BranchConfiguration); } - private static NextVersion CompareVersions(NextVersion versions1, NextVersion version2) + private static NextVersion CompareVersions(NextVersion version1, NextVersion version2) { - if (versions1.BaseVersion.BaseVersionSource == null) + if (version1.BaseVersion.BaseVersionSource == null) return version2; if (version2.BaseVersion.BaseVersionSource == null) - return versions1; + return version1; - return versions1.BaseVersion.BaseVersionSource.When < version2.BaseVersion.BaseVersionSource.When - ? versions1 + return version1.BaseVersion.BaseVersionSource.When >= version2.BaseVersion.BaseVersionSource.When + ? version1 : version2; } @@ -244,8 +244,20 @@ IEnumerable GetNextVersionsInternal() foreach (var effectiveBranchConfiguration in effectiveBranchConfigurations) { this.log.Info($"Calculating base versions for '{effectiveBranchConfiguration.Branch.Name}'"); - foreach (var versionStrategy in this.versionStrategies) + + var versionStrategies = this.versionStrategies.ToList(); + var fallbackVersionStrategy = versionStrategies.FirstOrDefault(element => element is FallbackVersionStrategy); + if (fallbackVersionStrategy is not null) + { + versionStrategies.Remove(fallbackVersionStrategy); + versionStrategies.Add(fallbackVersionStrategy); + } + + var atLeastOneBaseVersionReturned = false; + foreach (var versionStrategy in versionStrategies) { + if (atLeastOneBaseVersionReturned && versionStrategy is FallbackVersionStrategy) continue; + using (this.log.IndentLog($"[Using '{versionStrategy.GetType().Name}' strategy]")) { foreach (var baseVersion in versionStrategy.GetBaseVersions(effectiveBranchConfiguration)) @@ -253,6 +265,8 @@ IEnumerable GetNextVersionsInternal() log.Info(baseVersion.ToString()); if (IncludeVersion(baseVersion, configuration.Ignore)) { + atLeastOneBaseVersionReturned = true; + yield return new NextVersion( incrementedVersion: baseVersion.GetIncrementedVersion(), baseVersion: baseVersion, diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/BaseVersion.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/BaseVersion.cs index 0d32d3dd48..ed9b94c57c 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/BaseVersion.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/BaseVersion.cs @@ -37,18 +37,9 @@ public SemanticVersion GetIncrementedVersion() result = result.Increment( increment: Operator.Increment, label: Operator.Label, - forceIncrement: Operator.ForceIncrement + forceIncrement: Operator.ForceIncrement, + Operator.AlternativeSemanticVersion ); - - if (result.IsLessThan(Operator.AlternativeSemanticVersion, includePreRelease: false)) - { - result = new SemanticVersion(result) - { - Major = Operator.AlternativeSemanticVersion!.Major, - Minor = Operator.AlternativeSemanticVersion.Minor, - Patch = Operator.AlternativeSemanticVersion.Patch - }; - } } return result; diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/BaseVersionOperand.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/BaseVersionOperand.cs index 0a963bb947..20944f2084 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/BaseVersionOperand.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/BaseVersionOperand.cs @@ -13,4 +13,18 @@ public BaseVersionOperand() : this(string.Empty, SemanticVersion.Empty) public string Source { get; init; } = Source.NotNull(); public SemanticVersion SemanticVersion { get; init; } = SemanticVersion.NotNull(); + + public ICommit? BaseVersionSource { get; init; } = BaseVersionSource; + + public override string ToString() + { + StringBuilder stringBuilder = new(); + + stringBuilder.Append($"{Source}: Take '{SemanticVersion:f}'"); + + if (BaseVersionSource is not null) + stringBuilder.Append($" based on commit '{BaseVersionSource.Id.ToString(7)}'."); + + return stringBuilder.ToString(); + } } diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/BaseVersionOperator.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/BaseVersionOperator.cs index 8f2708bc99..705c485c82 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/BaseVersionOperator.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/BaseVersionOperator.cs @@ -15,4 +15,31 @@ public sealed record class BaseVersionOperator : IBaseVersionIncrement public string? Label { get; init; } public SemanticVersion? AlternativeSemanticVersion { get; init; } + + public override string ToString() + { + StringBuilder stringBuilder = new(); + + stringBuilder.Append($"{Source}: "); + if (ForceIncrement) + stringBuilder.Append("Force version increment "); + else + { + stringBuilder.Append("Version increment "); + } + + stringBuilder.Append($"+semver '{Increment}'"); + + if (Label is null) + stringBuilder.Append(" with no label"); + else + { + stringBuilder.Append($" with label '{Label}'"); + } + + if (BaseVersionSource is not null) + stringBuilder.Append($" based on commit '{BaseVersionSource.Id.ToString(7)}'."); + + return stringBuilder.ToString(); + } } diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MergeMessageVersionStrategy.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MergeMessageVersionStrategy.cs index fd26fce6b4..547cba2277 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MergeMessageVersionStrategy.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MergeMessageVersionStrategy.cs @@ -1,6 +1,7 @@ using GitVersion.Common; using GitVersion.Configuration; using GitVersion.Extensions; +using GitVersion.Git; using GitVersion.Logging; namespace GitVersion.VersionCalculation; @@ -40,28 +41,23 @@ private IEnumerable GetBaseVersionsInternal(EffectiveBranchConfigur { this.log.Info($"Found commit [{commit}] matching merge message format: {mergeMessage.FormatName}"); - var shouldIncrement = !configuration.Value.PreventIncrementOfMergedBranch; - var message = commit.Message.Trim(); var baseVersionSource = commit; - if (shouldIncrement) + if (commit.IsMergeCommit()) { - var parents = commit.Parents.ToArray(); - if (parents.Length == 2 && message.Contains("Merge branch") && message.Contains("release")) - { - baseVersionSource = this.repositoryStore.FindMergeBase(parents[0], parents[1]); - } + baseVersionSource = this.repositoryStore.FindMergeBase(commit.Parents[0], commit.Parents[1]); } var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null); - var increment = shouldIncrement ? incrementStrategyFinder.DetermineIncrementedField( - currentCommit: Context.CurrentCommit, - baseVersionSource: baseVersionSource, - shouldIncrement: true, - configuration: configuration.Value, - label: label - ) : VersionField.None; + var increment = configuration.Value.PreventIncrementOfMergedBranch + ? VersionField.None : incrementStrategyFinder.DetermineIncrementedField( + currentCommit: Context.CurrentCommit, + baseVersionSource: baseVersionSource, + shouldIncrement: true, + configuration: configuration.Value, + label: label + ); - yield return new BaseVersion($"Merge message '{message}'", mergeMessage.Version, baseVersionSource) + yield return new BaseVersion($"Merge message '{commit.Message.Trim()}'", mergeMessage.Version, null) { Operator = new BaseVersionOperator() { diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TaggedCommitVersionStrategy.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TaggedCommitVersionStrategy.cs index 35cf8075b9..a8a2bd7f61 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TaggedCommitVersionStrategy.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TaggedCommitVersionStrategy.cs @@ -40,14 +40,11 @@ private IEnumerable GetBaseVersionsInternal(EffectiveBranchConfigur ).SelectMany(elements => elements).Distinct().ToArray(); var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null); - var semanticVersionsWithTag = taggedSemanticVersionService.GetTaggedSemanticVersions( - branch: Context.CurrentBranch, - configuration: Context.Configuration, - label: label, - notOlderThan: Context.CurrentCommit.When, - taggedSemanticVersion: configuration.Value.GetTaggedSemanticVersion() - ).SelectMany(elements => elements).Distinct().ToArray(); + var maxTaggedSemanticVersion = taggedSemanticVersions + .Where(element => !element.Value.IsMatchForBranchSpecificLabel(label)) + .Max(); + var semanticVersionsWithTag = taggedSemanticVersions.Where(element => element.Value.IsMatchForBranchSpecificLabel(label)); foreach (var semanticVersionWithTag in semanticVersionsWithTag) { var baseVersionSource = semanticVersionWithTag.Tag.Commit; @@ -65,7 +62,8 @@ private IEnumerable GetBaseVersionsInternal(EffectiveBranchConfigur { Increment = increment, ForceIncrement = false, - Label = label + Label = label, + AlternativeSemanticVersion = maxTaggedSemanticVersion?.Value } }; } diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TrackReleaseBranchesVersionStrategy.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TrackReleaseBranchesVersionStrategy.cs index 6d8ddf164f..ac2f1291a3 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TrackReleaseBranchesVersionStrategy.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TrackReleaseBranchesVersionStrategy.cs @@ -18,7 +18,7 @@ internal sealed class TrackReleaseBranchesVersionStrategy( private readonly IRepositoryStore repositoryStore = repositoryStore.NotNull(); private readonly IBranchRepository branchRepository = branchRepository.NotNull(); private readonly IIncrementStrategyFinder incrementStrategyFinder = incrementStrategyFinder.NotNull(); - private readonly VersionInBranchNameVersionStrategy releaseVersionStrategy = new(contextLazy, repositoryStore); + private readonly VersionInBranchNameVersionStrategy releaseVersionStrategy = new(contextLazy); private GitVersionContext Context => contextLazy.Value; diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TrunkBasedVersionStrategy.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TrunkBasedVersionStrategy.cs index 6d4495491f..4b6efc9697 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TrunkBasedVersionStrategy.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TrunkBasedVersionStrategy.cs @@ -1,4 +1,3 @@ -using System.ComponentModel; using GitVersion.Common; using GitVersion.Configuration; using GitVersion.Core; @@ -53,6 +52,8 @@ internal sealed class TrunkBasedVersionStrategy( new CommitOnTrunkBranchedToNonTrunk(), // NonTrunk + new FirstCommitOnRelease(), + new CommitOnNonTrunk(), new CommitOnNonTrunkWithPreReleaseTag(), new LastCommitOnNonTrunkWithPreReleaseTag(), @@ -74,16 +75,31 @@ public IEnumerable GetBaseVersions(EffectiveBranchConfiguration con if (!Context.Configuration.VersionStrategy.HasFlag(VersionStrategies.TrunkBased)) yield break; - var iteration = CreateIteration(branchName: Context.CurrentBranch.Name, configuration: configuration.Value); + var branchConfiguration = Context.Configuration.GetBranchConfiguration(Context.CurrentBranch); + + var iteration = CreateIteration( + branchName: Context.CurrentBranch.Name, + configuration: branchConfiguration + ); - var commitsInReverseOrder = configuration.Value.Ignore.Filter(Context.CurrentBranchCommits); + var commitsInReverseOrder = Context.Configuration.Ignore.Filter(Context.CurrentBranchCommits); + TaggedSemanticVersions taggedSemanticVersion = TaggedSemanticVersions.OfBranch; + if (branchConfiguration.TrackMergeTarget == true) taggedSemanticVersion |= TaggedSemanticVersions.OfMergeTargets; + if (branchConfiguration.TracksReleaseBranches == true) + { + taggedSemanticVersion |= TaggedSemanticVersions.OfReleaseBranches; + } + if (!(branchConfiguration.IsMainBranch == true || branchConfiguration.IsReleaseBranch == true)) + { + taggedSemanticVersion |= TaggedSemanticVersions.OfMainBranches; + } var taggedSemanticVersions = taggedSemanticVersionService.GetTaggedSemanticVersions( branch: Context.CurrentBranch, configuration: Context.Configuration, label: null, notOlderThan: Context.CurrentCommit.When, - taggedSemanticVersion: configuration.Value.GetTaggedSemanticVersion() + taggedSemanticVersion: taggedSemanticVersion ); var targetLabel = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null); IterateOverCommitsRecursive( @@ -93,18 +109,20 @@ public IEnumerable GetBaseVersions(EffectiveBranchConfiguration con taggedSemanticVersions: taggedSemanticVersions ); - yield return DetermineBaseVersion(iteration, targetLabel); + yield return DetermineBaseVersion(iteration, targetLabel, incrementStrategyFinder, Context.Configuration); } private TrunkBasedIteration CreateIteration( - ReferenceName branchName, EffectiveConfiguration configuration, TrunkBasedIteration? parent = null) + ReferenceName branchName, IBranchConfiguration configuration, + TrunkBasedIteration? parentIteration = null, TrunkBasedCommit? parentCommit = null) { var iterationCount = Interlocked.Increment(ref iterationCounter); - return new( + return new TrunkBasedIteration( id: $"#{iterationCount}", branchName: branchName, configuration: configuration, - parent: parent + parentIteration: parentIteration, + parentCommit: parentCommit ); } @@ -114,77 +132,118 @@ private bool IterateOverCommitsRecursive( { traversedCommits ??= []; - Lazy> commitsWasBranchedFromLazy = new( - () => GetCommitsWasBranchedFrom(branchName: iteration.BranchName) - ); + bool exit = false; var configuration = iteration.Configuration; var branchName = iteration.BranchName; + var branch = repositoryStore.FindBranch(branchName); + + Lazy> commitsWasBranchedFromLazy = new( + () => branch is null + ? new Dictionary() + : GetCommitsWasBranchedFrom(branch) + ); foreach (var item in commitsInReverseOrder) { if (!traversedCommits.Add(item)) continue; if (commitsWasBranchedFromLazy.Value.TryGetValue(item, out var effectiveConfigurationWasBranchedFrom) - && (!configuration.IsMainBranch || effectiveConfigurationWasBranchedFrom.Value.IsMainBranch)) + && (!(configuration.IsMainBranch == true) || effectiveConfigurationWasBranchedFrom.Value.IsMainBranch == true)) { + var excludeBranch = branch; + configuration = effectiveConfigurationWasBranchedFrom.Value; branchName = effectiveConfigurationWasBranchedFrom.Branch.Name; + branch = repositoryStore.FindBranch(branchName); + + commitsWasBranchedFromLazy = new Lazy> + (() => branch is null ? new Dictionary() + : GetCommitsWasBranchedFrom(branch, excludeBranch is null ? Array.Empty() : [excludeBranch]) + ); + + TaggedSemanticVersions taggedSemanticVersion = TaggedSemanticVersions.OfBranch; + if ((configuration.TrackMergeTarget ?? Context.Configuration.TrackMergeTarget) == true) + { + taggedSemanticVersion |= TaggedSemanticVersions.OfMergeTargets; + } + if ((configuration.TracksReleaseBranches ?? Context.Configuration.TracksReleaseBranches) == true) + { + taggedSemanticVersion |= TaggedSemanticVersions.OfReleaseBranches; + } + if (!(configuration.IsMainBranch == true || configuration.IsReleaseBranch == true)) + { + taggedSemanticVersion |= TaggedSemanticVersions.OfMainBranches; + } taggedSemanticVersions = taggedSemanticVersionService.GetTaggedSemanticVersions( branch: effectiveConfigurationWasBranchedFrom.Branch, configuration: Context.Configuration, label: null, notOlderThan: Context.CurrentCommit.When, - taggedSemanticVersion: effectiveConfigurationWasBranchedFrom.Value.GetTaggedSemanticVersion() + taggedSemanticVersion: taggedSemanticVersion ); } - var incrementForcedByCommit = GetIncrementForcedByCommit(item, configuration); - var commit = iteration.CreateCommit(item, branchName, configuration, incrementForcedByCommit); + var commit = iteration.CreateCommit(item, branchName, configuration); var semanticVersions = taggedSemanticVersions[item].ToArray(); commit.AddSemanticVersions(semanticVersions.Select(element => element.Value)); - var label = targetLabel ?? configuration.GetBranchSpecificLabel(branchName, null); + var label = targetLabel ?? new EffectiveConfiguration( + configuration: Context.Configuration, + branchConfiguration: configuration + ).GetBranchSpecificLabel(branchName, null); + foreach (var semanticVersion in semanticVersions) { - if (semanticVersion.Value.IsMatchForBranchSpecificLabel(label)) return true; + if (semanticVersion.Value.IsMatchForBranchSpecificLabel(label)) + { + if (configuration.Increment != IncrementStrategy.Inherit) + { + return true; + } + else + { + exit = true; + } + } + } + + if (exit && configuration.Increment != IncrementStrategy.Inherit) + { + return true; } if (item.IsMergeCommit()) { Lazy> mergedCommitsInReverseOrderLazy = new( - () => incrementStrategyFinder.GetMergedCommits(item, 1, configuration.Ignore).Reverse().ToList() + () => incrementStrategyFinder.GetMergedCommits(item, 1, Context.Configuration.Ignore).Reverse().ToList() ); - if (configuration.TrackMergeMessage + if ((configuration.TrackMergeMessage ?? Context.Configuration.TrackMergeMessage) == true && MergeMessage.TryParse(item, Context.Configuration, out var mergeMessage)) { - if (mergeMessage.Version is not null) - { - commit.AddSemanticVersions(mergeMessage.Version); - return true; - } - if (mergeMessage.MergedBranch is not null) { - var childConfiguration = Context.Configuration.GetEffectiveConfiguration( - mergeMessage.MergedBranch - ); + var childConfiguration = Context.Configuration.GetBranchConfiguration(mergeMessage.MergedBranch); + var childBranchName = mergeMessage.MergedBranch; - if (childConfiguration.IsMainBranch) + if (childConfiguration.IsMainBranch == true) { - if (configuration.IsMainBranch) throw new NotImplementedException(); + if (configuration.IsMainBranch == true) throw new NotImplementedException(); + mergedCommitsInReverseOrderLazy = new( - () => incrementStrategyFinder.GetMergedCommits(item, 0, configuration.Ignore).Reverse().ToList() + () => incrementStrategyFinder.GetMergedCommits(item, 0, Context.Configuration.Ignore).Reverse().ToList() ); childConfiguration = configuration; + childBranchName = iteration.BranchName; } var childIteration = CreateIteration( - branchName: mergeMessage.MergedBranch, + branchName: childBranchName, configuration: childConfiguration, - parent: iteration + parentIteration: iteration, + parentCommit: commit ); var done = IterateOverCommitsRecursive( @@ -206,32 +265,13 @@ private bool IterateOverCommitsRecursive( return false; } - private VersionField GetIncrementForcedByCommit(ICommit commit, EffectiveConfiguration configuration) - { - commit.NotNull(); - configuration.NotNull(); - - return configuration.CommitMessageIncrementing switch - { - CommitMessageIncrementMode.Enabled => incrementStrategyFinder.GetIncrementForcedByCommit(commit, configuration), - CommitMessageIncrementMode.Disabled => VersionField.None, - CommitMessageIncrementMode.MergeMessageOnly => commit.IsMergeCommit() - ? incrementStrategyFinder.GetIncrementForcedByCommit(commit, configuration) : VersionField.None, - _ => throw new InvalidEnumArgumentException( - nameof(configuration.CommitMessageIncrementing), (int)configuration.CommitMessageIncrementing, typeof(CommitMessageIncrementMode) - ) - }; - } - - private IReadOnlyDictionary GetCommitsWasBranchedFrom(ReferenceName branchName) + private IReadOnlyDictionary GetCommitsWasBranchedFrom( + IBranch branch, params IBranch[] excludedBranches) { - Dictionary result = []; - - var branch = repositoryStore.FindBranch(branchName); - if (branch is null) return result; + Dictionary result = new(); var branchCommits = repositoryStore.FindCommitBranchesBranchedFrom( - branch, Context.Configuration + branch, Context.Configuration, excludedBranches: excludedBranches ).ToList(); var branchCommitDictionary = branchCommits.ToDictionary( @@ -240,36 +280,38 @@ private IReadOnlyDictionary GetCommitsWas foreach (var item in branchCommitDictionary.Keys) { var branchConfiguration = Context.Configuration.GetBranchConfiguration(item); - if (branchConfiguration.Increment == IncrementStrategy.Inherit) continue; if (result.ContainsKey(branchCommitDictionary[item])) { + if (branchConfiguration.Increment == IncrementStrategy.Inherit && branchConfiguration.IsMainBranch is null) + { + throw new InvalidOperationException(); + } + if ((branchConfiguration.IsMainBranch ?? Context.Configuration.IsMainBranch) == true - && !result[branchCommitDictionary[item]].Value.IsMainBranch) + && result[branchCommitDictionary[item]].Configuration.IsMainBranch == false) { - result[branchCommitDictionary[item]] - = new(new(Context.Configuration, branchConfiguration), item); + result[branchCommitDictionary[item]] = new(item, branchConfiguration); } } else { - result.Add( - key: branchCommitDictionary[item], - value: new(new(Context.Configuration, branchConfiguration), item) - ); + result.Add(key: branchCommitDictionary[item], value: new(item, branchConfiguration)); } } return result; } - private static BaseVersion DetermineBaseVersion(TrunkBasedIteration iteration, string? targetLabel) - => DetermineBaseVersionRecursive(iteration, targetLabel); + private static BaseVersion DetermineBaseVersion(TrunkBasedIteration iteration, string? targetLabel, + IIncrementStrategyFinder incrementStrategyFinder, IGitVersionConfiguration configuration) + => DetermineBaseVersionRecursive(iteration, targetLabel, incrementStrategyFinder, configuration); - internal static BaseVersion DetermineBaseVersionRecursive(TrunkBasedIteration iteration, string? targetLabel) + internal static BaseVersion DetermineBaseVersionRecursive(TrunkBasedIteration iteration, string? targetLabel, + IIncrementStrategyFinder incrementStrategyFinder, IGitVersionConfiguration configuration) { iteration.NotNull(); - var incrementSteps = GetIncrements(iteration, targetLabel).ToArray(); + var incrementSteps = GetIncrements(iteration, targetLabel, incrementStrategyFinder, configuration).ToArray(); BaseVersion? result = null; for (var i = 0; i < incrementSteps.Length; i++) @@ -283,15 +325,20 @@ internal static BaseVersion DetermineBaseVersionRecursive(TrunkBasedIteration it result ??= new BaseVersion(); result = result.Apply(baseVersionOperator); } + else if (incrementSteps[i] is BaseVersion baseVersion) + { + result = baseVersion; + } } return result ?? throw new InvalidOperationException(); } - private static IEnumerable GetIncrements(TrunkBasedIteration iteration, string? targetLabel) + private static IEnumerable GetIncrements(TrunkBasedIteration iteration, string? targetLabel, + IIncrementStrategyFinder incrementStrategyFinder, IGitVersionConfiguration configuration) { - TrunkBasedContext context = new() + TrunkBasedContext context = new(incrementStrategyFinder, configuration) { - TargetLabel = targetLabel, + TargetLabel = targetLabel }; foreach (var commit in iteration.Commits) diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/VersionInBranchNameVersionStrategy.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/VersionInBranchNameVersionStrategy.cs index 12d1525677..dabbcb6bda 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/VersionInBranchNameVersionStrategy.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/VersionInBranchNameVersionStrategy.cs @@ -1,8 +1,6 @@ using System.Diagnostics.CodeAnalysis; -using GitVersion.Common; using GitVersion.Configuration; using GitVersion.Extensions; -using GitVersion.Git; namespace GitVersion.VersionCalculation; @@ -11,13 +9,9 @@ namespace GitVersion.VersionCalculation; /// BaseVersionSource is the commit where the branch was branched from its parent. /// Does not increment. /// -internal sealed class VersionInBranchNameVersionStrategy( - Lazy contextLazy, - IRepositoryStore repositoryStore) - : IVersionStrategy +internal sealed class VersionInBranchNameVersionStrategy(Lazy contextLazy) : IVersionStrategy { private readonly Lazy contextLazy = contextLazy.NotNull(); - private readonly IRepositoryStore repositoryStore = repositoryStore.NotNull(); private GitVersionContext Context => contextLazy.Value; @@ -39,9 +33,6 @@ public bool TryGetBaseVersion(EffectiveBranchConfiguration configuration, [NotNu if (!configuration.Value.IsReleaseBranch) return false; - Lazy commitBranchWasBranchedFrom = new( - () => this.repositoryStore.FindCommitBranchBranchedFrom(configuration.Branch, Context.Configuration) - ); foreach (var branch in new[] { Context.CurrentBranch, configuration.Branch }) { if (branch.Name.TryGetSemanticVersion(out var result, configuration.Value.VersionInBranchRegex, @@ -56,7 +47,7 @@ public bool TryGetBaseVersion(EffectiveBranchConfiguration configuration, [NotNu var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, branchNameOverride); - baseVersion = new BaseVersion("Version in branch name", result.Value, commitBranchWasBranchedFrom.Value.Commit) + baseVersion = new BaseVersion("Version in branch name", result.Value, null) { Operator = new BaseVersionOperator() { diff --git a/src/GitVersion.Testing/Fixtures/RepositoryFixtureBase.cs b/src/GitVersion.Testing/Fixtures/RepositoryFixtureBase.cs index 74aa84e7ff..c15937ee55 100644 --- a/src/GitVersion.Testing/Fixtures/RepositoryFixtureBase.cs +++ b/src/GitVersion.Testing/Fixtures/RepositoryFixtureBase.cs @@ -67,7 +67,11 @@ protected virtual void Dispose(bool disposing) public void Checkout(string branch) => Commands.Checkout(Repository, branch); - public void Remove(string branch) => Repository.Branches.Remove(branch); + public void Remove(string branch) + { + Repository.Branches.Remove(branch); + SequenceDiagram.Destroy(branch); + } public static void Init(string path, string branchName = "main") => GitTestExtensions.ExecuteGitCmd($"init {path} -b {branchName}"); diff --git a/src/GitVersion.Testing/Fixtures/SequenceDiagram.cs b/src/GitVersion.Testing/Fixtures/SequenceDiagram.cs index c5f93a2c6b..322e7a9355 100644 --- a/src/GitVersion.Testing/Fixtures/SequenceDiagram.cs +++ b/src/GitVersion.Testing/Fixtures/SequenceDiagram.cs @@ -24,6 +24,11 @@ public SequenceDiagram() /// public void Activate(string branch) => this.diagramBuilder.AppendLineFormat("activate {0}", GetParticipant(branch)); + /// + /// Deactivates a branch/participant in the sequence diagram + /// + public void Deactivate(string branch) => this.diagramBuilder.AppendLineFormat("deactivate {0}", GetParticipant(branch)); + /// /// Destroys a branch/participant in the sequence diagram ///