- Unlock newer C# language features in deployment scripts
- Allow referencing NuGet packages directly from within scripts
- Remove the need to have Mono installed to run C# scripts on Linux deployment targets
C# scripting accounts for ~5% of our script steps, so we want to understand the impact this change could have on our users.
If you're using C# scripts in your deployment processes, and are deploying to Linux targets using SSH and Mono, or to Windows Tentacle targets running Windows versions earlier than 2012 R2, the proposed changes could impact you.
This post outlines the potential changes, plus the trade-offs in moving to dotnet-script and deprecating scriptcs. We also created a GitHub issue where you can provide feedback, and we can further gauge the demand for this functionality.
How we propose to support dotnet-script
This Request for Comments (RFC) proposes removing
scriptcs in favor of
To deploy software to your server we use Tentacle, a lightweight service responsible for communicating with Octopus Server, and invoking Calamari. Calamari is a command-line tool that knows how to perform the deployment, and is the host process for all deployment actions including script execution. We currently build Calamari for .NET Framework 4.0.0, 4.5.2, and netcore3.1. Depending on your server OS, architecture and version, Tentacle receives one of these Calamari builds.
Historically, Calamari required Mono to be installed on your Linux targets to execute
scriptcs as it's built on the full .NET Framework. With the introduction of cross-platform .NET apps with netcore3.1 Linux can now natively run .NET apps removing the complexity and overhead of Mono. Linux targets currently receive the netcore3.1 Calamari by default, with the exception of Linux SSH targets, which can specify to run scripts on Mono.
dotnet-script is a modern implementation of C# scripting, built on .NET. It can run on all targets that support .NET apps (netcore3.1 and newer). If we make this change, it would mean that C# scripts would only be able to be run on targets that support .NET. Windows Server 2012 R2 and earlier only support .NET Framework, so these targets would lose the ability to run C# scripts.
|Removes Mono dependency for Linux||❌||✅|
|NuGet import support||❌||✅|
|Allows future .NET 5 & 6 support||❌||✅|
Benefits of the proposed approach
All C# language features included up to version 8 are now available for use in your C# scripts.
Removing the dependency on Mono to execute scripts brings us inline with modern cross platform .NET capabilities reducing the complexity of calling into Mono and related issues.
The NuGet import support from
dotnet-script allows for the direct referencing of a NuGet package in a script without having to include the dll in the scripts packages. The new approach can be seen below.
#r "nuget: RestSharp, 108.0.1" using RestSharp; var client = new RestClient("https://pokeapi.co/api/v2/"); var request = new RestRequest("pokemon/ditto"); var response = await client.ExecuteGetAsync(request); Console.WriteLine(response.Content);
Linux SSH Targets using Mono
One trade-off of this change is that C# scripting would no longer be available on Linux deployment targets using SSH with Mono.
To run C# scripts against your SSH linux targets, you'd need to reconfigure your SSH targets to use the self-contained Calamari which runs via netcore3.1.
To do this, select the Self-Contained Calamari target runtime on your SSH target. Targets using the Linux tentacle will continue to work as they always have.
Windows Server 2012 R2 (and earlier) targets
The other trade-off with this change is that
dotnet-script only works with netcore3.1 and above. This would make C# scripting unavailable to deployments against Windows Tentacles installed on versions of Windows earlier than 2012 R2, as these run .NET Framework builds of Calamari.
We developed a workaround so you can continue using scriptcs on your affected Windows targets, but you'll have to update your deployment process.
- Add the scriptcs NuGet package as a referenced package.
- Copy the body of your C# Script into the
$ScriptContentvariable in the PowerShell template below.
Any paramaters used in the C# script need to be passed in through the scriptcs arguments and referenced using the
Env.ScriptArgs[Index] format inside the ScriptContent. The template below shows an example of how to do this for
$ScriptContent = @" Console.WriteLine(Env.ScriptArgs); "@ New-Item -Path . -Name "ScriptFile.csx" -ItemType "file" -Value $ScriptContent $scriptCs = Join-Path $OctopusParameters["Octopus.Action.Package[scriptcs].ExtractedPath"] "tools/scriptcs.exe" & $scriptCs ScriptFile.csx -- $OctopusParameters["Octopus.Deployment.Id"]
When will this be released?
We're still evaluating how many users this change is likely to affect. We won't make or release the proposed changes until we have a clear picture of who we'll impact and what actions they'd need to take.
We want your feedback
We're still considering this change, so now is a great time to help shape this proposal with your feedback. We created a GitHub issue to capture the discussion.
Specifically, we want to know:
- Will the limitations of Linux SSH targets or Windows versions older than 2012 R2 affect you?
- If so, can you foresee any challenges that may stop you from upgrading these deployment targets or using alternative scripting languages?
- Do the newer language features, easier NuGet package reference, and added reliability in removing Mono justify these changes?
Your feedback will help us deliver the best solution we can.
In summary, the migration from
dotnet-script will result in the following changes:
- C# scripting deprecated for Linux SSH targets running Mono
- C# scripting deprecated for Windows deployment targets running on versions earlier than 2012 R2
- Increase support for language features from C# 5 to C# 8
- Direct imports of NuGet packages in scripts
- Removal of Mono requirement for running C# scripts on Linux targets
Thanks for reading this RFC. Any feedback you have is greatly appreciated.