Migrating

The loader speaks version 2.1.0 manifests only. Running against an older tree fails with a pointer here. curo repo migrate converts both 1.x and 2.0 trees in place; coming from 1.x there is also a small invocation table below.

Migrating Manifests

From the repository root:

curo repo migrate --dry-run   # report what would change, write nothing
curo repo migrate             # convert in place

migrate walks the component tree, reads each 1.x curo.toml and writes a fresh, lean manifest in its place. Manifests that are already current are left alone. After writing, the whole tree is re-loaded through the strict loader, so a successful migrate means a working tree.

Anything the migrator cannot mechanically decide is flagged for human review, never guessed. The report lists each flag with its location:

  • runtime-slot: a 1.x named runtime slot (the caller-selected -r names). Runtimes are now declared per command; decide whether one is wanted and write it by hand.
  • runtime-lifecycle: a 1.x [runtime.default] start/stop lifecycle that cannot be turned into a runtime automatically.
  • args-usage: a command using {{ args }}. Still supported, but arguments now arrive from -- instead of -D, so confirm the shape.
  • dropped-key: a 1.x key with no current equivalent.
  • profile-split: a [cicd] table (1.x or 2.0). Its release keys (build, publish, deploy) move to [rel] and everything else to [ci]; the flag records where each key landed so you can confirm the call.
  • script-rename: a .curo/actions/cicd.* script. The cicd profile no longer exists, so the file is inert until renamed; the flag suggests the target (rel.* for release actions, ci.* otherwise). migrate rewrites manifests only, never renames files.

Comments and formatting are not preserved: the output is a lean manifest, not an edit.

Invocation Changes

1.x2.0
curo build curo clicuro build curo/cli
curo test unitcuro test.unit
curo -e cicd buildcuro -p rel build
curo -e cicd test unitcuro -p ci test.unit
curo lint -D "--fix" web uicuro lint web/ui -- --fix
curo test --texclude functionalcuro test --without functional
curo build -n "test unit"curo build -n test.unit
curo infocuro repo info
curo find web uicuro repo find web/ui
curo versioncuro repo version
curo init > curo.tomlcuro repo init > curo.toml

The pattern: every addressable thing is one shell token. Sublevels use dots, component paths use slashes, and the quoting disappears.

Notes:

  • -e/--env still parses as a hidden, deprecated alias of -p/--profile and prints a warning. Scripts keep working while you update them.
  • Trailing -- arguments are first-class: they reach every resolved command, so the 1.x rule that -D only worked with a single component is gone.
  • "Environment" is now "profile", and profiles are hard-coded to dev, ci and rel, falling back down the chain. The 1.x cicd fused two of them; pick per invocation: reporting and installing is ci, releasing is rel.
  • Zero resolved actions is now a loud error instead of a silent success.
  • An interrupted or failing step now stops the run and reports honestly; 1.x could print a success footer after a failure.

From 2.0

2.1 split the cicd profile into ci (machine manner: reporting, hookless install) and rel (the release artifact and its delivery), with the linear fallback rel -> ci -> dev. curo repo migrate converts a 2.0 tree the same way it converts 1.x: [cicd] splits by the axis rule with a profile-split flag, and the version line bumps. Two things stay yours:

  • Rename .curo/actions/cicd.* scripts to rel.* or ci.* (discovery keys on the profile name). migrate flags each one it finds with the suggested target; until renamed, the script is silently inert.
  • In pipelines, replace -p cicd with -p ci on test-shaped jobs and -p rel on delivery jobs.

New in 2.x

Worth adopting once migrated:

  • --plan renders the execution plan without running it; with --porcelain it is a machine-readable dry-run.
  • --porcelain emits machine-readable JSON, on actions and on the repo commands. Each planned action names the source_profile its command was found under, so fallback is visible.
  • Declared runtimes: bind a command to a start/exec/stop lifecycle with in = "<name>", and override at the command line with -r, including -r bare.
  • {{ global }}: declare that a component's action runs the root's command, instead of remembering -g.
  • Shell completion: curo repo completion fish|bash|zsh.