Skip to content

Portable Build Scripts

Roman Kuzmin edited this page Dec 24, 2012 · 9 revisions

It is possible and even expected in some cases to have a copy of Invoke-Build tools kept together with build scripts and make the build tool set portable, only assuming PowerShell is installed and configured for invoking scripts. Invoke-Build.ps1 is often enough, other tools and files are optional.

Another reason to keep a copy of Invoke-Build with build scripts is use of incompatible build engine versions. Existing build scripts do not have to be upgraded for a newer version, they may continue to use old tools.

Build scripts which do not call Invoke-Build.ps1 and Invoke-Builds.ps1 are already portable. Otherwise there are some challenges:

  • How to invoke Invoke-Build.ps1 from tasks, that is, call it nested?
  • How to invoke parallel builds by Invoke-Builds.ps1 from tasks?
  • How to avoid accidental calls to incompatible tools in the path?

These challenges are resolved with the special aliases defined by the engine:

  • Invoke-Build is a self-alias of the currently running script Invoke-Build.ps1
  • Invoke-Builds is an alias of the script Invoke-Builds.ps1 in the same directory.

Portable build scripts should follow one simple rule. They use these aliases instead of script names. In other words, they should call the scripts just by names without file extensions and paths.

Example

The task Test in .build.ps1 simply dispatches the call to other scripts:

$TestScripts = ('SmokeTest.build.ps1', 'MoreTests.build.ps1', ...)

task Test {
    foreach($_ in $TestScripts) {
        Invoke-Build Test $_
    }
}

If Invoke-Build.ps1 is kept in the same directory with build scripts then it is called by its relative path:

./Invoke-Build.ps1 Test .build.ps1

Or, if Invoke-Build.ps1 is kept separately in a known directory then it is called using its full path:

C:/Scripts/InvokeBuild/Invoke-Build.ps1 Test .build.ps1

Or, if the directory is defined by an environment variable:

& $env:InvokeBuild/Invoke-Build.ps1 Test .build.ps1

As far as the example build script uses the alias Invoke-Build then nested calls work fine even if the build engine is not in the path. And if there is yet another copy of Invoke-Build.ps1 in the path, normally a newer possibly not compatible version, then it is not called.