Operations
| Operation | Description |
|---|---|
Root | The root path of the project (where build.csando is located). Returns BuildPath, not DirectoryRef. Use for path construction and string arguments. For operations requiring DirectoryRef (Npm, Cloudflare, etc.), use Directory(".") instead. Supports path combining with the / operator. |
Temp | Temporary files directory (root/.ando/tmp). Supports path combining with the / operator. Use for caches, intermediate files, etc. |
Env | Gets an environment variable. Global function — call as Env(), not Ando.Env(). By default throws if not set. Pass required: false to return null. The second parameter is a bool, not a default value — use null-coalescing (??) for defaults. |
Directory | Creates a DirectoryRef — required by operations that need a working directory (Npm, Cloudflare, Playwright, Ando.Build). Global function — call as Directory(). Note: Root returns BuildPath, not DirectoryRef. Use Directory(".") when an operation needs a reference to the project root. Supports path combining with the / operator. |
DefineProfile | Defines a build profile that can be activated via CLI. Takes a single argument (the profile name). Returns a Profile object with implicit bool conversion — use directly in if statements. There is no HasProfile() or Profile() function. Use -p or --profile CLI flag to activate. |
UseImage | Set the Docker image for the current build container. Must be called before build steps execute. |
CopyArtifactsToHost | Register files to copy from the container to the host after the build completes. The first parameter is the path inside the container (relative to /workspace or absolute), and the second is the destination on the host (relative to project root or absolute). |
CopyZippedArtifactsToHost | Register files to be archived and copied from the container to the host after the build completes. Creates a single archive file for faster transfer of many small files. Supports .tar.gz (default) and .zip formats. If the destination is a directory, creates artifacts.tar.gz in that directory. |
Build | Run a nested build script. Accepts a directory (runs build.csando in that directory) or a specific .csando file path. The child build runs in its own isolated container with its own environment file ( .env.ando or .env) and context. |
Log | Logging operations for outputting messages during the build. Has four methods: Log.Info() (visible at Normal verbosity), Log.Warning() (visible at Minimal+), Log.Error() (always visible), and Log.Debug() (only at Detailed verbosity). |
Operation Details
Root
source
The root path of the project (where build.csando is located). Returns BuildPath, not DirectoryRef. Use for path construction and string arguments. For operations requiring DirectoryRef (Npm, Cloudflare, etc.), use Directory(".") instead. Supports path combining with the / operator.
var output = Root / "dist";
Dotnet.Publish(app, o => o.Output(output));Temp
source
Temporary files directory (root/.ando/tmp). Supports path combining with the / operator. Use for caches, intermediate files, etc.
var cache = Temp / "cache";
var intermediate = Temp / "build-output";Env
source
Gets an environment variable. Global function — call as Env(), not Ando.Env(). By default throws if not set. Pass required: false to return null. The second parameter is a bool, not a default value — use null-coalescing (??) for defaults.
var apiKey = Env("API_KEY");
var optional = Env("OPTIONAL_VAR", required: false);
var lang = Env("SITE_LANG", required: false) ?? "en";Directory
source
Creates a DirectoryRef — required by operations that need a working directory (Npm, Cloudflare, Playwright, Ando.Build). Global function — call as Directory(). Note: Root returns BuildPath, not DirectoryRef. Use Directory(".") when an operation needs a reference to the project root. Supports path combining with the / operator.
var frontend = Directory("./frontend");
Npm.Ci(frontend);
Cloudflare.PagesDeploy(frontend / "dist", "my-site");
Npm.Ci(Directory(".")); // Use Directory(".") instead of RootDefineProfile
source
Defines a build profile that can be activated via CLI. Takes a single argument (the profile name). Returns a Profile object with implicit bool conversion — use directly in if statements. There is no HasProfile() or Profile() function. Use -p or --profile CLI flag to activate.
var release = DefineProfile("release");
var publish = DefineProfile("publish");
Dotnet.Build(app);
if (release) {
Git.Tag("v1.0.0");
GitHub.CreateRelease(o => o.WithTag("v1.0.0"));
}
// CLI usage:
// ando -p release
// ando -p publish,releaseUseImage
source
Set the Docker image for the current build container. Must be called before build steps execute.
Ando.UseImage("ubuntu:24.04");
Ando.UseImage("mcr.microsoft.com/dotnet/sdk:9.0");
Ando.UseImage("node:22");CopyArtifactsToHost
source
Register files to copy from the container to the host after the build completes. The first parameter is the path inside the container (relative to /workspace or absolute), and the second is the destination on the host (relative to project root or absolute).
Ando.CopyArtifactsToHost("dist", "./dist");
Ando.CopyArtifactsToHost("bin/Release", "./output");CopyZippedArtifactsToHost
source
Register files to be archived and copied from the container to the host after the build completes. Creates a single archive file for faster transfer of many small files. Supports .tar.gz (default) and .zip formats. If the destination is a directory, creates artifacts.tar.gz in that directory.
Ando.CopyZippedArtifactsToHost("dist", "./output");
Ando.CopyZippedArtifactsToHost("dist", "./dist/binaries.tar.gz");
Ando.CopyZippedArtifactsToHost("dist", "./dist/binaries.zip");Build
source
Run a nested build script. Accepts a directory (runs build.csando in that directory) or a specific .csando file path. The child build runs in its own isolated container with its own environment file (.env.ando or .env) and context.
Ando.Build(Directory("./website"));
Ando.Build(Directory("./website") / "deploy.csando");
Ando.Build(Directory("./api"), o => o.WithDind());Log
source
Logging operations for outputting messages during the build. Has four methods: Log.Info() (visible at Normal verbosity), Log.Warning() (visible at Minimal+), Log.Error() (always visible), and Log.Debug() (only at Detailed verbosity).
Log.Info("Starting deployment...");
Log.Warning("Cache is stale, rebuilding");
Log.Error("Failed to connect to server");
Log.Debug("Processing item 5 of 10");Globals
These globals are available in all build.csando scripts without any prefix or import. Env(), Directory(), and DefineProfile() are global functions — call them directly, not as methods on the Ando object.
// Directory reference (returns DirectoryRef)
var frontend = Directory("./frontend");
// Path construction with / operator (Root returns BuildPath)
var output = Root / "dist";
var cache = Temp / "build-cache";
// Access environment variables (global function, not Ando.Env)
var dbUrl = Env("DATABASE_URL");
var apiKey = Env("API_KEY", required: false);
var lang = Env("SITE_LANG", required: false) ?? "en";
// Use regular C# variables for custom values
var buildNumber = "123";
Environment Variables
The Env() function retrieves environment variables. The second parameter is required: (a bool), NOT a default value string.
// Required (default) - throws if not set
var apiKey = Env("API_KEY");
// Optional - returns null if not set
var optional = Env("OPTIONAL_VAR", required: false);
// Optional with default value - use null-coalescing (??)
var lang = Env("SITE_LANG", required: false) ?? "en";
// WRONG: second parameter is bool, not a default value
// var lang = Env("SITE_LANG", "en"); // Compile error!
There is no SetEnv() function. Set environment variables via .env.ando files, OS environment, or CI/CD configuration.
BuildPath vs DirectoryRef
ANDO has two path types. Operations like Npm.Ci(), Cloudflare.PagesDeploy(), Playwright.Test(), and Ando.Build() require DirectoryRef, not BuildPath.
// Root returns BuildPath - use for path construction
var outputPath = Root / "dist";
Dotnet.Publish(app, o => o.Output(outputPath)); // OK: accepts string/BuildPath
// Directory() returns DirectoryRef - use for operations
var frontend = Directory("./frontend");
Npm.Ci(frontend); // OK: requires DirectoryRef
// WRONG: Npm.Ci(Root) - BuildPath is not DirectoryRef
// Use Directory(".") to reference the project root as DirectoryRef:
Npm.Ci(Directory(".")); // OK
Profiles
Profiles allow conditional execution of build steps. DefineProfile() takes a single argument (the name) and returns a Profile with implicit bool conversion. There is no HasProfile(), HasAnyProfile(), or Profile() function.
// Define profiles at the top of your build.csando
var release = DefineProfile("release");
var publish = DefineProfile("publish");
// Project references
var app = Dotnet.Project("./src/App/App.csproj");
var tests = Dotnet.Project("./tests/App.Tests/App.Tests.csproj");
// Always run build and tests
Dotnet.Build(app);
Dotnet.Test(tests);
// Only run when "release" profile is active
if (release) {
Dotnet.Publish(app, o => o.Output(Root / "dist"));
Git.Tag("v1.0.0");
}
// Only run when "publish" profile is active
if (publish) {
Nuget.EnsureAuthenticated();
Nuget.Pack(app);
Nuget.Push(app, o => o.SkipDuplicate());
}
// CLI usage:
// ando # Build and test only
// ando -p release # Build, test, publish, and tag
// ando -p publish # Build, test, pack, and push to NuGet
Log
Logging operations for outputting messages during the build. Visibility depends on verbosity level.
// Informational messages (visible at Normal verbosity)
Log.Info("Starting build process...");
// Warnings (visible at Minimal verbosity and above)
Log.Warning("Cache directory not found, rebuilding from scratch");
// Errors (always visible)
Log.Error("Build failed: missing dependency");
// Debug messages (only visible at Detailed verbosity)
Log.Debug($"Processing file: {filePath}");
Build Configuration
Build configuration, artifact copying, and nested builds. Use these to set the Docker image, copy outputs to host, and run child build scripts.
// ando-doc-snippet-test
// Set the Docker image for the build container
Ando.UseImage("mcr.microsoft.com/dotnet/sdk:9.0");
// Copy artifacts from container to host after build
Ando.CopyArtifactsToHost("dist", "./dist");
// Copy as compressed archive (faster for many small files)
Ando.CopyZippedArtifactsToHost("dist", "./output"); // Creates ./output/artifacts.tar.gz
Ando.CopyZippedArtifactsToHost("dist", "./dist/binaries.tar.gz"); // Specific filename
Ando.CopyZippedArtifactsToHost("dist", "./dist/binaries.zip"); // Zip format
// Run a child build in a subdirectory
Ando.Build(Directory("./website"));
// Run a specific build file
Ando.Build(Directory("./website") / "deploy.csando");
// Child build with Docker-in-Docker enabled
Ando.Build(Directory("./integration-tests"), o => o.WithDind());
Options Reference
Build Options
| Option | Description |
|---|---|
WithVerbosity(string) | Set output verbosity level. Values: “Quiet” (errors only), “Minimal” (warnings and errors), “Normal” (default), “Detailed” (debug output). |
ColdStart(bool) | Force a fresh container for this build, ignoring any warm container cache. Use when you need a clean environment or are debugging container state issues. |
WithDind(bool) | Enable Docker-in-Docker mode. Required when the child build needs to run Docker commands (e.g., building images, running docker-compose). Mounts the Docker socket into the container. |
WithImage(string) | Override the Docker image for this child build. Use when the child build requires different tools than the parent (e.g., Node.js build in a .NET project). |