NUKE Build System

repository·develop·Indexed 25 days ago

https://github.com/nuke-build/nuke

A C#/.NET build automation system that treats build scripts as first-class C# code. NUKE allows developers to write build automation as regular C# console applications, providing full OOP capabilities, IDE features like debugging and refactoring, and automatic CI/CD configuration generation. Key features include parameter injection, path abstraction, model access, and a flexible target dependency system with execution, ordering, and trigger dependencies.

Tokens
34.3K
Snippets
124
Records
182
Agent score
86%

What's inside NUKE

  1. Overview of NUKE Build System

    develop

    NUKE is an AKEless build system for C#/.NET. It allows developers to write build automation as regular C# console applications, providing full Object-Oriented Programming (OOP) capabilities, including code completion, debugging, refactoring, and code formatting within an IDE.

    Key features include:

    • Parameter injection: Easily pass parameters to build steps.
    • Path abstraction: Handles path separators automatically.
    • Model access: Provides access to solution and project models.
    • Step sharing: Allows sharing build steps across different repositories.
    • CI/CD Generation: Can automatically generate CI/CD configurations (like YAML) that support parallelization across multiple agents to optimize throughput.
  2. Quickstart: Set up a NUKE build

    develop

    To quickly set up a new NUKE build in an existing repository, follow these steps:

    1. Install the NUKE global tool.
    2. Navigate to your repository and run the :setup command to initialize the build structure.
    3. Run the build using the nuke command.
    4. Open the generated build project to explore the default Build class.
  3. Import TeamCity secrets into Nuke parameters

    develop

    To use secret variables stored in TeamCity, use the ImportSecrets property on the [TeamCity] attribute and the [TeamCityToken] attribute to map the secret to a Nuke [Parameter]. This automatically configures the TeamCity settings to load the secret into an environment variable for your build.

    [TeamCity(
        // ...
        ImportSecrets = new[] { nameof(NuGetApiKey) })]
    [TeamCityToken(nameof(NuGetApiKey), "<guid>")]
    class Build : NukeBuild
    {
        [Parameter] [Secret] readonly string NuGetApiKey;
    }
  4. Access Jenkins environment variables via the Jenkins class

    develop

    When running NUKE builds on Jenkins, you can access predefined Jenkins environment variables using the Jenkins.Instance property. This provides strongly-typed access to build metadata such as branch names, commit hashes, and job details, avoiding the need to manually parse environment strings.

    Jenkins Jenkins => Jenkins.Instance;
    
    Target Print => _ => _
        .Executes(() =>
        {
            Log.Information("Branch = {Branch}", Jenkins.GitBranch);
            Log.Information("Commit = {Commit}", Jenkins.GitCommit);
        });
  5. Define the Build class structure

    develop

    A NUKE build project is a .NET console application where the main class is named Build and inherits from NukeBuild. You must define a Main method to invoke the build execution. You can specify one, multiple, or no default targets in the Execute call.

    // Single Default Target
    class Build : NukeBuild
    {
        public static int Main() => Execute<Build>(x => x.Compile);
    
        // Target definitions
    }
    
    // Multiple Default Targets
    class Build : NukeBuild
    {
        public static int Main() => Execute<Build>(x => x.Test, x => x.Pack);
    
        // Target definitions
    }
    
    // No Default Target
    class Build : NukeBuild
    {
        public static int Main() => Execute<Build>();
    
        // Target definitions
    }
  6. Load a Solution using the SolutionAttribute

    develop

    The easiest way to load a solution in a NUKE build is to declare a Solution field decorated with the [Solution] attribute. This allows NUKE to automatically inject the solution instance. You can access the solution path and its directory via the Solution and Solution.Directory properties.

    [Solution]
    readonly Solution Solution;
    
    Target Print => _ => _
        .Executes(() =>
        {
            Log.Information("Solution path = {Value}", Solution);
            Log.Information("Solution directory = {Value}", Solution.Directory);
        });
  7. Manage secrets using the NUKE CLI

    develop

    NUKE provides an integrated encryption utility to save and load secret values (like passwords or auth-tokens) directly within parameter files. This avoids the security risks of using plain-text environment variables.

    To start managing secrets, run the :secrets command. You can optionally specify a profile.

    Workflow:

    1. Run the command.
    2. If no secrets exist, you will be prompted to choose a password. If secrets already exist, you must provide the existing password.
    3. Select secret parameters from a list to set or update their values.
    4. Accept or discard your changes.

    Note for macOS users: You can choose to generate a password and save it to your macOS Keychain to leverage native security tooling.

    nuke :secrets [profile]
  8. Remove secrets from NUKE

    develop

    To delete a secret, manually remove the corresponding key-value pair from your parameter file.

    Important: If you lose the password used to encrypt your secrets, you cannot recover them. In this case, you must remove all secrets from the parameter file and re-populate them using the nuke :secrets command.

  9. Update structured data in files atomically

    develop

    Instead of performing separate read, modify, and write steps, use the atomic Update<T> methods to modify a file in a single operation. This is recommended for tasks like updating version numbers or configuration values.

    Available methods:

    • jsonFile.UpdateJson<T>(update: x => ...)
    • xmlFile.UpdateXml<T>(update: x => ...)
    • yamlFile.UpdateYaml<T>(update: x => ...)
    // JSON
    jsonFile.UpdateJson<Configuration>(
        update: x => x.Value = "new-value");
    
    // XML
    xmlFile.UpdateXml<Configuration>(
        update: x => x.Value = "new-value");
    
    // YAML
    yamlFile.UpdateYaml<Configuration>(
        update: x => x.Value = "new-value");
  10. Use MinVer for repository-based versioning

    develop

    To generate version numbers using MinVer, install the minver-cli package and use the [MinVer] attribute in your Build.cs file. This populates a MinVer field.

    nuke :add-package minver-cli
    [MinVer]
    readonly MinVer MinVer;
    
    Target Print => _ => _
        .Executes(() =>
        {
            Log.Information("MinVer = {Value}", MinVer.Version);
        });