Skip to content

feat: add support for environment variables in branch labels#4944

Open
robertcoltheart wants to merge 11 commits into
GitTools:mainfrom
robertcoltheart:feature/enhance-branch-label-with-env-vars
Open

feat: add support for environment variables in branch labels#4944
robertcoltheart wants to merge 11 commits into
GitTools:mainfrom
robertcoltheart:feature/enhance-branch-label-with-env-vars

Conversation

@robertcoltheart
Copy link
Copy Markdown

Description

Supports environment variable substitution in the label configuration for a branch using the established format used elsewhere. Fallbacks are also supported if the environment variable is not found. The changes are backwards compatible and should not fail for existing configuration.

Documentation detailing the changes has been added to configuration.md.

Related Issue

Resolves #4745

Motivation and Context

Allow labels to include environment variables as well as regex-captured variables. This is useful for CICD environments like GitHub where the pull request head_ref can be provided instead of the merge commit target.

How Has This Been Tested?

Unit tests covering the new functionality have been added.

Screenshots (if appropriate):

Checklist:

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

Comment thread docs/input/docs/reference/configuration.md
@robertcoltheart
Copy link
Copy Markdown
Author

1 check is failing because the Nuke website is down.

@arturcic arturcic requested a review from HHobeck May 22, 2026 16:16
@robertcoltheart robertcoltheart requested a review from arturcic May 26, 2026 22:53
* [ChocolateyGUI](https://github.com/chocolatey/ChocolateyGUI)
* [GitLink](https://github.com/GitTools/GitLink)
* [OctopusDeploy](https://github.com/OctopusDeploy)
* [NUKE](https://nuke.build)
Copy link
Copy Markdown
Author

@robertcoltheart robertcoltheart May 30, 2026

Choose a reason for hiding this comment

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

Nuke is abandoned now and the website is unlikely to come back online. This was failing the build.

return label;
var labelPlaceholders = BuildLabelPlaceholders(configuration.RegularExpression, effectiveBranchName);

return label.FormatWith(labelPlaceholders, environment);
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Throws if environment variable is not found and has no fallback. This is deliberate to stay consistent with other usages of environment variables, for example in assembly file version.

@robertcoltheart
Copy link
Copy Markdown
Author

@HHobeck @arturcic Fixed a couple of issues that I missed. This is ready for review and merge now, thanks!

Comment thread src/GitVersion.Configuration.Tests/Configuration/ConfigurationExtensionsTests.cs Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here are a few suggestions regarding this implementation:

  1. Use object instead of generics: Change the generic type T to object. It makes more sense here since a generic type parameter provides no extra benefit for this use case.

  2. Clarify supported types: The method currently supports instances of type object and IDictionary<string, object>, but this intent is not clearly expressed in the method body. I suggest splitting this into explicit overloads for better readability, like this:

internal static class StringFormatWithExtension
{
    extension(string template)
    {
        public string FormatWith(object? source, IEnvironment environment)
        {
            object? GetFromSource(string value)
            {
                // ...
            }

            object? GetFromEnvironment(string value) => environment.GetEnvironmentVariable(value);
            
            return template.FormatWith(GetFromSource, GetFromEnvironment);
        }

        public string FormatWith(IDictionary<string, object> source, IEnvironment environment)
        {
            object? GetFromSource(string value)
            {
                source.TryGetValue(value, out var result);
                return result;
            }

            object? GetFromEnvironment(string value) => environment.GetEnvironmentVariable(value);

            return template.FormatWith(GetFromSource, GetFromEnvironment);
        }

        private string FormatWith(
            Func<string, object?> getFromSource, Func<string, object?> getFromEnvironment)
        {
            // ...
        }
    }
}
  1. Allow flexible placeholder combinations: It does not make sense to restrict how placeholders can occur. Why shouldn't all of the following combinations be valid?
  • {JustAProperty}
  • {JustAProperty ?? "JustAFallback"}
  • {JustAProperty} ?? {env:JustAVariable}
  • {JustAProperty} ?? {env:JustAVariable} ?? "JustAFallback"
  • {env:JustAVariable}
  • {env:JustAVariable} ?? "JustAFallback"
  • {env:JustAVariable} ?? {JustAProperty}
  • {env:JustAVariable} ?? {JustAProperty} ?? "JustAFallback"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

1 and 2, fair enough, will make these changes.

For 3, it was written this way (and I'm guessing the original implementor in #4746 did it this way for the same reason) to remain compatible/easy to understand as the existing configuration options for label and for assembly-file-versioning-format, where the {env:} syntax is derived from. The understanding I have is that {Name} syntax is reserved for regex captures, whereas {env:} is used for environment variables. I think it would be more confusing given the language that the configuration has cultivated to conflate these 2 concepts.

If the longer-term intention is to further enhance the regex/env var to support this conflation, I'd suggest doing this in a follow up change rather than here. Let me know your thoughts on this.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Jun 1, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ISSUE]: Provide the ability to use environment variables in labels

3 participants