maru2

package module
v0.8.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 8, 2025 License: Apache-2.0 Imports: 39 Imported by: 0

README

maru2 (for now)

GitHub Tag GitHub go.mod Go version GitHub License CodeQL Go Report Card codecov CI Status

[!IMPORTANT] Until this callout is removed, maru2 is in maintenance mode while other efforts take priority.

The current API is considered stable and any breaking changes will be done in a backwards compatible manner.

Dependency and security updates will still continue to be performed as needed.

Issues and Pull Requests are welcome, the CLI team may just take longer to respond.

A simple task runner.

Installation

via brew:

brew install defenseunicorns/tap/maru2

via curl:

curl -s https://raw.githubusercontent.com/defenseunicorns/maru2/main/install.sh | bash

via wget:

wget -q -O - https://raw.githubusercontent.com/defenseunicorns/maru2/main/install.sh | bash

via go install:

go install github.com/defenseunicorns/maru2/cmd/maru2@latest

or if you like to live dangerously:

go install github.com/defenseunicorns/maru2/cmd/maru2@main

or checkout the latest release artifacts.

Documentation

View CLI usage w/ maru2 --help

If you are coming from maru-runner / uds run and looking to transition, checkout the migration guide.

If you are looking to embed maru2 into another Cobra CLI, take a look at the example in cmd/internal.

If you are looking for Go docs, the best way to view them is go doc -http or visit pkg.go.dev.

Contributing

Thanks for taking time out of your day to contribute! Read the contributing guide for more information.

Schema Validation

Enabling schema validation in VSCode:

    "yaml.schemas": {
        "https://raw.githubusercontent.com/defenseunicorns/maru2/main/maru2.schema.json": "tasks.yaml",
    },

Per file basis:

# yaml-language-server: $schema=https://raw.githubusercontent.com/defenseunicorns/maru2/main/maru2.schema.json

Documentation

Overview

Package maru2 provides a simple task runner.

Index

Constants

View Source
const (
	GitHubActionsEnvVar = "GITHUB_ACTIONS"
	GitLabCIEnvVar      = "GITLAB_CI"
)

Environment variables used to determine what CI environment (if any) maru2 is in

https://docs.github.com/en/actions/reference/workflows-and-actions/variables

https://docs.gitlab.com/ci/variables/predefined_variables/

View Source
const MediaTypeWorkflow = "application/vnd.maru2.workflow.v1+yaml"

MediaTypeWorkflow is the mediatype for all maru2 workflows

View Source
const MediaTypeWorkflowCollection = "application/vnd.maru2.collection.v1"

MediaTypeWorkflowCollection is the mediatype for the maru2 OCI collection artifact

Variables

View Source
var (
	DebugColor = lipgloss.AdaptiveColor{
		Light: "#2e7de9",
		Dark:  "#7aa2f7",
	}
	InfoColor = lipgloss.AdaptiveColor{
		Light: "#007197",
		Dark:  "#7dcfff",
	}
	WarnColor = lipgloss.AdaptiveColor{
		Light: "#8c6c3e",
		Dark:  "#e0af68",
	}
	ErrorColor = lipgloss.AdaptiveColor{
		Light: "#f52a65",
		Dark:  "#f7768e",
	}
	FatalColor = lipgloss.AdaptiveColor{
		Light: "#9854f1",
		Dark:  "#bb9af7",
	}
	GreenColor = lipgloss.AdaptiveColor{
		Light: "#587539",
		Dark:  "#9ece6a",
	}
	GrayColor = lipgloss.AdaptiveColor{
		Light: "#c5c6bC",
		Dark:  "#3a3943",
	}
)

The terminal colors maru2 uses, derived from https://github.com/charmbracelet/vhs/blob/main/themes.json

Functions

func ExecuteBuiltin

func ExecuteBuiltin(ctx context.Context, step v1.Step, with schema.With, previousOutputs CommandOutputs, dry bool) (map[string]any, error)

ExecuteBuiltin dispatches to registered builtin tasks (builtin:echo, builtin:fetch)

Strips the "builtin:" prefix, renders templates in the With map, then delegates to the appropriate builtin's Execute method

func Fetch

func Fetch(ctx context.Context, svc *uses.FetcherService, uri *url.URL) (v1.Workflow, error)

Fetch downloads and validates a workflow from a remote or local source

Supports multiple fetcher types (GitHub, GitLab, OCI, HTTP, local files) with automatic fetcher selection based on URL scheme and configuration

func FetchAll

func FetchAll(ctx context.Context, svc *uses.FetcherService, wf v1.Workflow, src *url.URL) error

FetchAll recursively downloads all remote workflow dependencies

Scans the workflow for uses: references, resolves URLs relative to the source, and pre-fetches all dependencies into the cache for offline execution

func ListAllLocal

func ListAllLocal(ctx context.Context, src *url.URL, fsys afero.Fs) ([]string, error)

ListAllLocal recursively discovers all local file dependencies in a workflow tree

Scans file:// workflows for local uses: references, validates them, and returns the complete list of local files needed for execution

func MergeWithAndParams

func MergeWithAndParams(ctx context.Context, with schema.With, params v1.InputMap) (schema.With, error)

MergeWithAndParams merges runtime inputs with parameter definitions

Resolves defaults, environment variables, validates inputs with regex, enforces required parameters, and handles type casting

Resolution priority: provided > default-from-env > default > error if required

func ParseOutput

func ParseOutput(r io.ReadSeeker) (map[string]string, error)

ParseOutput parses the output file of a step

Matches behavior of GitHub Actions.

https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings

func Publish

func Publish(ctx context.Context, dst *remote.Repository, entrypoints []string) error

Publish packages workflows as OCI artifacts in a container registry

Fetches all remote imports, stores them in a temp directory, then pushes the complete workflow bundle to the OCI registry for distribution

func RegisterWhichShortcut

func RegisterWhichShortcut(short, long string)

RegisterWhichShortcut registers a key-value pair to be expanded during the "which" text template function

func Run

func Run(
	parent context.Context,
	svc *uses.FetcherService,
	wf v1.Workflow,
	taskName string,
	outer schema.With,
	origin *url.URL,
	ro RuntimeOptions,
) (map[string]any, error)

Run is the main event loop in maru2

It is implemented as a recursive function instead of a DAG for simplicity (debatable)

Run follows the following general pattern:

  1. Find the called task in the provided workflow

  2. Merge the provided inputs w/ the default workflow inputs

  3. Create a child context to listen for SIGINT

  4. For each step in the task:

    4a. Compile `if` conditionals and determine if the step should run

    4b. Soft reset the context if a previous step was cancelled, timed out, etc...

    4c. Wrap the current context in a timeout if `timeout` was set

    4d. If `uses` is set, resolve & fetch, then goto Step 1

    4e. If `run` is set, render the script with the provided inputs / environment

    4f. Parse the outputs from the script and store for later step retrieval

    4g. Add tracing if there was an error

  5. Return the final step's output and the first error encountered

func ShouldRun

func ShouldRun(ctx context.Context, expression string, err error, with schema.With, previousOutputs CommandOutputs, dry bool) (bool, error)

ShouldRun evaluates if expressions using the expr engine

Provides built-in functions: failure(), always(), cancelled(), input("name"), from("step-id", "key")

Returns false for failed steps when no expression is provided

func TemplateString

func TemplateString(ctx context.Context, str string, with schema.With, previousOutputs CommandOutputs, dry bool) (string, error)

TemplateString expands templates in str using Go's text/template engine

In dry run mode, missing inputs and outputs are rendered with special markers

func TemplateWithMap

func TemplateWithMap(ctx context.Context, withMap schema.With, input schema.With, previousOutputs CommandOutputs, dry bool) (schema.With, error)

TemplateWithMap recursively expands templates in all string values within a map

Handles nested maps and slices while preserving non-string values

func WorkflowSchema

func WorkflowSchema(version string) *jsonschema.Schema

WorkflowSchema generates JSON Schema for workflow validation

Returns version-specific schema for v0/v1, or a meta-schema with conditional validation that automatically selects the correct version based on schema-version field

Types

type CommandOutputs

type CommandOutputs map[string]map[string]any

CommandOutputs is a map of step IDs to their outputs.

type RuntimeOptions added in v0.8.0

type RuntimeOptions struct {
	// The WorkingDir to start the execution from, passed to the exec.Command in run blocks, leave blank for current process' PWD
	WorkingDir string
	// Environment variables passed to the exec.Command in run blocks, usually initialized w/ os.Environ()
	Env []string
	// Whether this execution is a dry run or not
	Dry bool
	// Whether this execution is already inside a collapsible section in CI, disables nested collapsible sections if true
	Collapsed bool
	// See `go doc exec.Cmd.Stdout`
	Stdout io.Writer
	// See `go doc exec.Cmd.Stderr`
	Stderr io.Writer
	// See `go doc exec.Cmd.Stdin`
	Stdin io.Reader
}

RuntimeOptions are configurations whereupon the default empty/nil value is an acceptable case and are not a requirement for a valid runtime execution

Leave this type as a concrete instance vs a pointer type as this object will be mutated along the runtime pipeline, and copy by value is the desired behavior versus copy by reference

type TaskList added in v0.8.0

type TaskList struct {
	// contains filtered or unexported fields
}

TaskList is a prettier way to display a workflow's entrypoints from a CLI's perspective

func NewDetailedTaskList added in v0.8.0

func NewDetailedTaskList(ctx context.Context, svc *uses.FetcherService, origin *url.URL, wf v1.Workflow) (*TaskList, error)

NewDetailedTaskList renders a table detailing a workflow and all aliased workflows tasks

The formatting is inspired by `just --list`

func (*TaskList) Row added in v0.8.0

func (tl *TaskList) Row(col0, col1 string)

Row appends a row to the list

func (*TaskList) String added in v0.8.0

func (tl *TaskList) String() string

String implements fmt.Stringers

type TraceError

type TraceError struct {
	Trace []string // Logical stack trace
	// contains filtered or unexported fields
}

TraceError is an error with a logical stack trace

func (*TraceError) Error

func (e *TraceError) Error() string

Error returns the original error message

func (*TraceError) Unwrap

func (e *TraceError) Unwrap() error

Unwrap returns the underlying error

Directories

Path Synopsis
Package builtins provides built-in functions for maru2
Package builtins provides built-in functions for maru2
cmd
Package cmd provides the root command for the maru2 CLI.
Package cmd provides the root command for the maru2 CLI.
internal command
Package main is the entry point for the application
Package main is the entry point for the application
maru2 command
Package main is the entry point for the application
Package main is the entry point for the application
maru2-publish command
Package main is the entry point for the application
Package main is the entry point for the application
maru2-schema command
Package main is the entry point for the application.
Package main is the entry point for the application.
Package config provides system-level configuration for maru2
Package config provides system-level configuration for maru2
v0
Package v0 provides the schema for v0 of the system config file for maru2
Package v0 provides the schema for v0 of the system config file for maru2
Package schema provides the workfow types and schema for maru2
Package schema provides the workfow types and schema for maru2
v0
Package v0 is the v0 (alpha) schema for maru2,
Package v0 is the v0 (alpha) schema for maru2,
v1
Package v1 is the v1 schema for maru2 workflows
Package v1 is the v1 schema for maru2 workflows
Package uses provides a cache+clients for storing and retrieving remote workflows.
Package uses provides a cache+clients for storing and retrieving remote workflows.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL