hammerkit

dotnet

Build and test a .NET project or solution, with the NuGet package cache kept on the host.

Build and test a .NET project or solution, with the NuGet package cache kept on the host. build compiles into artifacts, test runs the tests after it. Both are skipped while the files they read are unchanged, and downloaded packages are kept in .nuget/packages of your home directory, so they are not fetched again.

.hammerkit.yaml
includes:
  dotnet:
    git: https://github.com/no0dles/hammerkit.git
    ref: v1.20.0
    path: catalog/dotnet
    with:
      DOTNET_VERSION: '10.0'
      PROJECT: tests/Hello.Tests

tasks:
  check:
    deps: [dotnet:test]

PROJECT names what dotnet build and dotnet test take: a project, a solution, or . for the one in the directory. Pointing it at the test project builds the app it references as well.

Tasks

TaskWhat it doesReadsProduces
buildBuild the project, restoring its packages first.the files matched by SOURCESartifacts
testRun the tests of the project without building again.the files matched by SOURCES

The tasks pass -p:UseArtifactsOutput=true, so bin and obj go to artifacts/ at the root instead of into the project folders. The project folders are the tasks' inputs: build output written into them would change the inputs, and the next run would miss the cache. A built app is in artifacts/bin/<project>/<configuration>/, in lower case, for example dotnet artifacts/bin/Hello/release/Hello.dll.

Inputs

InputDefaultMeaning
DOTNET_VERSION10.0Tag of the mcr.microsoft.com/dotnet/sdk image the tasks run in. Quote it in with ('10.0'), or YAML reads it as the number 10.
PROJECT.The project or solution to build and test.
SOURCES{src/**,tests/**,Directory.*,global.json,nuget.config}A glob of the files the tasks read: the code under src and tests, and the shared build files at the root. Replace it when your projects live elsewhere, for example {app/**,Directory.*}.
CONFIGURATIONReleaseThe build configuration.

Packages are restored from the sources in your nuget.config and are not locked. The .NET tutorial shows a build file that restores in its own task with --locked-mode, for projects that want the restore to fail when a lock file no longer matches.

The entry

catalog/dotnet/build.yaml
# Builds and tests a .NET solution with the NuGet package cache kept on the host.
envs:
  # tag of the SDK image the tasks run in, quoted so 10.0 stays 10.0
  DOTNET_VERSION: '10.0'
  # the project or solution to build and test, as `dotnet build` takes it
  PROJECT: .
  # a glob of the files the tasks read: the projects and their code, plus the shared
  # build files at the root (Directory.Build.props, global.json, nuget.config)
  SOURCES: '{src/**,tests/**,Directory.*,global.json,nuget.config}'
  # the build configuration
  CONFIGURATION: Release

tasks:
  build:
    description: build the project into artifacts
    image: mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}
    src:
      - '${SOURCES}'
    generates: [artifacts]
    mounts:
      - $PWD/.nuget/packages:/nuget/packages
    envs:
      NUGET_PACKAGES: /nuget/packages
      DOTNET_CLI_TELEMETRY_OPTOUT: '1'
    cmds:
      - dotnet build ${PROJECT} --configuration ${CONFIGURATION} -p:UseArtifactsOutput=true -p:ArtifactsPath=$PWD/artifacts --disable-build-servers

  test:
    description: run the tests of the project
    image: mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}
    deps: [build]
    src:
      - '${SOURCES}'
    mounts:
      - $PWD/.nuget/packages:/nuget/packages
    envs:
      NUGET_PACKAGES: /nuget/packages
      DOTNET_CLI_TELEMETRY_OPTOUT: '1'
    cmds:
      - dotnet test ${PROJECT} --configuration ${CONFIGURATION} --no-build -p:UseArtifactsOutput=true -p:ArtifactsPath=$PWD/artifacts --disable-build-servers

On this page