Skip to content

Getting Started

Scott Singleton edited this page May 25, 2026 · 5 revisions

Getting Started

Three commands from zero to running your first target.

Prerequisites

  • A supported .NET SDK installed: .NET 8, 9, or 10. Tamp's first-party packages multi-target all three; pick whichever is on your dev machine. (See ADR 0015 for why.)
  • git (for repository discovery — Tamp walks up looking for .git to find the project root).

The three-line on-ramp

dotnet tool install -g dotnet-tamp        # one-time, on your machine
cd your-repo                              # any .NET solution layout
dotnet tamp init                          # scaffold build/Build.cs
dotnet tool restore && dotnet tamp Test   # restore the local tool, run the scaffolded Test target

That's it. tamp init writes five files into the current directory:

Path Purpose
build/Build.cs Build script (shape varies by template) with Clean / Restore / Compile / Test / Default targets
build/Build.csproj Pins Tamp.Core and Tamp.NetCli.V10 at the version of the CLI that scaffolded you
.config/dotnet-tools.json Registers dotnet-tamp as a local tool (only if absent — your existing manifest is preserved)
tamp.sh POSIX entry-point shim that auto-restores the tool manifest on first run, then forwards to dotnet tamp
tamp.cmd Windows entry-point shim (same behavior as tamp.sh)

The scaffold is embedded in the CLI binary, so tamp init works offline. It refuses to overwrite an existing build/Build.cs unless --force is passed; re-running it on a tamped repo without --force is a clean no-op.

Templates (0.2.0+)

Pick the shape that matches your repo. Default is minimal:

tamp init --template minimal      # Clean / Restore / Compile / Test (the default)
tamp init --template library      # minimal + typed Pack target with nupkg output dir
tamp init --template monorepo     # per-project Test fan-out + Ci aggregate + Pack

All three are embedded — no network round-trip, no template-package install. Run tamp init --list-templates to enumerate.

What you get — the scaffolded Build.cs

After tamp init, your build/Build.cs looks like:

using Tamp;
using Tamp.NetCli.V10;

class Build : TampBuild
{
    public static int Main(string[] args) => Execute<Build>(args);

    [Parameter("Build configuration")]
    Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release;

    [Solution] readonly Solution Solution = null!;

    AbsolutePath Artifacts => RootDirectory / "artifacts";

    Target Clean => _ => _.Executes(() => CleanArtifacts());

    Target Restore => _ => _
        .Internal()
        .Executes(() => DotNet.Restore(s => s.SetProject(Solution.Path)));

    Target Compile => _ => _
        .DependsOn(Restore)
        .Executes(() => DotNet.Build(s => s
            .SetProject(Solution.Path)
            .SetConfiguration(Configuration)
            .SetNoRestore(true)));

    Target Test => _ => _
        .DependsOn(Compile)
        .Executes(() => DotNet.Test(s => s
            .SetProject(Solution.Path)
            .SetConfiguration(Configuration)
            .SetNoBuild(true)));

    Target Default => _ => _
        .Default()
        .DependsOn(Compile);
}

Five elements doing the work:

  1. class Build : TampBuild — your build inherits the framework's entry point and statics.
  2. Execute<Build>(args) — the framework's Main shim. Reflects over your class, builds the target graph, parses args, dispatches.
  3. [Parameter] on Configuration — auto-bound from --configuration <value> on the CLI or the CONFIGURATION environment variable, with IsLocalBuild ? Debug : Release as the default.
  4. Target properties — declarative target definitions. Every target is top-level by default in 1.1.0+; mark internal helpers with .Internal(). .Default() on a target makes it the no-args entry point (replaces the legacy "literally-named-Default" convention, which still works as a fallback).
  5. DotNet.Build(...) — typed wrapper that returns a CommandPlan the runner dispatches.

Running targets

dotnet tamp                       # runs Default → Compile (Debug locally, Release on CI)
dotnet tamp Test                  # the scaffolded test target
dotnet tamp Compile --configuration Release   # override the parameter
dotnet tamp Compile --dry-run     # print the dotnet build command, execute nothing
dotnet tamp --list                # show top-level targets

The output ends with a build summary table:

─── Build Summary ───
  Target    Status   Duration
  Compile   ✓ Done   1.4 s
                     ─────
  Total              1.4 s

tamp init reference

tamp init                                 # default minimal template in cwd
tamp init --template library              # pick a non-default template (0.2.0+)
tamp init --template monorepo             # per-project Test fan-out (0.2.0+)
tamp init --solution path/to/Foo.slnx     # explicit solution (otherwise auto-detected)
tamp init --dry-run                       # print would-write list; touch nothing
tamp init --force                         # overwrite existing files (0.2.0+)
tamp init --list-templates                # list templates from registered sources
tamp init --help                          # full help

Solution detection: if there's exactly one .slnx (preferred) or .sln at the repo root, tamp init picks it up. Zero or multiple solutions — the scaffold falls back to [Solution]'s auto-discovery and tells you in the output.

Versions in the generated build/Build.csproj are pinned to the CLI's own version — the CLI that scaffolded you ships with a known-good Tamp.Core. Floating versions in build scripts have caused enough pain that we don't generate them. To upgrade Tamp later, edit the two PackageReference lines manually (or wait for tamp upgrade, deferred).

Template availability

All three embedded templates (minimal, library, monorepo) ship inside the CLI binary and work offline. NuGet-distributed templates (e.g. Tamp.Templates.AspNet) are resolved at scaffold time when you pass --template aspnet and the corresponding NuGet package is restorable. The --template-source <pkg> flag for pinning a specific template package is planned for 0.3.0+.

Bootstrapping a non-empty project

tamp init works on existing repos that already have a .slnx / .sln solution. The probe finds your solution; the generated Build.cs references it via [Solution]. If you already have a build/Build.cstamp init refuses to overwrite and tells you. --force lands in 0.2.0.

For repos with a layout the probe doesn't understand (multi-solution monorepos, Yarn-workspace polyglots), tamp init still scaffolds the minimal Build.cs and you wire up the [Solution] / sub-build details by hand. Monorepo / Yarn / Turborepo probes land in 0.2.0.

What if I'm not building a .NET project?

Tamp's build script is .NET (that's the framework runtime), but what it builds can be anything — a pure-React app, a Python package, a Rust crate, a Helm chart, a polyrepo with one Yarn workspace and three Bicep modules. The tamp init minimal template happens to scaffold against a .NET solution because that's the common starter shape, but adopters with a different stack just remove the [Solution] field from Build.cs and use wrapper packages for whatever toolchain they have — Tamp.Yarn.V4, Tamp.Bicep, Tamp.Docker.V27, Tamp.Playwright.V1, anything from the Module Catalog.

For multi-repo products, declare the logical project name + area on your build class so telemetry rolls up across components:

[BuildProject("HoldFast", Area = "frontend")]    // language-agnostic; works for any stack
class Build : TampBuild { ... }

That surfaces on the diagnostic spans as tamp.build.project.name="HoldFast" and tamp.build.project.area="frontend". Without the attribute, Tamp falls back to the [Solution] filename (when present) or the repo directory name — pick the attribute when neither is the right product identifier.

Where next

  • Build Script Authoring — the full DSL surface: dependencies, ordering, triggers, conditionals, failure handlers.
  • Parameter & Secret Injection[Solution], [GitRepository], [NuGetPackage], [Secret], [BuildProject].
  • Module Catalog — every wrapper Tamp ships and how its surface is shaped.
  • Pitfalls — destructive Clean patterns, yarn berry recovery, BuildKit migration warnings. Worth a five-minute read before your first non-trivial build.

Clone this wiki locally