fix: apply pending migrations without version arithmetic #1

Merged
end merged 1 commits from fix/pending-migration-identifiers into main 2026-10-06 00:14:36 -07:00
Owner

Migration versions are identifiers, but pending application used target - current as the number of migrations to execute. A database at version 29 with one pending migration at 20260929235340 applied that migration and then failed startup with ErrNoNextVersion.

Apply pending migrations one at a time until exhaustion, or until the requested positive cap has succeeded. Zero remains a no-op, negative values apply all pending migrations, and a cap larger than the remaining work succeeds with the actual applied count. Exported signatures, disabled-auto-migration rejection, and already-current behavior remain unchanged.

Keep status, per-migration, empty-migration, error, and completion logs, using real version IDs rather than initialVersion + appliedCount. Preserve provider/result errors and goose PartialError, including a migration that itself fails with a wrapped ErrNoNextVersion.

Validation:

  • Disposable in-memory SQLite regressions cover contiguous, gapped, timestamped and mixed identifiers, blank/partial/current histories, caps, disabled auto-migration, counts, exhaustion, cancellation, failures, and structured logs.
  • The small-gap and timestamp regressions fail against the original operation bodies with ErrNoNextVersion and pass with the fix.
  • go test -modfile=/tmp/migrate-pending-validation/go.mod -count=1 ./..., the corresponding -race run, and go vet pass; gofmt and git diff --check pass.
  • Changed operation functions have 100% statement coverage; no application databases or shared services were used.

The repository already replaces app/appcli/dbx with sibling directories absent in this fresh worktree, and its older published pins do not independently support the current module APIs. Validation used a temporary modfile resolving those replacements to compatible cached app 58e5e33e18da, appcli 60ecc69620df, and dbx 14686a83cb6c; existing production pins and relative replacements are unchanged. SQLite is a test-only import.

Migration versions are identifiers, but pending application used `target - current` as the number of migrations to execute. A database at version 29 with one pending migration at 20260929235340 applied that migration and then failed startup with `ErrNoNextVersion`. Apply pending migrations one at a time until exhaustion, or until the requested positive cap has succeeded. Zero remains a no-op, negative values apply all pending migrations, and a cap larger than the remaining work succeeds with the actual applied count. Exported signatures, disabled-auto-migration rejection, and already-current behavior remain unchanged. Keep status, per-migration, empty-migration, error, and completion logs, using real version IDs rather than `initialVersion + appliedCount`. Preserve provider/result errors and goose `PartialError`, including a migration that itself fails with a wrapped `ErrNoNextVersion`. Validation: - Disposable in-memory SQLite regressions cover contiguous, gapped, timestamped and mixed identifiers, blank/partial/current histories, caps, disabled auto-migration, counts, exhaustion, cancellation, failures, and structured logs. - The small-gap and timestamp regressions fail against the original operation bodies with `ErrNoNextVersion` and pass with the fix. - `go test -modfile=/tmp/migrate-pending-validation/go.mod -count=1 ./...`, the corresponding `-race` run, and `go vet` pass; `gofmt` and `git diff --check` pass. - Changed operation functions have 100% statement coverage; no application databases or shared services were used. The repository already replaces app/appcli/dbx with sibling directories absent in this fresh worktree, and its older published pins do not independently support the current module APIs. Validation used a temporary modfile resolving those replacements to compatible cached app 58e5e33e18da, appcli 60ecc69620df, and dbx 14686a83cb6c; existing production pins and relative replacements are unchanged. SQLite is a test-only import.
end added 1 commit 2026-10-06 00:09:26 -07:00
end merged commit 4ca353dd7e into main 2026-10-06 00:14:36 -07:00
end deleted branch fix/pending-migration-identifiers 2026-10-06 00:14:36 -07:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: go-toolkit/migrate#1