Migrations
go.putnami.dev/migration defines the backend-neutral registry and runner
contracts. go.putnami.dev/database owns SQL execution, while
go.putnami.dev/migratecli drives the production application graph as a
one-shot command without starting listeners or workloads.
Both public modules are stable and owned by the Go SDD surface. Their migration-execution and CLI specifications live next to their package sources.
Ownership model
- A feature plugin contributes
migration.Sourcevalues. - A backend plugin registers one
migration.Runnerfor each kind it owns. - The registry processes kinds in lexical order and fails on orphan sources before runtime execution, except during explicit source-only metadata work.
- Each runner owns its atomic boundary. The SQL runner applies the SQL and records that one migration in the same database transaction.
There is no cross-kind or cross-datasource distributed transaction. A failure stops the current registry operation and returns the records already completed.
Service migration command
Reuse the exact builder used by the server:
package main
import (
"os"
"go.putnami.dev/migratecli"
"example.com/service/internal/wire"
)
func main() {
os.Exit(migratecli.Run(wire.BuildApp))
}The CLI calls Application.Prepare, discovers the resulting registry, and
never calls Start. Because preparation can open eager dependencies, every
return path explicitly closes the prepared dependency container.
| Command | Result |
|---|---|
up [to name] |
Apply pending work, optionally through one target |
down [to name] |
Roll back the latest reversible work, optionally to one target |
status |
Show known and recorded migrations |
verify |
Report pending or drifted migrations |
inspect |
Dump the prepared registry without executing migration-state operations |
up, down, and status accept table, JSON, or JSONL output. Exit code 1
means invalid command input, 2 an operational failure, and 3 detected
drift. inspect is not guaranteed offline because application preparation may
open eager dependencies.
Drift and rollback
Versioned migration drift fails closed. Repeatable migration drift is applied again. Rollback is available only when the migration declares a reverse operation; applied SQL rollback remains possible because the runner persists the reverse SQL with the migration record.
Accepted decision records next to the registry and CLI package sources document these boundaries.
Related guides
- Persistence — SQL definitions and pools
- Plugins & Lifecycle — application preparation and shutdown
- Testing — project gates