Skip to content
This repository was archived by the owner on Sep 17, 2020. It is now read-only.
This repository was archived by the owner on Sep 17, 2020. It is now read-only.

How to get MSBuild property values #42

@fakhrulhilal

Description

@fakhrulhilal

Description

I want to transform placeholder in the web.config and populate it with MSBuild properties, either getting value from parameter, property attribute, or azure pipeline variables. The original goal is replacing placeholder (using format [CAPITALIZED_NAME]) within config files. The main source for replacing placeholders are from azure pipeline variables. It works by using example code. But sometimes, I need to test the build in my local using MSBuild parameter, making sure it will not break the build.

Example code

<UsingTask TaskName="PopulatePlaceholders" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
    <ParameterGroup>
        <SourceFile ParameterType="System.String" Required="true" />
        <TargetFile ParameterType="System.String" Required="true" />
        <Verbose ParameterType="System.Boolean" Required="false" />
    </ParameterGroup>
    <Task>
        <Using Namespace="System.Text.RegularExpressions"/>
        <Code Type="Fragment" Language="cs">
            <![CDATA[
if (File.Exists(SourceFile))
{
    Log.LogMessage($"Populating placeholder from MSBuild properties in '{SourceFile}'");
    string sourceContent = File.ReadAllText(SourceFile);
    string baseFolder = Path.GetFileName(Path.GetDirectoryName(SourceFile));
    var matches = Regex.Matches(sourceContent, @"\[(?<placeholder>[A-Z_]+)\]", RegexOptions.Multiline);
    string transformed = Regex.Replace(sourceContent, @"\[(?<placeholder>[A-Z_]+)\]", match => 
    {
        string placeholder = match.Groups["placeholder"].Value;
        string envValue = Environment.GetEnvironmentVariable(placeholder);
        if (Verbose) Log.LogMessage($"[{baseFolder}] Replacing {match.Value} with: {envValue}");
        return !string.IsNullOrEmpty(envValue) ? envValue : match.Value;
    }, RegexOptions.Multiline);
    File.WriteAllText(TargetFile, transformed);
}
]]>
        </Code>
    </Task>
</UsingTask>
]]>
        </Code>
    </Task>
</UsingTask>

What I've tried:

  1. Transform task
    Well, I need to define each transform XML in individual project (for file transformation). This will be harder to maintain for many projects. And the variable substitutions only support certain place.
  2. Magic Chunks
    This task suports more than transform task. But when I define single global source config for all projects, it adds new config value which's not defined in original web.config, breaking the config.

Expectation

All msbuild parameter prosessed from:

  1. From parameter (/p:Name=Value pair)
  2. From property element (<PropertyGroup><Name>Value</Name></PropertyGroup>)
  3. From azure pipeline variables

Actual

Only azure pipeline variables are parsed

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions