Cross Platform CI with CoreRT and AppVeyor

CoreRT is an ahead-of-time (AOT) compiler and runtime for .NET Core. It builds .NET Core applications into a single, small binary that runs without requiring .NET Core to be installed on the system. This makes distribution easy, especially to Mac OS and Linux, which may not have .NET Core installed. On all platforms, the program will have a faster start-up time and lower memory footprint.

Like most developers, I have a pet static site generator I’m working on. As it’s a command line utility that will be distributed to users that most likely won’t have .NET Core installed, I decided to try CoreRT. The initial setup was simple, but it took some time to figure out how to set up continuous integration (CI) on AppVeyor. I wanted the CI process to produce binaries artifacts from the master branch for each platform. As a bonus, if I tag a commit, it should build a release for each platform and post them to the GitHub Releases page.

One drawback of AppVeyor is that it does not yet support Mac OS. However, there are plans to support it sometime this year. I figure that if I have it working on both Windows and Linux, it should hopefully not be too difficult to add Mac OS support.

AppVeyor uses a YAML file for its configuration, and like most CI platforms, there’s more than one way to accomplish your goal. I found that the following configuration is a nice mixture of Don’t-Repeat-Yourself and maintainability:

version: '0.0.{build}'
clone_depth: 1
  # Windows with VS2017
  - Visual Studio 2017
  # default version of 'ubuntu' is old for compatibility reasons. Specify the newest LTS.
  - ubuntu1804
  - master
# items prefixed with 'cmd:' run only on Windows
# items prefixed with 'sh:' run only on Ubuntu
  - cmd: git config --global core.autocrlf true
  # application dependencies
  - cmd: choco install pandoc
  - sh:  wget && sudo dpkg -i pandoc-2.3.1-1-amd64.deb
  # corert dependencies
  - sh:  sudo apt-get install -y clang libkrb5-dev
  - dotnet --version
  - dotnet restore --verbosity m
  - dotnet build
  - cd Nessie.Tests
  - dotnet test
  - cd ..
  - cmd: dotnet publish -c release -r win-x64 -o dist/windows
  # specifying the absolute path here is required to remove paths from archive
  - cmd: 7z a Nessie/dist/windows/ %APPVEYOR_BUILD_FOLDER%/Nessie/dist/windows/nessie.exe
  # by default, CoreRT on linux tries to use clang-3.9, reset this to version independent
  - sh:  export CppCompilerAndLinker=clang
  - sh:  dotnet publish -c release -r linux-x64 -o dist/linux
  - sh:  7z a Nessie/dist/linux/ $APPVEYOR_BUILD_FOLDER/Nessie/dist/linux/Nessie
# for / matrix docs
        - image: Visual Studio 2017
     - path: 'Nessie/dist/windows/'
       name: nessie-windows

        - image: ubuntu1804
      - path: 'Nessie/dist/linux/'
        name: nessie-linux
  provider: GitHub
  # encrypted token, it's ok to be in version control
    secure: zQl909f8bNxmaKdpgiE730kw9vjsNvoV0SjwN/fk3lv9dy7d9cdhgo0/iz/apRqc
  artifact: nessie-windows, nessie-linux
  prerelease: true
    appveyor_repo_tag: true

I won’t go through this line-by-line, as hopefully the comments make everything clear. Here are the things that took me a while to figure out:

This is more of a brain dump than a blog post, but I hope this ends up being useful to other people out there working with CoreRT and AppVeyor!

tagged as csharp, corert, appveyor and continuous-integration