GitVersion icon indicating copy to clipboard operation
GitVersion copied to clipboard

Enhance branch label configuration with environment variable support

Open W0GER opened this issue 1 month ago • 5 comments

Added the ability to use environment variable placeholders in branch labels, allowing for dynamic label generation in CI/CD scenarios. Introduced fallback values for environment variables and updated related tests to ensure correct processing of these new features. Updated the GetBranchSpecificLabel method to handle environment variables even when regex does not match, maintaining backward compatibility.

Description

Implementation Steps

  1. Modify GetBranchSpecificLabel in src/GitVersion.Core/Extensions/ConfigurationExtensions.cs:
  • Add an optional IEnvironment parameter.
  • After regex placeholder processing, if IEnvironment is provided, process {env:...} placeholders using FormatWith.
  1. Update call sites to pass IEnvironment where available:
  • Thread IEnvironment through version calculation strategies that call GetBranchSpecificLabel.
  • Start with strategies that can access it via dependency injection.
  1. Update tests:
  • Add tests in src/GitVersion.Configuration.Tests/Configuration/ConfigurationExtensionsTests.cs for environment variable placeholders in labels.
  1. Documentation:
  • Update docs/input/docs/reference/configuration.md to document {env:...} support in labels.

Backward Compatibility

  • Existing code continues to work (parameter is optional)
  • Environment variable processing only occurs when IEnvironment is provided
  • No breaking changes to existing API

Related Issue

Resolves #4745

Motivation and Context

Allow labels to include environment variables so that labels can include things like the github_headref for pull requests.

This solves the issue of not being able to add the branch name on versions generated in workflows running on pull requests.

How Has This Been Tested?

Screenshots (if appropriate):

Checklist:

  • [x] My code follows the code style of this project.
  • [x] My change requires a change to the documentation.
  • [x] I have updated the documentation accordingly.
  • [x] I have added tests to cover my changes.
  • [x] All new and existing tests passed.

W0GER avatar Nov 13 '25 21:11 W0GER

@HHobeck

Getting a strange error on the Windows .net9.0 tests. The tests pass then an exception is thrown during calculating code coverage. From the logs:

Starting test execution, please wait...
  A total of 1 test files matched the specified pattern.
  Results File: D:/a/GitVersion/GitVersion/artifacts/test-results/GitVersion.MsBuild.Tests.net9.0.results.xml
  
  Passed!  - Failed:     0, Passed:   151, Skipped:     0, Total:   151, Duration: 51 s - GitVersion.MsBuild.Tests.dll (net9.0)
    [coverlet] 
    Calculating coverage result...
  C:\Users\runneradmin\.nuget\packages\coverlet.msbuild\6.0.4\build\coverlet.msbuild.targets(72,5): error : Unable to read beyond the end of the stream. [D:\a\GitVersion\GitVersion\src\GitVersion.MsBuild.Tests\GitVersion.MsBuild.Tests.csproj::TargetFramework=net9.0]
  C:\Users\runneradmin\.nuget\packages\coverlet.msbuild\6.0.4\build\coverlet.msbuild.targets(72,5): error :    at System.IO.BinaryReader.ReadInt32() [D:\a\GitVersion\GitVersion\src\GitVersion.MsBuild.Tests\GitVersion.MsBuild.Tests.csproj::TargetFramework=net9.0]
  C:\Users\runneradmin\.nuget\packages\coverlet.msbuild\6.0.4\build\coverlet.msbuild.targets(72,5): error :    at Coverlet.Core.Coverage.CalculateCoverage() in /_/src/coverlet.core/Coverage.cs:line 420 [D:\a\GitVersion\GitVersion\src\GitVersion.MsBuild.Tests\GitVersion.MsBuild.Tests.csproj::TargetFramework=net9.0]
  C:\Users\runneradmin\.nuget\packages\coverlet.msbuild\6.0.4\build\coverlet.msbuild.targets(72,5): error :    at Coverlet.Core.Coverage.GetCoverageResult() in /_/src/coverlet.core/Coverage.cs:line 160 [D:\a\GitVersion\GitVersion\src\GitVersion.MsBuild.Tests\GitVersion.MsBuild.Tests.csproj::TargetFramework=net9.0]
  C:\Users\runneradmin\.nuget\packages\coverlet.msbuild\6.0.4\build\coverlet.msbuild.targets(72,5): error :    at Coverlet.MSbuild.Tasks.CoverageResultTask.Execute() in /_/src/coverlet.msbuild.tasks/CoverageResultTask.cs:line 87 [D:\a\GitVersion\GitVersion\src\GitVersion.MsBuild.Tests\GitVersion.MsBuild.Tests.csproj::TargetFramework=net9.0]
  An error occurred when executing task 'UnitTest'.
  [NULL]

I'm not sure how to resolve this issue.

W0GER avatar Nov 14 '25 01:11 W0GER

I'm not sure how to resolve this issue.

@W0GER Thank you very much for your contribution. It could be a sporadic error. A retry has solved it.

HHobeck avatar Nov 14 '25 08:11 HHobeck

I have some points you need to address for this feature:

  1. Refactoring of StringFormatWithExtension.FormatWith in that way to accept a dictionary of type Dictionary<string, object> instead of T (additional method).
  2. In ConfigurationExtensions.GetBranchSpecificLabel create the Dictionary<string, object> instance from configuration.RegularExpression and effectiveBranchName by extracting the capturing group name and values. The dictionary might be empty.
  3. Call label.FormatWith(dictionary, environment) to replace the placeholders
  4. I'm not sure if we should suppress the ArgumentException. For backward compatibility reason I would say make a new optional parameter with name throwIfNotFound and throw a ArgumentException dependent of this option.
  5. The IEnvironment parameter needs to be not optional in ConfigurationExtensions.GetBranchSpecificLabel.

Hope that makes sense to you. Please let me know if you have any questions.

HHobeck avatar Nov 14 '25 08:11 HHobeck

@HHobeck I just saw your comments, I'll try to get these addressed this weekend.

W0GER avatar Dec 05 '25 21:12 W0GER