C# Scripting

I was a bit curious about this. In the Xamarin stacks we already have Mono installed, so we could actually run C# scripts instead of having to do any bash or javascripty thing.

There are a few options out there such as ScriptCS or Cake, which would be great. Ideally though whatever we need would have to be installed on all stacks.

Cake will run on dotnet core for the most part (some addins may not be supported but this is going to change as time goes on). I think scriptcs can be made to run there as well.

I know in the past we’ve talked about getting dotnet core installed on the base images. Can we have that discussion again? This would mean that bitrise steps could be developed in C#, which would be hugely valuable to .net developers like myself and James…

Hi @jamesmontemagno,

Thanks for the #feature-request! :wink:

For now if you’d want to run C# scripts as part of your step you should make sure that the C# runtime you need is installed. You can install it in the step’s step.sh right before you’d run the script, similar to https://github.com/bitrise-io/steps-fastlane/blob/2.2.0/step.sh

For a pre-installed runtime we should decide which runtime it should be (e.g. Mono vs .Net Core), as well as it should be stable enough long term, as the versioned Xcode stacks are not upgraded, those have the same version of the preinstalled tools the stack was initially released with.

So, we’re not against preinstalling a C# runtime, but for now it seems better to simply install that as part of the step.sh “entry” script.

So tl;dr is that both Mono and .NET Core are viable long term/stable options. They both are not going anywhere. Mono will continue to release new versions (we are on 5.x now) and I think it would be reasonable to pick a version for LTS images and stick with it for awhile. Major mono version releases aren’t extremely frequent.

.NET Core is a bit more interesting with versions. There is the concept of the SDK and Runtime as two separate versioned components. We have SDK 1.0 and 1.1 and Runtime 1.0.5 and 1.1.2 as the current ‘stable’ versions. SDK and Runtimes for 2.x will be out later this year.

I understand that we can install things via a step, but I think what we really want is one of the runtimes (whether it’s mono or .NET core) installed by default so we can start to have build steps written in C# be treated more like first class citizens and not slow down a build to install the runtime.

Honestly the most effective thing to do today would be to install Mono 5.x. It’s a bit bigger than .NET Core, but everything will run on it from a build/scripting perspective.

Will 2.x be backward compatible with 1.x?

So a step written for .Net Core will run with mono LTS without any issues?

.NET Core 2.x runtime will run .NET Core apps compiled against older SDK versions such as 1.0 or 1.1, yes that is correct.

Technically, Mono should always run .NET Core apps, given the Mono runtime is new enough. What I mean by this, is I wouldn’t expect a Mono runtime that’s 2 years old to necessarily run some app built against a brand new .NET Core SDK version.

Most .NET devs will start targeting what are called .NET Standard libraries. It’s basically an API surface/contract to compile against leaving the runtime up to implementation of it. Mono and .NET Core will both support code targeting .NET Standard Library, so apps compiled against it should run fine on both runtimes.

Mono is a bigger footprint to install, but will probably get you the best C# compatibility today and will be fine going forward (I believe current stable mono version already implements .NET Standard 2.0 which is coming later this year).

.NET Core would make some developers’ lives a bit harder in the short term but would be totally usable instead of mono. It has a smaller footprint, but it does have a hard dependency requirement to do with OpenSSL.

If I were making the decision, I would probably prefer .NET Core as it’s a smaller footprint but it seems like you might not be able to work out the OpenSSL requirements with your image for it, in which case I’d give Mono some serious consideration.

So, I chatted a bit with the team. And in general I think what we want to do is the ability to do 2 things:

1.) Execute existing .NET Libraries
2.) Execute C#/F# scripts

This easily can be done already today on the Xamarin stacks since mono is already installed and ready to go.

On the other stacks this is not possible, so I think that the ideal situation is that the Android/iOS stacks would include Mono. While the footprint is larger that .NET Core it is the best bet as it work on macOS and Linux and is self contained and there is nothing else to worry about at all (such as the .NET Core OpenSSL stuff).

This will allow developer to run their existing .NET Libraries and Cake would work out of the box.

The question here, given e.g. the recent Mono 5 release: is it expected that a newer Mono version can run a C# script written for a previous one? This is quite an important factor as in case of the Mac stacks we support those for up to ~2 years without upgrading the preinstalled tools.

There is an option built into the CLI to have a certain “toolkit” tool auto updated, e.g. we do that for Go right now, but as we don’t have enough C#/Mono/.Net experience that’s a bit out of scope / should be developed by the community.

The CLI built in toolkits are designed to be able to provide an up to date version of the “toolkit” (for steps which are marked for that toolkit), in a way which does not interfere with other tools, but that requires the toolkit to be installed in a specified directory (under $HOME/.bitrise/) and the tool should run in a way that it does not affect anything else other than the steps marked for that toolkit; e.g. if another, previous version of the tool already installed on the system that should not be affected for steps not marked with that toolkit.

So in short both should be possible, either a static preinstalled version or a more up-to-date / dynamic / managed version, but the second one (CLI toolkit support) requires some expertise in how the tool can be installed & used in isolation (so that it does not affect the system when it’s not “activated” for a step), which we don’t have for C# right now (but contributions are always welcome! ;))

The question here, given e.g. the recent Mono 5 release: is it expected that a newer Mono version can run a C# script written for a previous one? This is quite an important factor as in case of the Mac stacks we support those for up to ~2 years without upgrading the preinstalled tools.

Yes, a newer mono version is expected to run a C# script written for a previous one.

That sounds awesome! :wink:

Next question then: what’s the best way to install Mono on macOS and on Linux (Ubuntu)?

Mono is available on homebrew. I would assume this is enough to make this option feasible.

I don’t mind taking a look at this if necessary… I believe we can have side by side mono installs, but yeah would require some research for how to best make this happen.

So, macOS, use brew install mono

On Ubuntu, we have the instructions here: Redirecting…

Is brew a stable distribution channel? Sorry I’m not familiar with mono outside of Xamarin, so not sure how the brew formulae is updated. Is that community supplied or officially provided? Asking because it’s not mentioned at Redirecting… for macOS

The Ubuntu one is quite straightforward, simple to apt-get install - the question there: which package should be installed? mono-devel or mono-complete? Or something else?

To be honest I’m not entirely sure who updates the homebrew formula/bottles for it. If it’s an easy enough option you can always download the pkg and install right from the website’s link. In this case the current stable is: https://download.mono-project.com/archive/5.0.1/macos-10-universal/MonoFramework-MDK-5.0.1.1.macos10.xamarin.universal.pkg

I chatted a bit more with a few team members and it seemed like the best situation would be mono + scriptcs (http://scriptcs.net/) that could be installed on top of it, which is very light weight and would allow better scripting and additional things such as packages.

So to answer your questions:
1.) Yes, Mono 5 could run apps/scripts that were built against 4.0 for instance, would be just fine :slight_smile:

So, optionally to not need scriptcs we could just have Mono installed as the base and the creator could then do the checks to ensure that ScriptCS or Cake is installed and those are fast… so maybe scrap what I said and we can add sample code in a template

1 Like