PowerShell in .NET Core and Docker

PowerShell in .NET Core and Docker

Since the beginning of time .NET Core there has been one continuous annoyance about developing cross-platform solutions, including build scripts for windows and non-windows platforms.

We have at least fallen into a standard pattern, most repositories will contain both a build.cmd and build.sh that will build the project in whichever platform we're currently using.

Sometimes though there's only one or one is neglected in favour of the other. If we're using a build tool like Cake or Fake then we have a simple setup, our build files can just trigger the build logic which is stored in a single file. In fact, both tools will give you default build files that do just that.

So what if we're just doing a relatively plain build task? Something like

dotnet clean

dotnet tool restore

dotnet build ./src/*.csproj

dotnet build ./tests/*.csproj

dotnet test ./tests/*.csproj

dotnet package ./src/*.csproj

Over time changes will be made to this and human error is inevitable, a change will be made to build.cmd but not to build.sh, or vice versa.

Enter PowerShell Core, now available as a dotnet tool! Presuming you have the .NET Core SDK installed, you can simply run

dotnet tool install --global PowerShell

It will now be available with the pwsh command. But this still presumes that other developers will have it installed globally.

Let's add it on a project level.

# add a tool manifest if there isn't one already
dotnet new tool-manifest

dotnet tool install PowerShell

Now PowerShell becomes a tool available in the project. Instead of pwsh, you will have to specify dotnet pwsh but now we can create a build.ps1 file that can contain all our build logic and replace our build.cmd and build.sh files with a one-liner.

dotnet pwsh build.ps1

Now all our build logic is cross-platform without external dependencies!

Where this really comes into its own is that PowerShell has been included as a global tool in .NET Core SDK docker images.

Combined with Visual Studio Code's new Remote Development functionality, this means you can build a truly cross-platform development environment in a docker image. Simply set it up for your project, write one build script in PowerShell and rest secure in the knowledge that you're providing everything needed for another developer to be able to grab your project, open it up and build it immediately without having to worry about setting up dependencies or even what platform they're using!