Skip to main content
The same.yaml file is the core configuration file for a project in same. It defines the project metadata, available tools, and the tasks that can be executed.

Schema

version

version
string
required
The version of the configuration schema. Currently, the only supported version is “1”.

project

project
string
required
The name of the project. This is used for namespacing tasks when referenced from other projects or the workspace root.

tools

tools
map<string, string>
A map of tool aliases to their Nix package specifications. These tools are available to be used by tasks within this project.The key is the alias (e.g., go, lint) and the value is the Nix package specifier (e.g., [email protected], golangci-lint).

tasks

tasks
map<string, Task>
required
A map of task definitions. The key is the task name (e.g., build, test).

Task Definition

Each entry in the tasks map defines a specific unit of work.

input

input
string[]
A list of file glob patterns that are inputs to this task. Changes to these files will invalidate the task’s cache.Examples: ["src/**/*.go"], ["go.mod"], ["cmd", "internal"]

cmd

cmd
string[]
required
The command to execute. This is an array of strings representing the command and its arguments.

target

target
string[]
A list of output files or directories that this task produces. These are the artifacts generated by the command.

tools

tools
string[]
A list of tool aliases (defined in the top-level tools section or inherited from the workspace) that this task requires.

dependsOn

dependsOn
string[]
A list of other tasks that this task depends on. The same scheduler ensures these dependencies are executed successfully before running this task.Dependencies can be:
  • Local tasks: build
  • Cross-project tasks: lib:build

environment

environment
map<string, string>
A map of environment variables to set for the task execution.

workingDir

workingDir
string
The working directory for the command execution, relative to the project root.

rebuild

rebuild
string
default:"on-change"
Controls when the task should execute.
  • on-change (default): Execute only if inputs have changed (cache-based)
  • always: Execute on every run, bypassing the cache
Use always for tasks that produce non-deterministic outputs (e.g., timestamps, fetching external data, debugging).Note: Downstream tasks still honor their own rebuild strategy. If an “always” task produces identical outputs, dependent tasks with on-change won’t re-execute.

Example

same.yaml
version: "1"
project: "same"

tools:
  go: [email protected]
  lint: [email protected]

tasks:
  # Install dependencies
  install:
    input: ["go.mod", "go.sum"]
    cmd: ["go", "mod", "download"]
    tools: ["go"]

  # Run linter
  lint:
    input: ["cmd", "internal"]
    cmd: ["golangci-lint", "run"]
    tools: ["lint"]
    dependsOn: ["install"]

  # Build the binary
  build:
    input: ["cmd", "internal"]
    cmd: ["go", "build", "-o", "bin/same", "./cmd/same"]
    target: ["bin/same"]
    tools: ["go"]
    dependsOn: ["lint"]

  # Generate build timestamp (always runs)
  timestamp:
    cmd: ["sh", "-c", "date +%s > build-time.txt"]
    target: ["build-time.txt"]
    rebuild: always