Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Rename ConfigNextVersionVersionStrategy to ConfiguredNextVersionVersi…
…onStrategy
  • Loading branch information
HHobeck committed Jan 28, 2024
commit c5512f289b3e9c2b90b7ad37c65fbb10924b8954
2 changes: 1 addition & 1 deletion BREAKING_CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
* ContinuousDelivery (previously ContinuousDeployment)
* ContinuousDeployment (new)
* At the configuration root level, a new array called `strategies` has been introduced, which can consist of on or more following values:
* ConfigNextVersion
* ConfiguredNextVersion
* MergeMessage
* TaggedCommit
* TrackReleaseBranches
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit unsure about the name TrackReleaseBranches. We should be consistent with whether we use a verb (Track) in the enum values and whether we use singular (Commit) or plural (Branches) form.

Copy link
Contributor Author

@HHobeck HHobeck Jan 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm open to any renaming as long we are renaming the underlying classes who implements the strategy as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is TrackReleaseBranches really a versioning strategy, though? Isn't it more like a branch configuration?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment it is a version strategy yes. What is your suggestion!? To delete it? I thought this is the concept of our core domain to have provider based (strategy based) approach to determine the next version. And you can control whether or not it is called using the strategies property on the configuration root level.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I like the configurable strategy approach. But like next-version, tracks-release-branches is a configuration property. It's strange to have tracks-release-branches configured for a branch, but ignored because TrackReleaseBranches isn't configured.

Copy link
Contributor Author

@HHobeck HHobeck Jan 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here I would say like I already did previously: You need to think of the property like a characteristic of a branch or a characteristic of the repository which is generally isolated of the actual used strategies. If someone decide e.g. not to use the NextVersionVersionStrategy but define next-version then it would be fine to ignore it (Actually if not it would be a bug).

And your second example is even easy to argument. The track-release-braches property will be used in the TrackReleaseBranchesVersionStrategy and TrunkBaseVersionStrategy. If you decide to use TrunkBaseVersionStrategy you should not execute the TrackReleaseBranchesVersionStrategy because it gives you maybe a wrong behavior for the TrunkBased (Mainline) workflow.

Does it make sense?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't think of the possibility of tracks-release-branches being used by more than one strategy. That's not the case for next-version, is it?

Copy link
Contributor Author

@HHobeck HHobeck Jan 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I was mistaken. I have mixed tracks-release-branches with track-merge-message in my mind. You are right tracks-release-branches will be used in TrackReleaseBranchesVersionStrategy and next-version in ConfiguredNextVersionVersionStrategy only. But that can change. Who knows!?

Expand Down
69 changes: 26 additions & 43 deletions docs/input/docs/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ The global configuration looks like this:
assembly-versioning-scheme: MajorMinorPatch
assembly-file-versioning-scheme: MajorMinorPatch
tag-prefix: '[vV]?'
version-in-branch-pattern: (?<version>[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)'
Expand All @@ -53,30 +52,21 @@ commit-date-format: yyyy-MM-dd
merge-message-formats: {}
update-build-number: true
semantic-version-format: Strict
strategies:
- ConfigNextVersion
- MergeMessage
- TaggedCommit
- TrackReleaseBranches
- VersionInBranchName
strategies: [ConfigNext, MergeMessage, TaggedCommit, TrackReleaseBranches, VersionInBranchName]
branches:
develop:
tracks-release-branches: true
is-release-branch: false
is-main-branch: false
pre-release-weight: 0
mode: ContinuousDeployment
label: alpha
increment: Minor
prevent-increment-of-merged-branch-version: false
track-merge-target: true
regex: ^dev(elop)?(ment)?$
source-branches: []
is-source-branch-for: []
main:
tracks-release-branches: false
tracks-release-branches: true
is-release-branch: false
is-main-branch: true
pre-release-weight: 55000
is-main-branch: false
pre-release-weight: 0
main:
label: ''
increment: Patch
prevent-increment-of-merged-branch-version: true
Expand All @@ -85,13 +75,11 @@ branches:
source-branches:
- develop
- release
is-source-branch-for: []
release:
tracks-release-branches: false
is-release-branch: true
is-main-branch: false
pre-release-weight: 30000
mode: ManualDeployment
is-release-branch: false
is-main-branch: true
pre-release-weight: 55000
release:
label: beta
increment: None
prevent-increment-of-merged-branch-version: true
Expand All @@ -102,10 +90,12 @@ branches:
- main
- support
- release
is-source-branch-for: []
feature:
tracks-release-branches: false
is-release-branch: true
is-main-branch: false
pre-release-weight: 30000
mode: ManualDeployment
feature:
mode: ContinuousDelivery
label: '{BranchName}'
increment: Inherit
regex: ^features?[/-](?<BranchName>.+)
Expand All @@ -116,9 +106,8 @@ branches:
- feature
- support
- hotfix
is-source-branch-for: []
pull-request:
pre-release-weight: 30000
pull-request:
mode: ContinuousDelivery
label: PullRequest
increment: Inherit
Expand All @@ -131,11 +120,9 @@ branches:
- feature
- support
- hotfix
is-source-branch-for: []
hotfix:
is-release-branch: true
pre-release-weight: 30000
mode: ManualDeployment
hotfix:
mode: ContinuousDelivery
label: beta
increment: Inherit
regex: ^hotfix(es)?[/-]
Expand All @@ -144,25 +131,24 @@ branches:
- main
- support
- hotfix
is-source-branch-for: []
pre-release-weight: 30000
support:
tracks-release-branches: false
is-release-branch: false
is-main-branch: true
pre-release-weight: 55000
label: ''
increment: Patch
prevent-increment-of-merged-branch-version: true
track-merge-target: false
regex: ^support[/-]
source-branches:
- main
is-source-branch-for: []
tracks-release-branches: false
is-release-branch: false
is-main-branch: true
pre-release-weight: 55000
unknown:
mode: ManualDeployment
mode: ContinuousDelivery
label: '{BranchName}'
increment: Inherit
regex: (?<BranchName>.+)
regex: (?<BranchName>.*)
source-branches:
- main
- develop
Expand All @@ -171,7 +157,6 @@ branches:
- pull-request
- hotfix
- support
is-source-branch-for: []
ignore:
sha: []
mode: ContinuousDelivery
Expand All @@ -182,8 +167,6 @@ track-merge-target: false
track-merge-message: true
commit-message-incrementing: Enabled
regex: ''
source-branches: []
is-source-branch-for: []
tracks-release-branches: false
is-release-branch: false
is-main-branch: false
Expand Down Expand Up @@ -694,7 +677,7 @@ Example of invalid `Strict`, but valid `Loose`
### strategies

Specifies which version strategy implementation (one ore more) will be used to determine the next version. Following values are supported and can be combined:
* ConfigNextVersion
* ConfiguredNextVersion
* MergeMessage
* TaggedCommit
* TrackReleaseBranches
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ merge-message-formats: {}
update-build-number: true
semantic-version-format: Strict
strategies:
- ConfigNextVersion
- ConfiguredNextVersion
- MergeMessage
- TaggedCommit
- TrackReleaseBranches
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ public void OverwritesDefaultsWithProvidedConfig()
public void CombineVersionStrategyConfigNextAndTaggedCommit()
{
// Arrange
SetupConfigFileContent("strategies: [ConfigNextVersion, TaggedCommit]");
SetupConfigFileContent("strategies: [ConfiguredNextVersion, TaggedCommit]");

// Act
var configuration = this.configurationProvider.ProvideForDirectory(this.repoPath);

// Assert
configuration.VersionStrategy.ShouldBe(VersionStrategies.ConfigNextVersion | VersionStrategies.TaggedCommit);
configuration.VersionStrategy.ShouldBe(VersionStrategies.ConfiguredNextVersion | VersionStrategies.TaggedCommit);
}

[Test]
Expand Down
2 changes: 1 addition & 1 deletion src/GitVersion.Configuration/GitVersionConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public string? NextVersion
? VersionCalculation.VersionStrategies.None : VersionStrategies.Aggregate((one, another) => one | another);

[JsonPropertyName("strategies")]
[JsonPropertyDescription($"Specifies which version strategies (one or more) will be used to determine the next version. Following values are available: 'ConfigNextVersion', 'MergeMessage', 'TaggedCommit', 'TrackReleaseBranches', 'VersionInBranchName' and 'TrunkBased'.")]
[JsonPropertyDescription($"Specifies which version strategies (one or more) will be used to determine the next version. Following values are available: 'ConfiguredNextVersion', 'MergeMessage', 'TaggedCommit', 'TrackReleaseBranches', 'VersionInBranchName' and 'TrunkBased'.")]
public VersionStrategies[] VersionStrategies { get; internal set; } = [];

[JsonIgnore]
Expand Down
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the folder called SupportedWorkflows when it's associated with a configuration property called version-strategy? Either we should rename the YAML property to workflow or we should rename the folder to Strategies.

Copy link
Contributor Author

@HHobeck HHobeck Jan 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm correct we have a clash with the term TrunkBased here... What is your suggestion? In the folder SupportedWorkflows we are talking from workflow where in the strategy we are talking from strategy which is something different.

We could define e.g. on the workflow template SupportedWorkflows/TrunkBased/v1.yml to use the strategy TrunkBased,NextVersion to support the next-version configuration as well if it is applicable. Thus there is no one to one relation from workflow to strategy. It's up to you how you would define it.

Edit:
TLDR: The folder called SupportedWorkflows is not associated with a configuration property called version-strategy.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the overlap between strategy and workflow is a bit confusing. Would it be possible to remove strategy completely from configuration and only allow workflow to be configured? Perhaps not in v6, but in v7?

Copy link
Contributor Author

@HHobeck HHobeck Jan 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I saw a lot of issues where the user wants to have it in control which strategies are used or not. The workflows are static and integrated in the assembly. If you delete the strategies then how would the user change the behavior?

Another point here is that we are not defining any hard coded business logic around the workflow. The workflow is just a template which will be used as a base configuration. If the user like he can take the configuration directly with the same effect.

Edit:
What do you think about to name the strategy instead of TrunkBasedStrategy MainlineStrategy?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point wrt. allowing configurability on individual strategies. So we probably want workflow and strategies to be mutually exclusive, no? If not, how would workflow: TrunkBased with strategies: [TaggedCommit] work?

Copy link
Contributor Author

@HHobeck HHobeck Jan 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point wrt. allowing configurability on individual strategies. So we probably want workflow and strategies to be mutually exclusive, no?

The VersionStrategies pattern is the main mechanism to control which strategy will be used to determine the next version. This can be of course changed by the user. Like every time if the user changes the configuration and customizes their own workflow he needs to ensure the correct behavior as well. Because it is hard work to build a workflow we as contributors are providing a supported workflow templates (at this moment GitHubFlow, GitFlow and TrunkBased and maybe more in future) to help the user get there build pipe up and running. And for this workflows we give a support.

Comming to your question: You only can answer this question if it is working or not if you know what workflow the user wants to implement. Because we don't know what the workflow might be we cannot do any assumptions about it. In best case it has just a performance impact in worst case the user gets a version number he would not expect.

Edit:

If not, how would workflow: TrunkBased with strategies: [TaggedCommit] work?

The scenario you are describing here would be a customization of the TrunkBased workflow. This setting would of course break everything. But the user is responsible to ensure the behavior by himself when customizing. Changing configuration is only for advanced user who understanding what they are doing. Again the used workflow template is only a base template which can be overwritten. For the version calculation GitVersion doesn't care if you use a base workspace and customize it afterwards or provide a full configuration from scratch without the usage of a base workflow. It is equivalent and the result is the same.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I just want us to be on the same page here and offer the best possible developer experience when interacting with these new configuration properties. That's why I thought strategies and workflow could be made mutually exclusive; you either use one or the other. GitVersion would simply return an error if both properties are present in GitVersion.yml.

I think that's going to lead to fewer problems (i.e. fewer filed issues on GitHub) than allowing developers to mix workflow and strategies. From my years of experience maintaining API surfaces like this, it's wise to start out restrictive and increase flexibility over time. If we start out flexible, allowing strategies and workflow to be mixed, it's going to be much harder adding restrictions on their usage in the future.

If we are to allow strategies and workflow simultaneously, we need to figure out whether strategies are additive or reductive to the ones implicitly added by workflow, for instance. I say we just avoid having to answer that question by not allowing it.

Copy link
Contributor Author

@HHobeck HHobeck Jan 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm actually not a big fan of being a guardian for the user and protecting them for themselves. I would say to document it and make a attention sign that only advanced user who knows what they are doing should change this field.

Anyway if we do it like you mentioned how would the users of the following issues use this feature?

My expectation would be if you want to skip the MergeMessageVersionStrategy you need to change the configuration as following:

workflow: GitFlow/v1
strategies: [ConfiguredNextVersion, TaggedCommit, TrackReleaseBranches, VersionInBranchName]

and if you want to skip VersionInBranchNameVersionStrategy you write:

workflow: GitFlow/v1
strategies: [ConfiguredNextVersion, MergeMessage, TaggedCommit, TrackReleaseBranches]

That means the strategies array is not additive.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ commit-date-format: yyyy-MM-dd
merge-message-formats: {}
update-build-number: true
semantic-version-format: Strict
strategies: [TrunkBased, ConfigNextVersion]
strategies: [TrunkBased, ConfiguredNextVersion]
branches:
main:
mode: ContinuousDeployment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace GitVersion.Core.Tests.VersionCalculation.Strategies;

[TestFixture]
public class ConfigNextVersionBaseVersionStrategyTests : TestBase
public class ConfiguredNextVersionBaseVersionStrategyTests : TestBase
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like the class name here contains BaseVersion for no particular reason?

Suggested change
public class ConfiguredNextVersionBaseVersionStrategyTests : TestBase
public class ConfiguredNextVersionStrategyTests : TestBase

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

{
[Test]
public void ReturnsNullWhenNoNextVersionIsInConfig()
Expand All @@ -22,7 +22,7 @@ public void ReturnsNullWhenNoNextVersionIsInConfig()
[TestCase("2.12.654651698", "2.12.654651698", SemanticVersionFormat.Strict)]
[TestCase("2.12.654651698", "2.12.654651698", SemanticVersionFormat.Loose)]
[TestCase("0.1", "0.1.0", SemanticVersionFormat.Loose)]
public void ConfigNextVersionTest(string nextVersion, string expectedVersion, SemanticVersionFormat versionFormat)
public void ConfiguredNextVersionTest(string nextVersion, string expectedVersion, SemanticVersionFormat versionFormat)
{
var overrideConfiguration = new Dictionary<object, object?>
{
Expand All @@ -37,7 +37,7 @@ public void ConfigNextVersionTest(string nextVersion, string expectedVersion, Se
}

[TestCase("0.1", SemanticVersionFormat.Strict)]
public void ConfigNextVersionTestShouldFail(string nextVersion, SemanticVersionFormat versionFormat)
public void ConfiguredNextVersionTestShouldFail(string nextVersion, SemanticVersionFormat versionFormat)
{
var overrideConfiguration = new Dictionary<object, object?>
{
Expand All @@ -54,7 +54,7 @@ public void ConfigNextVersionTestShouldFail(string nextVersion, SemanticVersionF
var contextBuilder = new GitVersionContextBuilder().WithOverrideConfiguration(overrideConfiguration);
contextBuilder.Build();
contextBuilder.ServicesProvider.ShouldNotBeNull();
var strategy = contextBuilder.ServicesProvider.GetServiceForType<IVersionStrategy, ConfigNextVersionVersionStrategy>();
var strategy = contextBuilder.ServicesProvider.GetServiceForType<IVersionStrategy, ConfiguredNextVersionVersionStrategy>();
var context = contextBuilder.ServicesProvider.GetRequiredService<Lazy<GitVersionContext>>().Value;
var branchMock = GitToolsTestingExtensions.CreateMockBranch("main", GitToolsTestingExtensions.CreateMockCommit());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal static class ConfigurationConstants
public const AssemblyFileVersioningScheme DefaultAssemblyFileVersioningScheme = AssemblyFileVersioningScheme.MajorMinorPatch;
public const SemanticVersionFormat DefaultSemanticVersionFormat = SemanticVersionFormat.Strict;
public static readonly VersionStrategies[] DefaultVersionStrategies = [
VersionStrategies.ConfigNextVersion,
VersionStrategies.ConfiguredNextVersion,
VersionStrategies.MergeMessage,
VersionStrategies.TaggedCommit,
VersionStrategies.TrackReleaseBranches,
Expand Down
2 changes: 1 addition & 1 deletion src/GitVersion.Core/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ GitVersion.VersionCalculation.VersionCalculationModule
GitVersion.VersionCalculation.VersionCalculationModule.RegisterTypes(Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> void
GitVersion.VersionCalculation.VersionCalculationModule.VersionCalculationModule() -> void
GitVersion.VersionCalculation.VersionStrategies
GitVersion.VersionCalculation.VersionStrategies.ConfigNextVersion = 1 -> GitVersion.VersionCalculation.VersionStrategies
GitVersion.VersionCalculation.VersionStrategies.ConfiguredNextVersion = 1 -> GitVersion.VersionCalculation.VersionStrategies
GitVersion.VersionCalculation.VersionStrategies.MergeMessage = 2 -> GitVersion.VersionCalculation.VersionStrategies
GitVersion.VersionCalculation.VersionStrategies.None = 0 -> GitVersion.VersionCalculation.VersionStrategies
GitVersion.VersionCalculation.VersionStrategies.TaggedCommit = 4 -> GitVersion.VersionCalculation.VersionStrategies
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ namespace GitVersion.VersionCalculation;
/// BaseVersionSource is null.
/// Does not increment.
/// </summary>
internal class ConfigNextVersionVersionStrategy(Lazy<GitVersionContext> versionContext) : VersionStrategyBase(versionContext)
internal class ConfiguredNextVersionVersionStrategy(Lazy<GitVersionContext> versionContext) : VersionStrategyBase(versionContext)
{
public override IEnumerable<BaseVersion> GetBaseVersions(EffectiveBranchConfiguration configuration)
{
if (!Context.Configuration.VersionStrategy.HasFlag(VersionStrategies.ConfigNextVersion))
if (!Context.Configuration.VersionStrategy.HasFlag(VersionStrategies.ConfiguredNextVersion))
yield break;

var contextConfiguration = Context.Configuration;
Expand Down
4 changes: 2 additions & 2 deletions src/GitVersion.Core/VersionCalculation/VersionStrategies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ namespace GitVersion.VersionCalculation;
public enum VersionStrategies
{
None = 0,
ConfigNextVersion = 1,
ConfiguredNextVersion = 1,
MergeMessage = 2,
TaggedCommit = 4,
TrackReleaseBranches = 8,
VersionInBranchName = 16,
TrunkBased = 32,
TrunkBased = 32
}