/cake-build

Demonstrates a basic build of a .NET Core NuGet package using https://cakebuild.net/

Primary LanguageShellMIT LicenseMIT

Cake build

Package Release Pre-release
Contoso.Hello.Logic MyGet MyGet
Contoso.Hello.SuperLogic MyGet MyGet
CI Status Platform(s) Framework(s) Test Framework(s)
Travis CI Build Status Linux, OS X nestandard2.0 netcoreapp2.0.5
AppVeyor Build Status Windows nestandard2.0, net461 netcoreapp2.0.5, net461
CircleCI Build Status Docker: microsoft/dotnet:2.0.5-sdk-2.1.4-jessie nestandard2.0 netcoreapp2.0.5

Demonstrates a basic build of a .NET Core NuGet package using Cake.

I tried to create a somewhat realistic scenario without writing too much code:

  • The solution contains two projects which will be packed as NuGet packages.
    • The SuperLogic project depends from Logic and when packing this project reference will be turned into a NuGet package reference (handled out of the box by dotnet pack).
    • The Logic project references a NuGet package from nuget.org via a PackageReference, dotnet pack will turn this into a package reference.
  • The projects target both nestandard2.0 and net461 so they can be used with the .NET Framework (net461 and above).
  • The solution contains a test project.
  • Use SemVer to version the DLLs and the NuGet packages.

Benefits over a nuspec file

  • A single file describing the package and the project instead of two (*.csproj and *.nuspec)
  • References (projects or NuGet packages) are resolved automatically. There is no need to tweak a file manually anymore!

Referencing a project without turning it into a package reference

The SuperLogic project depends on the ExtraLogic project but we don't want to ship ExtraLogic as a package. Instead we want to include Contoso.Hello.ExtraLogic.dll in the SuperLogic package directly. Currently this is not supported out of the box but the team is tracking it.

Luckily this issue provides a workaround. All the modifications will take place in SuperLogic.csproj.

  • In the <PropertyGroup> section add the following line:
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);IncludeReferencedProjectInPackage</TargetsForTfmSpecificBuildOutput>
<ProjectReference Include="..\ExtraLogic\ExtraLogic.csproj">
  <PrivateAssets>all</PrivateAssets>
</ProjectReference>
  • Finally add the target responsible of copying the DLL:
<Target Name="IncludeReferencedProjectInPackage">
  <ItemGroup>
    <BuildOutputInPackage Include="$(OutputPath)Contoso.Hello.ExtraLogic.dll" />
  </ItemGroup>
</Target>

Pinning the version of Cake

To pin the version of Cake, add the following lines to your .gitignore file:

tools/*
!tools/packages.config

Pinning the version of Cake guarantees you'll be using the same version of Cake on your machine and in the build server.

Reusing this to bootstrap your project

CI

Each time a commit is pushed to master or features/* Travis CI, CircleCI and AppVeyor will build the changes.

In case of a successful build AppVeyor will:

  • On master
    • Create a GitHub release
    • Publish the NuGet packages (including symbols) to gabrielweyer feed
  • On features/*
    • Create a GitHub pre-release
    • Publish the NuGet packages (including symbols) to gabrielweyer-pre-release feed

Travis CI

Build status is visible here.

Travis CI has a few limitations:

  • Linux and OS X only so you can't build any net* Frameworks
    • For this reason I'm not publishing the NuGet packages from Travis CI
    • build.sh (the Cake bootstrapper) has been modified to support Cake Core CLR
    • build.cake has been modified
      • Targets netstandard2.0 / netcoreapp2.0 only on Travis (search for TravisCI.IsRunningOnTravisCI)
      • Custom implementation of GitVersion (search for SemVer), the built-in helper wouldn't work on mono
  • Doesn't parse test result files
  • Artifacts have to be uploaded to S3

AppVeyor

Build status is visible here.

  • Windows only
  • Can target both .NET Core and .NET Framework
    • For this reason we'll publish the NuGet packages using AppVeyor
  • Can create a GitHub release and tag the repository if required
  • Supports artifacts and test results
  • You can modify AppVeyor's build number programatically
    • Cake integrates with AppVeyor: publish test results, upload artifacts, update build number...

CircleCI

Build status is visible here.

  • Linux and OS X
  • Build in Docker containers
  • Supports artifacts and test results

Status checks

The master branch is protected:

  • Force push is disabled on master
  • master cannot be deleted
  • Non-protected branches (such as features/*) cannot be merged into master until they satisfy:
    • An AppVeyor passing build
    • A Travis passing build
    • A CircleCI passing build

After a branch was configured as protected, GitHub will suggest available status checks.