I was recently creating a new GitHub project and I wanted to target ASP.NET Core 2.0 preview 2. I like to use AppVeyor for the CI build and for publishing to MyGet/NuGet, as I can typically just copy and paste a single file between projects to get my standard build pipeline. Unfortunately, targeting the latest preview is easier said than done! In this post, I'll show how to update your appveyor.yml file so you can build your .NET Core preview libraries on AppVeyor.

Building .NET Core projects on AppVeyor

If you are targeting a .NET Core SDK version that AppVeyor explicitly supports, then you don't really have to do anything - a simple appveyor.yml file will handle everything for you. For example, the following is a (somewhat abridged) version I use on some of my existing projects:

version: '{build}'  
branches:  
  only:
  - master
clone_depth: 1  
nuget:  
  disable_publish_on_pr: true
build_script:  
- ps: .\Build.ps1
test: off  
artifacts:  
- path: .\artifacts\**\*.nupkg
  name: NuGet
deploy:  
- provider: NuGet
  name: production
  api_key:
    secure: xxxxxxxxxxxx
  on:
    branch: master
    appveyor_repo_tag: true

There's really nothing fancy here, most of this configuration is used to define when AppVeyor should run a build, and how to deploy the NuGet package to NuGet. There's essentially no configuration of the target environment required - the build simply calls the build.ps1 file to restore and build the project.

I've switched to using Cake for most of my projects these days, often based on a script from Muhammad Rehan Saeed. If this is your first time using AppVeyor to build your projects, I suggest you take a look at my previous post on using AppVeyor.

Unfortunately, if you try and build a .NET Core 2.0 preview 2 project with this script, you'll be out of luck. I found I got random, nondescript errors, such as this one:

AppVeyor error message

Installing .NET Core 2.0 preview 2 in AppVeyor

Luckily, AppVeyor makes it easy to install additional dependencies before running your build script - you just add additional commands under the install node:

version: '{build}'  
pull_requests:  
  do_not_increment_build_number: true
install:  
  # Run additional commands here

The tricky part is working out exactly what to run! I couldn't find any official guidance on scripting the install, so I went hunting in some of the Microsoft GitHub repos. In particular I found the JavaScriptServices repo which manually installs .NET Core. The install node at the time of writing (for preview 1) was:

install:  
   # .NET Core SDK binaries
   - ps: $urlCurrent = "https://download.microsoft.com/download/3/7/F/37F1CA21-E5EE-4309-9714-E914703ED05A/dotnet-dev-win-x64.2.0.0-preview1-005977.exe"
   - ps: $env:DOTNET_INSTALL_DIR = "$pwd\.dotnetsdk"
   - ps: mkdir $env:DOTNET_INSTALL_DIR -Force | Out-Null
   - ps: $tempFileCurrent = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
   - ps: (New-Object System.Net.WebClient).DownloadFile($urlCurrent, $tempFileCurrent)
   - ps: Add-Type -AssemblyName System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::ExtractToDirectory($tempFileCurrent, $env:DOTNET_INSTALL_DIR)
   - ps: $env:Path = "$env:DOTNET_INSTALL_DIR;$env:Path"

There's a lot of commands in there. Most of it we can copy and paste, but the trickiest point is that download URL - GUIDs, really?

Luckily there's an easy way to find the URL for preview 2 - you can look at the release notes for the version of .NET Core you want to target.

Release notes for preview 2

The link you want is the Windows 64-bit SDK binaries. Just right-click, copy the link and paste into the appveyor.yml, to give the final file. The full AppVeyor file from my recent CommonPasswordValidator repository is shown below:

version: '{build}'  
pull_requests:  
  do_not_increment_build_number: true
environment:  
  DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
  DOTNET_CLI_TELEMETRY_OPTOUT: true
install:  
  # Download .NET Core 2.0 Preview 2 SDK and add to PATH
  - ps: $urlCurrent = "https://download.microsoft.com/download/F/A/A/FAAE9280-F410-458E-8819-279C5A68EDCF/dotnet-sdk-2.0.0-preview2-006497-win-x64.zip"
  - ps: $env:DOTNET_INSTALL_DIR = "$pwd\.dotnetsdk"
  - ps: mkdir $env:DOTNET_INSTALL_DIR -Force | Out-Null
  - ps: $tempFileCurrent = [System.IO.Path]::GetTempFileName()
  - ps: (New-Object System.Net.WebClient).DownloadFile($urlCurrent, $tempFileCurrent)
  - ps: Add-Type -AssemblyName System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::ExtractToDirectory($tempFileCurrent, $env:DOTNET_INSTALL_DIR)
  - ps: $env:Path = "$env:DOTNET_INSTALL_DIR;$env:Path"  
branches:  
  only:
  - master
clone_depth: 1  
nuget:  
  disable_publish_on_pr: true
build_script:  
- ps: .\Build.ps1
test: off  
artifacts:  
- path: .\artifacts\**\*.nupkg
  name: NuGet
deploy:  
- provider: NuGet
  server: https://www.myget.org/F/andrewlock-ci/api/v2/package
  api_key:
    secure: xxxxxx
  skip_symbols: true
  on:
    branch: master
- provider: NuGet
  name: production
  api_key:
    secure: xxxxxx
  on:
    branch: master
    appveyor_repo_tag: true

Now when AppVeyor runs, you can see it running the install steps before running the build script:

Installing .NET Core

Using predictable download URLs

Shortly after battling with this issue, I took another look at the JavaScriptServices project, and noticed they'd switched to using nicer URLs for the SDK binaries. Instead of using the horrible GUIDy URLs, you can use zip files stored on an Azure CDN instead. These URLs just require you know the SDK version (including the build number) For example:

It looks like preview 2 is the first to be available at this URL, but as you can see, later builds are also available if you want to work with the bleeding edge builds.

Summary

In this post I showed how you could use the install node of an appveyor.yml file to install ASP.NET Core 2.0 preview 2 into your AppVeyor build pipeline. This lets you target preview versions of .NET Core in your build pipeline, before they're explicitly supported by AppVeyor.