diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 3aea86e6e8..6eb678197f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -110,7 +110,7 @@ jobs: uses: chabad360/htmlproofer@master with: directory: ./artifacts/docs/preview - arguments: --ignore-urls /api/,/docs/ --allow-hash-href --assume-extension --disable-external --no-check_external_hash + arguments: --ignore-urls /api/,/docs/ --allow-hash-href --allow-missing-href --assume-extension --disable-external --no-check_external_hash - name: '[Reviewdog Reporter]' id: reporter diff --git a/.github/workflows/mkdocs.yml b/.github/workflows/mkdocs.yml new file mode 100644 index 0000000000..83550f71b6 --- /dev/null +++ b/.github/workflows/mkdocs.yml @@ -0,0 +1,42 @@ +name: Markdown Update +on: + push: + +env: + DOTNET_ROLL_FORWARD: "Major" + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_NOLOGO: 1 + +defaults: + run: + shell: pwsh + +jobs: + docs: + name: Update Markdown (embedded snippets) + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Run MarkdownSnippets + run: | + dotnet tool install --global MarkdownSnippets.Tool + mdsnippets --write-header false + working-directory: ${{ github.workspace }}/docs/input + - + name: Check for changes + id: status + run: | + if ($null -ne (git status --porcelain)) { echo "has_changes=1"; echo "has_changes=1" >> $env:GITHUB_OUTPUT } + - + name: Push changes + run: | + git add --verbose . + git config user.name 'Artur Stolear' + git config user.email 'artur.stolear@gmail.com' + git commit -m 'Docs changes' --allow-empty + git push --force + if: steps.status.outputs.has_changes == '1' \ No newline at end of file diff --git a/build/CI.sln b/build/CI.sln index 67ace32076..4a5f522977 100644 --- a/build/CI.sln +++ b/build/CI.sln @@ -42,6 +42,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ ..\.github\workflows\_unit_tests.yml = ..\.github\workflows\_unit_tests.yml ..\.github\workflows\stale.yml = ..\.github\workflows\stale.yml ..\.github\workflows\winget.yml = ..\.github\workflows\winget.yml + ..\.github\workflows\mkdocs.yml = ..\.github\workflows\mkdocs.yml ..\.github\dependabot.yml = ..\.github\dependabot.yml EndProjectSection EndProject diff --git a/build/docs/BuildLifetime.cs b/build/docs/BuildLifetime.cs index 262ef513bc..db7ab45317 100644 --- a/build/docs/BuildLifetime.cs +++ b/build/docs/BuildLifetime.cs @@ -20,14 +20,18 @@ public override void Setup(BuildContext context, ISetupContext info) Theme = "Samson", OutputPath = context.MakeAbsolute(Paths.ArtifactsDocs.Combine("preview")), RootPath = context.MakeAbsolute(Paths.Docs), - ConfigurationFile = context.MakeAbsolute(Paths.Docs.CombineWithFilePath("config.wyam")), Settings = new Dictionary { { "BaseEditUrl", "https://github.com/gittools/GitVersion/tree/main/docs/input/" }, { "SourceFiles", context.MakeAbsolute(Paths.Src) + "/**/{!bin,!obj,!packages,!*.Tests,!GitTools.*,}/**/*.cs" }, { "Title", "GitVersion" }, - { "IncludeGlobalNamespace", false } - } + { "IncludeGlobalNamespace", false }, + { "IgnoreFolders", "**/mdsource" } + }, + EnvironmentVariables = new Dictionary + { + { "DOTNET_ROLL_FORWARD", "Major" }, + }, }; context.StartGroup("Build Setup"); diff --git a/build/docs/Tasks/PublishDocs.cs b/build/docs/Tasks/PublishDocs.cs index 23f0e29056..c4463d3cb6 100644 --- a/build/docs/Tasks/PublishDocs.cs +++ b/build/docs/Tasks/PublishDocs.cs @@ -58,7 +58,7 @@ private static bool AnyDocsChanged(ICakeContext context) var filesChanged = context.GitDiff(Paths.Root, sourceCommit.Sha); const string path = "docs/"; - var docFileChanged = filesChanged.Any(file => file.OldPath.StartsWith(path) || file.Path.StartsWith(path) || file.Path.Contains("config.wyam")); + var docFileChanged = filesChanged.Any(file => file.OldPath.StartsWith(path) || file.Path.StartsWith(path)); return docFileChanged; } diff --git a/docs/config.wyam b/docs/config.wyam deleted file mode 100644 index c242a361ce..0000000000 --- a/docs/config.wyam +++ /dev/null @@ -1 +0,0 @@ -Pipelines["RenderPages"].Replace("WriteMetadata", new Headings(2)); diff --git a/docs/input/docs/reference/configuration.md b/docs/input/docs/reference/configuration.md index bf1541109f..35e874cd32 100644 --- a/docs/input/docs/reference/configuration.md +++ b/docs/input/docs/reference/configuration.md @@ -38,7 +38,9 @@ tag-prefix: '[abc]' The built-in configuration for the `GitFlow` workflow (`workflow: GitFlow/v1`) looks like: -```yaml + + +```yml assembly-versioning-scheme: MajorMinorPatch assembly-file-versioning-scheme: MajorMinorPatch tag-prefix: '[vV]?' @@ -207,10 +209,14 @@ tracks-release-branches: false is-release-branch: false is-main-branch: false ``` +snippet source | anchor + The supported built-in configuration for the `GitHubFlow` workflow (`workflow: GitHubFlow/v1`) looks like: -```yaml + + +```yml assembly-versioning-scheme: MajorMinorPatch assembly-file-versioning-scheme: MajorMinorPatch tag-prefix: '[vV]?' @@ -270,12 +276,12 @@ branches: increment: Inherit prevent-increment: when-current-commit-tagged: false + track-merge-message: true regex: ^features?[/-](?.+) source-branches: - main - release is-source-branch-for: [] - track-merge-message: true is-main-branch: false pre-release-weight: 30000 pull-request: @@ -286,13 +292,13 @@ branches: of-merged-branch: true when-current-commit-tagged: false label-number-pattern: '[/-](?\d+)' + track-merge-message: true regex: ^(pull|pull\-requests|pr)[/-] source-branches: - main - release - feature is-source-branch-for: [] - track-merge-message: true pre-release-weight: 30000 unknown: mode: ManualDeployment @@ -300,6 +306,7 @@ branches: increment: Inherit prevent-increment: when-current-commit-tagged: false + track-merge-message: false regex: (?.+) source-branches: - main @@ -307,7 +314,6 @@ branches: - feature - pull-request is-source-branch-for: [] - track-merge-message: false is-main-branch: false ignore: sha: [] @@ -328,10 +334,14 @@ tracks-release-branches: false is-release-branch: false is-main-branch: false ``` +snippet source | anchor + The preview built-in configuration (experimental usage only) for the `TrunkBased` workflow (`workflow: TrunkBased/preview1`) looks like: -```yaml + + +```yml assembly-versioning-scheme: MajorMinorPatch assembly-file-versioning-scheme: MajorMinorPatch tag-prefix: '[vV]?' @@ -346,8 +356,8 @@ merge-message-formats: {} update-build-number: true semantic-version-format: Strict strategies: -- Mainline - ConfiguredNextVersion +- Mainline branches: main: mode: ContinuousDeployment @@ -355,46 +365,65 @@ branches: increment: Patch prevent-increment: of-merged-branch: true - when-current-commit-tagged: true track-merge-target: false + track-merge-message: true regex: ^master$|^main$ source-branches: [] + is-source-branch-for: [] tracks-release-branches: false is-release-branch: false is-main-branch: true pre-release-weight: 55000 feature: + mode: ContinuousDelivery + label: '{BranchName}' increment: Minor - regex: ^features?[/-](?.+) prevent-increment: when-current-commit-tagged: false + track-merge-message: true + regex: ^features?[/-](?.+) source-branches: - main + is-source-branch-for: [] + is-main-branch: false pre-release-weight: 30000 hotfix: + mode: ContinuousDelivery + label: '{BranchName}' increment: Patch - regex: ^hotfix(es)?[/-](?.+) prevent-increment: when-current-commit-tagged: false + regex: ^hotfix(es)?[/-](?.+) source-branches: - main + is-source-branch-for: [] + is-release-branch: 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+)' + track-merge-message: true regex: ^(pull|pull\-requests|pr)[/-] source-branches: - main + - feature + - hotfix + is-source-branch-for: [] pre-release-weight: 30000 unknown: increment: Patch - regex: (?.+) prevent-increment: when-current-commit-tagged: false + regex: (?.+) source-branches: - main + is-source-branch-for: [] pre-release-weight: 30000 ignore: sha: [] @@ -409,10 +438,14 @@ 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 ``` +snippet source | anchor + The details of the available options are as follows: diff --git a/docs/input/docs/reference/mdsource/configuration.source.md b/docs/input/docs/reference/mdsource/configuration.source.md new file mode 100644 index 0000000000..74b76fa054 --- /dev/null +++ b/docs/input/docs/reference/mdsource/configuration.source.md @@ -0,0 +1,570 @@ +--- +Order: 10 +Title: Configuration +Description: Details about how GitVersion can be configured to suit your needs +RedirectFrom: docs/configuration +--- + +GitVersion, starting from version 3.0, is mainly powered by configuration and no +longer has branching strategies hard-coded. + +:::{.alert .alert-info} +**Note** + +GitVersion ships with internal default configuration which works with +GitHubFlow and GitFlow, probably with others too. +::: + +The `develop` branch is set to `ContinuousDeployment` mode by default as we have +found that is generally what is needed when using GitFlow. + +To see the effective configuration (defaults and overrides), you can run +`gitversion /showConfig`. + +## Global configuration + +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/preview1) + +Example of using a `GitHubFlow` workflow with a different `tag-prefix`: + +```yaml +workflow: GitHubFlow/v1 +tag-prefix: '[abc]' +``` + +The built-in configuration for the `GitFlow` workflow (`workflow: GitFlow/v1`) looks like: + +snippet: /docs/workflows/GitFlow/v1.yml + +The supported built-in configuration for the `GitHubFlow` workflow (`workflow: GitHubFlow/v1`) looks like: + +snippet: /docs/workflows/GitHubFlow/v1.yml + +The preview built-in configuration (experimental usage only) for the `TrunkBased` workflow (`workflow: TrunkBased/preview1`) looks like: + +snippet: /docs/workflows/TrunkBased/preview1.yml + +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`. 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 +feature branch with breaking changes (i.e., a major increment), indicating what +the next `git tag` is going to be. + +`next-version` is not a permanent replacement for `git tag` and should only be +used intermittently. Since version 5.5 GitVersion supports `next-version` with +`mode: Mainline` and should not be treated as a "base version". + +If you are using `next-version` and are experiencing weird versioning behaviour, +please remove it, create a `git tag` with an appropriate version number on an +appropriate historical commit and see if that resolves any versioning issues +you may have. + +### assembly-versioning-scheme + +When updating assembly info, `assembly-versioning-scheme` tells GitVersion how +to treat the `AssemblyVersion` attribute. Useful to lock the major when using +Strong Naming. Note: you can use `None` to skip updating the `AssemblyVersion` +while still updating the `AssemblyFileVersion` and `AssemblyInformationVersion` +attributes. Valid values: `MajorMinorPatchTag`, `MajorMinorPatch`, `MajorMinor`, +`Major`, `None`. + +### assembly-file-versioning-scheme + +When updating assembly info, `assembly-file-versioning-scheme` tells GitVersion +how to treat the `AssemblyFileVersion` attribute. Note: you can use `None` to +skip updating the `AssemblyFileVersion` while still updating the +`AssemblyVersion` and `AssemblyInformationVersion` attributes. Valid values: +`MajorMinorPatchTag`, `MajorMinorPatch`, `MajorMinor`, `Major`, `None`. + +### assembly-file-versioning-format + +Specifies the format of `AssemblyFileVersion` and +overwrites the value of `assembly-file-versioning-scheme`. + +Expressions in curly braces reference one of the [variables][variables] +or a process-scoped environment variable (when prefixed with `env:`). For example, + +```yaml +# use a variable if non-null or a fallback value otherwise +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{WeightedPreReleaseNumber ?? 0}' + +# use an environment variable or raise an error if not available +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER}' + +# use an environment variable if available or a fallback value otherwise +assembly-file-versioning-format: '{Major}.{Minor}.{Patch}.{env:BUILD_NUMBER ?? 42}' +``` + +### assembly-versioning-format + +Specifies the format of `AssemblyVersion` and +overwrites the value of `assembly-versioning-scheme`. +Follows the same formatting semantics as `assembly-file-versioning-format`. + +### assembly-informational-format + +Specifies the format of `AssemblyInformationalVersion`. +Follows the same formatting semantics as `assembly-file-versioning-format`. +The default value is `{InformationalVersion}`. + +### mode + +Sets the `mode` of how GitVersion should create a new version. Read more at +[deployment modes][modes]. + +### increment + +The part of the SemVer to increment when GitVersion detects it needs to be +increased, such as for commits after a tag: `Major`, `Minor`, `Patch`, `None`. + +The special value `Inherit` means that GitVersion should find the parent branch +(i.e. the branch where the current branch was branched from), and use its values +for [increment](#increment) or other branch related properties. + +### tag-prefix + +A regular expression which is used to trim Git tags before processing (e.g., +v1.0.0). The default value is `[vV]`. + +### version-in-branch-pattern + +A regular expression which is used to determine the version number in the branch +name or commit message (e.g., v1.0.0-LTS). This setting only applies on branches +where the option `is-release-branch` is set to `true`. The default value is +`(?[vV]?\d+(\.\d+)?(\.\d+)?).*`. + +### major-version-bump-message + +The regex to match commit messages with to perform a major version increment. +Default set to `'\+semver:\s?(breaking|major)'`, which will match occurrences of +`+semver: major` and `+semver: breaking` in a commit message. + +### minor-version-bump-message + +The regex to match commit messages with to perform a minor version increment. +Default set to `'\+semver:\s?(feature|minor)'`, which will match occurrences of +`+semver: feature` and `+semver: minor` in a commit message. + +### patch-version-bump-message + +The regex to match commit messages with to perform a patch version increment. +Default set to `'\+semver:\s?(fix|patch)'`, which will match occurrences of +`+semver: fix` and `+semver: patch` in a commit message. + +### no-bump-message + +Used to tell GitVersion not to increment when in Mainline development mode. +Default `\+semver:\s?(none|skip)`, which will match occurrences of `+semver: +none` and `+semver: skip` + +When a commit matches **both** the `no-bump-message` **and** any combination of +the `version-bump-message`, `no-bump-message` takes precedence and no increment is applied. + +### tag-pre-release-weight + +The pre-release weight in case of tagged commits. If the value is not set in the +configuration, a default weight of 60000 is used instead. If the +`WeightedPreReleaseNumber` [variable][variables] is 0 and this parameter is set, +its value is used. This helps if your branching model is GitFlow and the last +release build, which is often tagged, can utilize this parameter to produce a +monotonically increasing build number. + +### commit-message-incrementing + +Sets whether it should be possible to increment the version with special syntax +in the commit message. See the `*-version-bump-message` options above for +details on the syntax. Default set to `Enabled`; set to `Disabled` to disable. + +### commit-date-format + +Sets the format which will be used to format the `CommitDate` output variable. + +### ignore + +The header property for the `ignore` configuration. + +:::{.alert .alert-info} +**Note:** When ignoring a commit or a range of commits, they are only ignored in +the search for a [version source][version-sources], not when calculating other +parts of the version number, such as build metadata. +::: + +#### sha + +A sequence of SHAs to be excluded from the version calculations. Useful when +there is a rogue commit in history yielding a bad version. You can use either +style below: + +```yaml +ignore: + sha: [e7bc24c0f34728a25c9187b8d0b041d935763e3a, 764e16321318f2fdb9cdeaa56d1156a1cba307d7] +``` + +or + +```yaml +ignore: + sha: + - e7bc24c0f34728a25c9187b8d0b041d935763e3a + - 764e16321318f2fdb9cdeaa56d1156a1cba307d7 +``` + +#### commits-before + +Date and time in the format `yyyy-MM-ddTHH:mm:ss` (eg `commits-before: +2015-10-23T12:23:15`) to setup an exclusion range. Effectively any commit before +`commits-before` will be ignored. + +### merge-message-formats + +Custom merge message formats to enable identification of merge messages that do not +follow the built-in conventions. Entries should be added as key-value pairs where +the value is a regular expression. +e.g. + +```yaml +merge-message-formats: + tfs: '^Merged (?:PR (?\d+)): Merge (?.+) to (?.+)' +``` + +The regular expression should contain the following capture groups: + +- `SourceBranch` - Identifies the source branch of the merge +- `TargetBranch` - Identifies the target branch of the merge +- `PullRequestNumber` - Captures the pull-request number + +Custom merge message formats are evaluated _before_ any built in formats. +Support for [Conventional Commits][conventional-commits] can be +[configured][conventional-commits-config]. + +### update-build-number + +Configures GitVersion to update the build number or not when running on a build server. + +## Branch configuration + +Then we have branch specific configuration, which looks something like this: + +:::{.alert .alert-info} +**Note** + +v4 changed from using regexes for keys, to named configs +::: + +If you have branch specific configuration upgrading to v4 will force you to +upgrade. + +```yaml +branches: + main: + regex: ^master$|^main$ + mode: ContinuousDelivery + label: '' + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'develop', 'release' ] + tracks-release-branches: false + is-release-branch: false + is-main-branch: true + pre-release-weight: 55000 + develop: + regex: ^dev(elop)?(ment)?$ + mode: ContinuousDeployment + label: alpha + increment: Minor + prevent-increment-of-merged-branch-version: false + track-merge-target: true + source-branches: [] + tracks-release-branches: true + is-release-branch: false + is-main-branch: false + pre-release-weight: 0 + release: + regex: ^releases?[/-] + mode: ContinuousDelivery + label: beta + increment: None + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'develop', 'main', 'support', 'release' ] + tracks-release-branches: false + is-release-branch: true + is-main-branch: false + pre-release-weight: 30000 + feature: + regex: ^features?[/-] + mode: ContinuousDelivery + label: '{BranchName}' + increment: Inherit + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + pre-release-weight: 30000 + pull-request: + regex: ^(pull|pull\-requests|pr)[/-] + mode: ContinuousDelivery + label: PullRequest + increment: Inherit + label-number-pattern: '[/-](?\d+)[-/]' + source-branches: [ 'develop', 'main', 'release', 'feature', 'support', 'hotfix' ] + pre-release-weight: 30000 + hotfix: + regex: ^hotfix(es)?[/-] + mode: ContinuousDelivery + label: beta + increment: Inherit + source-branches: [ 'release', 'main', 'support', 'hotfix' ] + pre-release-weight: 30000 + support: + regex: ^support[/-] + mode: ContinuousDelivery + label: '' + increment: Patch + prevent-increment-of-merged-branch-version: true + track-merge-target: false + source-branches: [ 'main' ] + tracks-release-branches: false + is-release-branch: false + is-main-branch: true + pre-release-weight: 55000 +``` + +If you don't specify the regex, the built-in for that branch config will be +used (recommended). + +We don't envision many people needing to change most of these configuration +values, but here they are if you need to: + +### regex + +This is the regex which is used to match the current branch to the correct +branch configuration. + +[Named groups](https://learn.microsoft.com/en-us/dotnet/standard/base-types/grouping-constructs-in-regular-expressions#named-matched-subexpressions) can be used to dynamically label pre-releases based on the branch name, or parts of it. See [Label](#label) for more details and examples. + +### source-branches + +Because Git commits only refer to parent commits (not branches) GitVersion +sometimes cannot tell which branch the current branch was branched from. + +Take this commit graph + +```shell +* release/v1.0.0 * feature/foo +| ________________/ +|/ +* +* +* (main) +``` + +By looking at this graph, you cannot tell which of these scenarios happened: + +- feature/foo branches off release/v1.0.0 + - Branch release/v1.0.0 from main + - Branch feature/foo from release/v1.0.0 + - Add a commit to both release/v1.0.0 and feature/foo + - release/v1.0.0 is the base for feature/foo +- release/v1.0.0 branches off feature/foo + - Branch feature/foo from main + - Branch release/v1.0.0 from feature/foo + - Add a commit to both release/v1.0.0 and feature/foo + - feature/foo is the base for release/v1.0.0 + +Or put more simply, you cannot tell which branch was created first, +`release/v1.0.0` or `feature/foo`. + +To resolve this issue, we give GitVersion a hint about our branching workflows +by telling it what types of branches a branch can be created from. For example, +feature branches are, by default, configured to have the following source +branches: + +`source-branches: ['main', 'develop', 'feature', 'hotfix', 'support']` + +This means that we will never bother to evaluate pull request branches as merge +base options and being explicit in this way also improves the performance of +GitVersion. + +### is-source-branch-for + +The reverse of `source-branches`. This property was introduced to keep it easy +to extend GitVersion's config. + +It exists to make it easier to extend GitVersion's configuration. If only +`source-branches` exists and you add a new branch type, for instance +`unstable/`, you then need to re-define the `source-branches` configuration +value for existing branches (like feature/) to now include the new unstable +branch. + +A complete example: + +```yaml +branches: + unstable: + regex: ... + is-source-branch-for: ['main', 'develop', 'feature', 'hotfix', 'support'] +``` + +Without this configuration value you would have to do: + +```yaml +branches: + unstable: + regex: + feature: + source-branches: ['unstable', 'develop', 'feature', 'hotfix', 'support'] + release: + source-branches: ['unstable', 'develop'] + etc... +``` + +### branches + +The header for all the individual branch configuration. + +### mode + +Same as for the [global configuration, explained above](#mode). + +### label + +The pre-release label to use for this branch. Use the value `{BranchName}` as a placeholder to +insert the value of the named group `BranchName` from the [regular expression](#regex). + +For example: branch `feature/foo` would become a pre-release label +of `alpha.foo` with `label: 'alpha.{BranchName}'` and `regex: '^features?[/-](?.+)'`. + +Another example: branch `features/sc-12345/some-description` would become a pre-release label of `sc-12345` with `label: '{StoryNo}'` and `regex: '^features?[/-](?sc-\d+)[-/].+'`. + +**Note:** To clear a default use an empty string: `label: ''` + +### increment + +Same as for the [global configuration, explained above](#increment). + +### prevent-increment-of-merged-branch + +The increment of the branch merged to will be ignored, regardless of whether the merged branch has a version number or not, when this branch related property is set to true on the target branch. + +When `release-2.0.0` is merged into main, we want main to build `2.0.0`. If +`release-2.0.0` is merged into develop we want it to build `2.1.0`, this option +prevents incrementing after a versioned branch is merged. + +In a GitFlow-based repository, setting this option can have implications on the +`CommitsSinceVersionSource` output variable. It can rule out a potentially +better version source proposed by the `MergeMessageBaseVersionStrategy`. For +more details and an in-depth analysis, please see [the discussion][2506]. + +### prevent-increment-when-branch-merged + +The increment of the merged branch will be ignored when this branch related property is set to `true` on the source branch. + +### prevent-increment-when-current-commit-tagged + +This branch related property controls the behvior whether to use the tagged (value set to true) or the incremented (value set to false) semantic version. Defaults to true. + +### label-number-pattern + +Pull requests require us to extract the pre-release number out of the branch +name so `refs/pulls/534/merge` builds as `PullRequest.534`. This is a regex with +a named capture group called `number`. + +If the branch `mode` is set to `ContinuousDeployment`, then the extracted +`number` is appended to the name of the pre-release label and the number portion +is the number of commits since the last label. This enables consecutive commits to +the pull request branch to generate unique full semantic version numbers when +the branch is configured to use ContinuousDeployment mode. + +**Example usage:** + +```yaml +branches: + pull-request: + mode: ContinuousDeployment + label: PullRequest + increment: Inherit + track-merge-target: true + label-number-pattern: '[/-](?\d+)[-/]' +``` + +### track-merge-target + +Strategy which will look for tagged merge commits directly off the current +branch. For example `develop` → `release/1.0.0` → merge into `main` and tag +`1.0.0`. The tag is _not_ on develop, but develop should be version `1.0.0` now. + +### track-merge-message + +This property is a branch related property and gives the user the possibility to control the behavior of whether the merge +commit message will be interpreted as a next version or not. Consider we have a main branch and a `release/1.0.0` branch and +merge changes from `release/1.0.0` to the `main` branch. If `track-merge-message` is set to `true` then the next version will +be `1.0.0` otherwise `0.0.1`. + +### tracks-release-branches + +Indicates this branch config represents develop in GitFlow. + +### is-release-branch + +Indicates this branch config represents a release branch in GitFlow. + +### is-main-branch + +This indicates that this branch is a main branch. By default `main` and `support/*` are main branches. + +### pre-release-weight + +Provides a way to translate the `PreReleaseLabel` ([variables][variables]) to a numeric +value in order to avoid version collisions across different branches. For +example, a release branch created after "1.2.3-alpha.55" results in +"1.2.3-beta.1" and thus e.g. "1.2.3-alpha.4" and "1.2.3-beta.4" would have the +same file version: "1.2.3.4". One of the ways to use this value is to set +`assembly-file-versioning-format: +{Major}.{Minor}.{Patch}.{WeightedPreReleaseNumber}`. If the `pre-release-weight` +is set, it would be added to the `PreReleaseNumber` to get a final +`AssemblySemFileVer`, otherwise a branch specific default for +`pre-release-weight` will be used in the calculation. Related Issues [1145][1145] +and [1366][1366]. + +### semantic-version-format + +Specifies the semantic version format that is used when parsing the string. +Can be `Strict` - using the [regex](https://regex101.com/r/Ly7O1x/3/) +or `Loose` the old way of parsing. The default if not specified is `Strict` +Example of invalid `Strict`, but valid `Loose` + +``` log +1.2-alpha4 +01.02.03-rc03 +1.2.3.4 +``` + +### 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: + +- Fallback +- ConfiguredNextVersion +- MergeMessage +- TaggedCommit +- TrackReleaseBranches +- VersionInBranchName +- TrunkBased + +[1145]: https://github.com/GitTools/GitVersion/issues/1145 +[1366]: https://github.com/GitTools/GitVersion/issues/1366 +[2506]: https://github.com/GitTools/GitVersion/pull/2506#issuecomment-754754037 +[conventional-commits-config]: /docs/reference/version-increments#conventional-commit-messages +[conventional-commits]: https://www.conventionalcommits.org/ +[modes]: /docs/reference/modes +[variables]: /docs/reference/variables +[version-sources]: /docs/reference/version-sources diff --git a/docs/input/docs/workflows/GitFlow/v1.yml b/docs/input/docs/workflows/GitFlow/v1.yml index 897bb5e169..f839b27b94 100644 --- a/docs/input/docs/workflows/GitFlow/v1.yml +++ b/docs/input/docs/workflows/GitFlow/v1.yml @@ -1,4 +1,4 @@ -assembly-versioning-scheme: MajorMinorPatch +assembly-versioning-scheme: MajorMinorPatch assembly-file-versioning-scheme: MajorMinorPatch tag-prefix: '[vV]?' version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* diff --git a/docs/input/docs/workflows/GitHubFlow/v1.yml b/docs/input/docs/workflows/GitHubFlow/v1.yml index 4b3a4c9591..822fe7991f 100644 --- a/docs/input/docs/workflows/GitHubFlow/v1.yml +++ b/docs/input/docs/workflows/GitHubFlow/v1.yml @@ -1,4 +1,4 @@ -assembly-versioning-scheme: MajorMinorPatch +assembly-versioning-scheme: MajorMinorPatch assembly-file-versioning-scheme: MajorMinorPatch tag-prefix: '[vV]?' version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* @@ -57,12 +57,12 @@ branches: increment: Inherit prevent-increment: when-current-commit-tagged: false + track-merge-message: true regex: ^features?[/-](?.+) source-branches: - main - release is-source-branch-for: [] - track-merge-message: true is-main-branch: false pre-release-weight: 30000 pull-request: @@ -73,13 +73,13 @@ branches: of-merged-branch: true when-current-commit-tagged: false label-number-pattern: '[/-](?\d+)' + track-merge-message: true regex: ^(pull|pull\-requests|pr)[/-] source-branches: - main - release - feature is-source-branch-for: [] - track-merge-message: true pre-release-weight: 30000 unknown: mode: ManualDeployment @@ -87,6 +87,7 @@ branches: increment: Inherit prevent-increment: when-current-commit-tagged: false + track-merge-message: false regex: (?.+) source-branches: - main @@ -94,7 +95,6 @@ branches: - feature - pull-request is-source-branch-for: [] - track-merge-message: false is-main-branch: false ignore: sha: [] diff --git a/docs/input/docs/workflows/TrunkBased/preview1.yml b/docs/input/docs/workflows/TrunkBased/preview1.yml index cc9b59a1dd..07012e4dd6 100644 --- a/docs/input/docs/workflows/TrunkBased/preview1.yml +++ b/docs/input/docs/workflows/TrunkBased/preview1.yml @@ -1,4 +1,4 @@ -assembly-versioning-scheme: MajorMinorPatch +assembly-versioning-scheme: MajorMinorPatch assembly-file-versioning-scheme: MajorMinorPatch tag-prefix: '[vV]?' version-in-branch-pattern: (?[vV]?\d+(\.\d+)?(\.\d+)?).* @@ -12,8 +12,8 @@ merge-message-formats: {} update-build-number: true semantic-version-format: Strict strategies: -- Mainline - ConfiguredNextVersion +- Mainline branches: main: mode: ContinuousDeployment @@ -21,46 +21,65 @@ branches: increment: Patch prevent-increment: of-merged-branch: true - when-current-commit-tagged: true track-merge-target: false + track-merge-message: true regex: ^master$|^main$ source-branches: [] + is-source-branch-for: [] tracks-release-branches: false is-release-branch: false is-main-branch: true pre-release-weight: 55000 feature: + mode: ContinuousDelivery + label: '{BranchName}' increment: Minor - regex: ^features?[/-](?.+) prevent-increment: when-current-commit-tagged: false + track-merge-message: true + regex: ^features?[/-](?.+) source-branches: - main + is-source-branch-for: [] + is-main-branch: false pre-release-weight: 30000 hotfix: + mode: ContinuousDelivery + label: '{BranchName}' increment: Patch - regex: ^hotfix(es)?[/-](?.+) prevent-increment: when-current-commit-tagged: false + regex: ^hotfix(es)?[/-](?.+) source-branches: - main + is-source-branch-for: [] + is-release-branch: 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+)' + track-merge-message: true regex: ^(pull|pull\-requests|pr)[/-] source-branches: - main + - feature + - hotfix + is-source-branch-for: [] pre-release-weight: 30000 unknown: increment: Patch - regex: (?.+) prevent-increment: when-current-commit-tagged: false + regex: (?.+) source-branches: - main + is-source-branch-for: [] pre-release-weight: 30000 ignore: sha: [] @@ -75,6 +94,8 @@ 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 diff --git a/src/GitVersion.Configuration.Tests/GitVersion.Configuration.Tests.csproj b/src/GitVersion.Configuration.Tests/GitVersion.Configuration.Tests.csproj index 2b5ddb0b6c..fdfd126300 100644 --- a/src/GitVersion.Configuration.Tests/GitVersion.Configuration.Tests.csproj +++ b/src/GitVersion.Configuration.Tests/GitVersion.Configuration.Tests.csproj @@ -3,4 +3,17 @@ + + + + + + + + + + diff --git a/src/GitVersion.Configuration.Tests/Workflows/WorkflowsTests.cs b/src/GitVersion.Configuration.Tests/Workflows/WorkflowsTests.cs new file mode 100644 index 0000000000..801d5239c4 --- /dev/null +++ b/src/GitVersion.Configuration.Tests/Workflows/WorkflowsTests.cs @@ -0,0 +1,36 @@ +namespace GitVersion.Configuration.Tests.Configuration; + +[TestFixture] +public class WorkflowsTests +{ + private readonly ConfigurationSerializer serializer = new(); + + private static readonly object[][] Workflows = + [ + ["GitFlow/v1", GitFlowConfigurationBuilder.New], + ["GitHubFlow/v1", GitHubFlowConfigurationBuilder.New], + ["TrunkBased/preview1", TrunkBasedConfigurationBuilder.New] + ]; + + [Test(Description = "This test is to ensure that the configuration for workflow is up to date")] + [TestCaseSource(nameof(Workflows))] + public void CheckWorkflowsAreUpdated(string workflow, IConfigurationBuilder configurationBuilder) + { + var configuration = configurationBuilder.Build(); + + var serializedConfiguration = serializer.Serialize(configuration); + var segments = workflow.Split("/"); + var folderName = segments[0]; + var fileName = segments[^1]; + + serializedConfiguration.ShouldMatchApproved(builder => builder + .WithFilenameGenerator((_, _, type, extension) => FilenameGenerator(fileName, type, extension)) + .WithFileExtension("yml") + .SubFolder($"approved/{folderName}")); + } + + private static string FilenameGenerator(string fileName, string type, string ext) => + type == "approved" + ? $"{fileName}.{ext}" + : $"{fileName}.{type}.{ext}"; +} diff --git a/src/GitVersion.Configuration.Tests/Workflows/approved/GitFlow/v1.yml b/src/GitVersion.Configuration.Tests/Workflows/approved/GitFlow/v1.yml new file mode 100644 index 0000000000..f839b27b94 --- /dev/null +++ b/src/GitVersion.Configuration.Tests/Workflows/approved/GitFlow/v1.yml @@ -0,0 +1,167 @@ +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: +- Fallback +- ConfiguredNextVersion +- MergeMessage +- TaggedCommit +- TrackReleaseBranches +- VersionInBranchName +branches: + develop: + mode: ContinuousDelivery + label: alpha + increment: Minor + prevent-increment: + when-current-commit-tagged: false + track-merge-target: true + track-merge-message: true + regex: ^dev(elop)?(ment)?$ + source-branches: + - main + is-source-branch-for: [] + tracks-release-branches: true + is-release-branch: false + is-main-branch: false + pre-release-weight: 0 + main: + label: '' + increment: Patch + prevent-increment: + of-merged-branch: true + track-merge-target: false + track-merge-message: true + regex: ^master$|^main$ + source-branches: [] + is-source-branch-for: [] + tracks-release-branches: false + is-release-branch: false + is-main-branch: true + pre-release-weight: 55000 + release: + mode: ManualDeployment + label: beta + increment: Minor + prevent-increment: + of-merged-branch: true + when-current-commit-tagged: false + track-merge-target: false + regex: ^releases?[/-](?.+) + source-branches: + - main + - support + is-source-branch-for: [] + tracks-release-branches: false + is-release-branch: true + is-main-branch: false + pre-release-weight: 30000 + feature: + mode: ManualDeployment + label: '{BranchName}' + increment: Inherit + prevent-increment: + when-current-commit-tagged: false + track-merge-message: true + regex: ^features?[/-](?.+) + source-branches: + - develop + - main + - release + - support + - hotfix + is-source-branch-for: [] + 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+)' + track-merge-message: true + regex: ^(pull|pull\-requests|pr)[/-] + source-branches: + - develop + - main + - release + - feature + - support + - hotfix + is-source-branch-for: [] + pre-release-weight: 30000 + hotfix: + mode: ManualDeployment + label: beta + increment: Inherit + prevent-increment: + when-current-commit-tagged: false + regex: ^hotfix(es)?[/-](?.+) + source-branches: + - main + - support + is-source-branch-for: [] + is-release-branch: true + is-main-branch: false + pre-release-weight: 30000 + support: + label: '' + increment: Patch + prevent-increment: + of-merged-branch: 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 + label: '{BranchName}' + increment: Inherit + prevent-increment: + when-current-commit-tagged: true + regex: (?.+) + source-branches: + - main + - develop + - release + - feature + - pull-request + - hotfix + - support + is-source-branch-for: [] + is-main-branch: false +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: '' +source-branches: [] +is-source-branch-for: [] +tracks-release-branches: false +is-release-branch: false +is-main-branch: false diff --git a/src/GitVersion.Configuration.Tests/Workflows/approved/GitHubFlow/v1.yml b/src/GitVersion.Configuration.Tests/Workflows/approved/GitHubFlow/v1.yml new file mode 100644 index 0000000000..822fe7991f --- /dev/null +++ b/src/GitVersion.Configuration.Tests/Workflows/approved/GitHubFlow/v1.yml @@ -0,0 +1,116 @@ +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: +- Fallback +- ConfiguredNextVersion +- MergeMessage +- TaggedCommit +- TrackReleaseBranches +- VersionInBranchName +branches: + main: + label: '' + increment: Patch + prevent-increment: + of-merged-branch: true + track-merge-target: false + track-merge-message: true + regex: ^master$|^main$ + source-branches: [] + is-source-branch-for: [] + tracks-release-branches: false + is-release-branch: false + is-main-branch: true + pre-release-weight: 55000 + release: + mode: ManualDeployment + label: beta + 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 + is-source-branch-for: [] + tracks-release-branches: false + is-release-branch: true + is-main-branch: false + pre-release-weight: 30000 + feature: + mode: ManualDeployment + label: '{BranchName}' + increment: Inherit + prevent-increment: + when-current-commit-tagged: false + track-merge-message: true + regex: ^features?[/-](?.+) + source-branches: + - main + - release + is-source-branch-for: [] + 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+)' + track-merge-message: true + regex: ^(pull|pull\-requests|pr)[/-] + source-branches: + - main + - release + - feature + is-source-branch-for: [] + pre-release-weight: 30000 + unknown: + mode: ManualDeployment + label: '{BranchName}' + increment: Inherit + prevent-increment: + when-current-commit-tagged: false + track-merge-message: false + regex: (?.+) + source-branches: + - main + - release + - feature + - pull-request + is-source-branch-for: [] + is-main-branch: false +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: '' +source-branches: [] +is-source-branch-for: [] +tracks-release-branches: false +is-release-branch: false +is-main-branch: false diff --git a/src/GitVersion.Configuration.Tests/Workflows/approved/TrunkBased/preview1.yml b/src/GitVersion.Configuration.Tests/Workflows/approved/TrunkBased/preview1.yml new file mode 100644 index 0000000000..07012e4dd6 --- /dev/null +++ b/src/GitVersion.Configuration.Tests/Workflows/approved/TrunkBased/preview1.yml @@ -0,0 +1,101 @@ +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: +- ConfiguredNextVersion +- Mainline +branches: + main: + mode: ContinuousDeployment + label: '' + increment: Patch + prevent-increment: + of-merged-branch: true + track-merge-target: false + track-merge-message: true + regex: ^master$|^main$ + source-branches: [] + is-source-branch-for: [] + tracks-release-branches: false + is-release-branch: false + is-main-branch: true + pre-release-weight: 55000 + feature: + mode: ContinuousDelivery + label: '{BranchName}' + increment: Minor + prevent-increment: + when-current-commit-tagged: false + track-merge-message: true + regex: ^features?[/-](?.+) + source-branches: + - main + is-source-branch-for: [] + is-main-branch: false + pre-release-weight: 30000 + hotfix: + mode: ContinuousDelivery + label: '{BranchName}' + increment: Patch + prevent-increment: + when-current-commit-tagged: false + regex: ^hotfix(es)?[/-](?.+) + source-branches: + - main + is-source-branch-for: [] + is-release-branch: 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+)' + track-merge-message: true + regex: ^(pull|pull\-requests|pr)[/-] + source-branches: + - main + - feature + - hotfix + is-source-branch-for: [] + pre-release-weight: 30000 + unknown: + increment: Patch + prevent-increment: + when-current-commit-tagged: false + regex: (?.+) + source-branches: + - main + is-source-branch-for: [] + 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: '' +source-branches: [] +is-source-branch-for: [] +tracks-release-branches: false +is-release-branch: false +is-main-branch: false diff --git a/src/GitVersion.Configuration/GitVersion.Configuration.csproj b/src/GitVersion.Configuration/GitVersion.Configuration.csproj index cf3b09fcfe..75a9ad34e1 100644 --- a/src/GitVersion.Configuration/GitVersion.Configuration.csproj +++ b/src/GitVersion.Configuration/GitVersion.Configuration.csproj @@ -30,20 +30,7 @@ - - - - - - - - - - - - - - - + + diff --git a/src/GitVersion.Core/Configuration/IConfigurationBuilder.cs b/src/GitVersion.Core/Configuration/IConfigurationBuilder.cs index 1eabfff749..e6827f7a0a 100644 --- a/src/GitVersion.Core/Configuration/IConfigurationBuilder.cs +++ b/src/GitVersion.Core/Configuration/IConfigurationBuilder.cs @@ -1,6 +1,6 @@ namespace GitVersion.Configuration; -internal interface IConfigurationBuilder +public interface IConfigurationBuilder { void AddOverride(IReadOnlyDictionary value); diff --git a/src/GitVersion.Core/PublicAPI.Shipped.txt b/src/GitVersion.Core/PublicAPI.Shipped.txt index 55ad0b8489..78e07b591c 100644 --- a/src/GitVersion.Core/PublicAPI.Shipped.txt +++ b/src/GitVersion.Core/PublicAPI.Shipped.txt @@ -107,6 +107,9 @@ GitVersion.Configuration.IBranchConfiguration.SourceBranches.get -> System.Colle GitVersion.Configuration.IBranchConfiguration.TrackMergeMessage.get -> bool? GitVersion.Configuration.IBranchConfiguration.TrackMergeTarget.get -> bool? GitVersion.Configuration.IBranchConfiguration.TracksReleaseBranches.get -> bool? +GitVersion.Configuration.IConfigurationBuilder +GitVersion.Configuration.IConfigurationBuilder.AddOverride(System.Collections.Generic.IReadOnlyDictionary! value) -> void +GitVersion.Configuration.IConfigurationBuilder.Build() -> GitVersion.Configuration.IGitVersionConfiguration! GitVersion.Configuration.IConfigurationFileLocator GitVersion.Configuration.IConfigurationFileLocator.GetConfigurationFile(string? directory) -> string? GitVersion.Configuration.IConfigurationFileLocator.Verify(string? workingDirectory, string? projectRootDirectory) -> void