Search code examples
cakebuild

Pass multiple parameters/arguments to target


I've got a target Release-Prepare taking the version as an argument:

var version = Argument("version", "1.0.0.0");

Task ("Release-Prepare")
    .Does (() => {
        // Compute the package version
        var gitCommitHash = GitLogTip(projectDir).Sha;
        var gitVersion = gitCommitHash?.Substring(0, 8) ?? "Unknown";
        var currentDateTime = DateTime.UtcNow.ToString("yyyyMMddHHmmss");
        var packageVersion = $"{version}-{gitVersion}-{currentDateTime}";
        Information(packageVersion);

        // Versions having to be modified in *.csproj
        var versionXPath = "/Project/PropertyGroup/Version";
        var assemblyVersionXPath = "/Project/PropertyGroup/AssemblyVersion";
        var fileVersionXPath = "/Project/PropertyGroup/FileVersion";

        // Set versions for all projects (excpet testing)
        var projectFilePaths = GetFiles("./**/*.csproj");
        foreach(var projectFilePath in projectFilePaths) {
            if(projectFilePath.FullPath.Contains("Tests")){
                // Do not version test projects
                continue;
            }

            XmlPoke(projectFilePath, versionXPath, packageVersion);
            XmlPoke(projectFilePath, assemblyVersionXPath, version);
            XmlPoke(projectFilePath, fileVersionXPath, version);
        }
    });

Executing the target without parameters works fine:

PS E:\dev\Sppd.TeamTuner> powershell -ExecutionPolicy ByPass -File build.ps1 -script "e:\dev\Sppd.TeamTuner\build.cake" -target "Release-Prepare" -verbosity normal
Preparing to run build script...
Running build script...

========================================
Release-Prepare
========================================
1.0.0.0-af9d218d-20191125093743

Task                          Duration
--------------------------------------------------
Release-Prepare               00:00:02.3258569
--------------------------------------------------
Total:                        00:00:02.3258569

But I can't figure out how to pass the target AND the version using a PowerShell command. I've tried:

  • powershell -ExecutionPolicy ByPass -File build.ps1 -script "e:\dev\Sppd.TeamTuner\build.cake" -target "Release-Prepare" -version="1.2.3.4" -verbosity normal -> Error: Argument value is not a valid boolean value.
  • powershell -ExecutionPolicy ByPass -File build.ps1 -script "e:\dev\Sppd.TeamTuner\build.cake" -ScriptArgs '--target=Release-Prepare','--version=1.3.1.2' -verbosity normal -> Error: The target 'Release-Prepare,--version=1.3.1.2' was not found.

I've tried all permutations of -ScriptArgs '--target=Release-Prepare','--version=1.3.1.2' I could think of (single dash, space/comma, single/double quotes. But everything I've tried resulted in cake intzerpreting as a single command.

How do ScriptArgs have to be specified to work for multiple parameters?


Solution

  • I am going to assume that you are using the latest bootstrapper file, which is available from here:

    https://cakebuild.net/download/bootstrapper/windows

    NOTE: If this is not the case, then the way that the arguments are parsed and sent to Cake might be different than what I am showing here.

    You can download this using:

    Invoke-WebRequest https://cakebuild.net/download/bootstrapper/windows -OutFile build.ps1
    

    As mentioned here.

    With that in place, let's use the following build.cake file:

    ///////////////////////////////////////////////////////////////////////////////
    // ARGUMENTS
    ///////////////////////////////////////////////////////////////////////////////
    
    var target = Argument("target", "Default");
    var configuration = Argument("configuration", "Release");
    var version = Argument("applicationVersion", "1.0.0.0");
    
    ///////////////////////////////////////////////////////////////////////////////
    // SETUP / TEARDOWN
    ///////////////////////////////////////////////////////////////////////////////
    
    Setup(ctx =>
    {
       // Executed BEFORE the first task.
       Information("Running tasks...");
    });
    
    Teardown(ctx =>
    {
       // Executed AFTER the last task.
       Information("Finished running tasks.");
    });
    
    ///////////////////////////////////////////////////////////////////////////////
    // TASKS
    ///////////////////////////////////////////////////////////////////////////////
    
    Task("Default")
    .Does(() => {
       Information("Configuration: {0}", configuration);
       Information("Target: {0}", target);
       Information("Version: {0}", version);
    });
    
    Task("Release-Prepare")
       .Does(() =>
    {
       Information("Configuration: {0}", configuration);
       Information("Target: {0}", target);
       Information("Version: {0}", version);
    });
    
    RunTarget(target);
    
    

    If we run this with no arguments, we will get this as the output:

    ========================================
    Default
    ========================================
    Configuration: Release
    Target: Default
    Version: 1.0.0.0
    

    However, if we run the following:

    .\build.ps1 --target=Release-Prepare --configuration=Debug --applicationVersion=2.2.2.2
    

    We will get:

    ========================================
    Release-Prepare
    ========================================
    Configuration: Debug
    Target: Release-Prepare
    Version: 2.2.2.2
    

    One thing to mention compared to what you have...

    The version argument is already one that is reserved by the Cake.exe directly, i.e. running:

    cake.exe --version
    

    Will output the version number of Cake itself. That is why I switched to using applicationVersion as the argument name, rather than version.