@tailor-platform/sdk 2.36.0 → 2.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +132 -0
- package/dist/{application-DaJbleMi.mjs → application-Bz80INH4.mjs} +1 -1
- package/dist/application-CeqD1OK-.mjs +207 -0
- package/dist/application-CeqD1OK-.mjs.map +1 -0
- package/dist/cli/commands/deploy/deploy.d.mts +7 -1
- package/dist/cli/commands/deploy/tailordb/migration-validation.d.mts +3 -0
- package/dist/cli/commands/executor/jobs.d.mts +3 -0
- package/dist/cli/commands/tailordb/migrate/bundler.d.mts +3 -0
- package/dist/cli/commands/tailordb/migrate/config.d.mts +4 -0
- package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +10 -0
- package/dist/cli/commands/tailordb/migrate/generate.d.mts +28 -2
- package/dist/cli/commands/tailordb/migrate/hints.d.mts +1 -0
- package/dist/cli/commands/tailordb/migrate/remote-state.d.mts +3 -0
- package/dist/cli/commands/tailordb/migrate/schema-checks.d.mts +3 -1
- package/dist/cli/commands/tailordb/migrate/snapshot-comparison.d.mts +4 -0
- package/dist/cli/commands/tailordb/migrate/snapshot-files.d.mts +44 -6
- package/dist/cli/commands/tailordb/migrate/snapshot-local.d.mts +2 -0
- package/dist/cli/commands/tailordb/migrate/snapshot-migrations.d.mts +2 -0
- package/dist/cli/commands/tailordb/migrate/snapshot-types.d.mts +8 -0
- package/dist/cli/commands/tailordb/migrate/types.d.mts +2 -0
- package/dist/cli/commands/workspace/create.d.mts +1 -1
- package/dist/cli/lib.d.mts +3 -3
- package/dist/cli/lib.mjs +1 -1
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/cli/main.mjs +65 -58
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/shared/args.d.mts +14 -5
- package/dist/cli/shared/client.d.mts +40 -3
- package/dist/cli/shared/error-json.d.mts +12 -26
- package/dist/cli/shared/function-execution.d.mts +2 -0
- package/dist/cli/shared/prompt.d.mts +9 -4
- package/dist/client-CHXix4LD.mjs +1 -0
- package/dist/client-DOQv-BP8.mjs +2 -0
- package/dist/client-DOQv-BP8.mjs.map +1 -0
- package/dist/completion/zsh-worker.zsh +151 -79
- package/dist/configure/config/index.d.mts +2 -0
- package/dist/configure/config/types.d.mts +2 -0
- package/dist/configure/index.mjs.map +1 -1
- package/dist/configure/services/executor/operation.d.mts +5 -4
- package/dist/configure/services/http-adapter/http-adapter.d.mts +1 -1
- package/dist/configure/services/index.d.mts +0 -1
- package/dist/configure/services/tailordb/schema.d.mts +1 -0
- package/dist/configure/services/tailordb/types.d.mts +12 -0
- package/dist/context-DSi5kfqr.mjs +23 -0
- package/dist/context-DSi5kfqr.mjs.map +1 -0
- package/dist/context-OOASEQLA.mjs +1 -0
- package/dist/{crashreport-DGU6lwiX.mjs → crashreport-CQTAlnbA.mjs} +4 -4
- package/dist/{crashreport-DGU6lwiX.mjs.map → crashreport-CQTAlnbA.mjs.map} +1 -1
- package/dist/crashreport-GRnWyDnF.mjs +1 -0
- package/dist/date-representation-Cr7W7Pn2.mjs.map +1 -1
- package/dist/{errors-BXmGBX-7.mjs → errors-9OOL3xOM.mjs} +6 -5
- package/dist/errors-9OOL3xOM.mjs.map +1 -0
- package/dist/field_behavior_pb-B196sUx6.mjs +2 -0
- package/dist/field_behavior_pb-B196sUx6.mjs.map +1 -0
- package/dist/{kysely-type-B0ri1-Xs.mjs → kysely-type-DhAZqdQg.mjs} +14 -10
- package/dist/kysely-type-DhAZqdQg.mjs.map +1 -0
- package/dist/notification_resource_pb-BZ0hCA01.mjs +1 -0
- package/dist/notification_resource_pb-Dwzah7gO.mjs +2 -0
- package/dist/notification_resource_pb-Dwzah7gO.mjs.map +1 -0
- package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
- package/dist/plugin/builtin/seed/seed-type-processor.d.mts +4 -3
- package/dist/plugin/get-generated-table.d.mts +4 -0
- package/dist/plugin/index.mjs.map +1 -1
- package/dist/plugin/types.d.mts +55 -3
- package/dist/plugin/with-context.d.mts +16 -0
- package/dist/register-ts-hook-CXYYYgCl.mjs +1094 -0
- package/dist/register-ts-hook-CXYYYgCl.mjs.map +1 -0
- package/dist/repl-editor-Bposemei.mjs +2 -0
- package/dist/repl-editor-Bposemei.mjs.map +1 -0
- package/dist/resource_pb-elY668ZB.mjs +2 -0
- package/dist/resource_pb-elY668ZB.mjs.map +1 -0
- package/dist/schema-BU1aIQ63.mjs.map +1 -1
- package/dist/{secret-file-BxZ-J_Nz.mjs → secret-file-CSXzcg4c.mjs} +2 -2
- package/dist/{secret-file-BxZ-J_Nz.mjs.map → secret-file-CSXzcg4c.mjs.map} +1 -1
- package/dist/{service-CaGmqg0r.mjs → service-B2vx6CGM.mjs} +2 -2
- package/dist/{service-CaGmqg0r.mjs.map → service-B2vx6CGM.mjs.map} +1 -1
- package/dist/service-DB-RHn25.mjs +9 -0
- package/dist/service-DB-RHn25.mjs.map +1 -0
- package/dist/service-DsAWXbVX.mjs +1 -0
- package/dist/service_pb-Bethc2NW.mjs +1 -0
- package/dist/service_pb-CfpSriCy.mjs +2 -0
- package/dist/service_pb-CfpSriCy.mjs.map +1 -0
- package/dist/tailor-proto/src/tailor/v1/function_pb.d.mts +3 -3
- package/dist/tailor-proto/src/tailor/v1/function_resource_pb.d.mts +92 -0
- package/dist/tailor-proto/src/tailor/v1/notification_pb.d.mts +176 -0
- package/dist/tailor-proto/src/tailor/v1/notification_resource_pb.d.mts +172 -0
- package/dist/tailor-proto/src/tailor/v1/service_pb.d.mts +78 -0
- package/dist/types/app-config.generated.d.mts +1 -1
- package/dist/types/auth-connection.generated.d.mts +2 -2
- package/dist/types/auth.generated.d.mts +13 -13
- package/dist/types/executor.generated.d.mts +25 -25
- package/dist/types/field.generated.d.mts +2 -2
- package/dist/types/http-adapter.generated.d.mts +4 -4
- package/dist/types/idp.generated.d.mts +272 -272
- package/dist/types/resolver.generated.d.mts +10 -10
- package/dist/types/tailordb.generated.d.mts +84 -80
- package/dist/types/workflow.generated.d.mts +2 -2
- package/dist/validation-errors-DqCeUW4L.mjs +3 -0
- package/dist/validation-errors-DqCeUW4L.mjs.map +1 -0
- package/{LICENSE → dist/vendor/graphql/LICENSE} +6 -6
- package/dist/vendor/graphql/language/KindTypeMap.d.mts +3 -0
- package/dist/vendor/graphql/language/ast.d.mts +784 -0
- package/dist/vendor/graphql/language/kinds_.d.mts +203 -0
- package/dist/vendor/graphql/language/source.d.mts +46 -0
- package/dist/vendor/graphql/language/tokenKind.d.mts +35 -0
- package/dist/vitest/date-representation.d.mts +2 -0
- package/dist/vitest/environment.d.mts +1 -0
- package/dist/vitest/environment.mjs.map +1 -1
- package/dist/vitest/index.mjs.map +1 -1
- package/dist/vitest/migration-steps.d.mts +13 -2
- package/dist/vitest/mock-kysely.d.mts +12 -2
- package/dist/vitest/mocks/aigateway.d.mts +7 -1
- package/dist/vitest/mocks/authconnection.d.mts +7 -1
- package/dist/vitest/mocks/file.d.mts +8 -2
- package/dist/vitest/mocks/iconv.d.mts +7 -1
- package/dist/vitest/mocks/idp.d.mts +7 -1
- package/dist/vitest/mocks/logger.d.mts +7 -1
- package/dist/vitest/mocks/secretmanager.d.mts +7 -1
- package/dist/vitest/mocks/tailordb-pglite.d.mts +12 -2
- package/dist/vitest/mocks/tailordb.d.mts +22 -4
- package/dist/vitest/mocks/workflow.d.mts +2 -1
- package/dist/vitest/pglite-kysely.d.mts +18 -2
- package/dist/vitest/pglite-temporal.d.mts +5 -1
- package/dist/vitest/workflow-local.d.mts +7 -0
- package/dist/workspace_resource_pb-Cow7mrJY.mjs +2 -0
- package/dist/workspace_resource_pb-Cow7mrJY.mjs.map +1 -0
- package/docs/cli/application.md +63 -29
- package/docs/cli/executor.md +2 -0
- package/docs/cli/function.md +3 -1
- package/docs/cli/notification.md +128 -0
- package/docs/cli/tailordb.md +45 -68
- package/docs/cli/workflow.md +2 -0
- package/docs/cli/workspace.md +20 -18
- package/docs/cli-reference.md +231 -50
- package/docs/configuration.md +2 -2
- package/docs/data-clone.md +1 -1
- package/docs/github-actions.md +266 -41
- package/docs/plugin/custom.md +4 -4
- package/docs/runtime.md +1 -1
- package/docs/services/auth.md +2 -0
- package/docs/services/idp.md +2 -0
- package/docs/services/tailordb/index.md +13 -4
- package/docs/services/tailordb/migration.md +109 -71
- package/docs/services/workflow.md +1 -1
- package/docs/testing.md +9 -10
- package/package.json +23 -19
- package/dist/application-BbORWCj-.mjs +0 -207
- package/dist/application-BbORWCj-.mjs.map +0 -1
- package/dist/configure/services/http-adapter/index.d.mts +0 -2
- package/dist/crashreport-WsYAWARW.mjs +0 -1
- package/dist/errors-BXmGBX-7.mjs.map +0 -1
- package/dist/kysely-type-B0ri1-Xs.mjs.map +0 -1
- package/dist/register-ts-hook-iAcG1dfz.mjs +0 -1057
- package/dist/register-ts-hook-iAcG1dfz.mjs.map +0 -1
- package/dist/repl-editor-DkrCZmmg.mjs +0 -2
- package/dist/repl-editor-DkrCZmmg.mjs.map +0 -1
- package/dist/service-DTrVVaDJ.mjs +0 -1
- package/dist/service-hIarp2Gl.mjs +0 -8
- package/dist/service-hIarp2Gl.mjs.map +0 -1
- package/dist/service_pb-6EkMfdOb.mjs +0 -2
- package/dist/service_pb-6EkMfdOb.mjs.map +0 -1
- package/dist/service_pb-CsJKokDl.mjs +0 -1
- package/dist/workspace_resource_pb-C4CkoYww.mjs +0 -2
- package/dist/workspace_resource_pb-C4CkoYww.mjs.map +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
description: "Generate, test, and apply TailorDB schema migrations with optional data migration scripts, and recover from failed migrations."
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
# TailorDB Migrations
|
|
5
|
+
# TailorDB Migrations (Beta)
|
|
6
6
|
|
|
7
7
|
> **Beta:** The `tailordb migration` command and the migration runtime are beta features. They may introduce breaking changes in future releases. The CLI emits a beta warning on every invocation.
|
|
8
8
|
|
|
@@ -58,14 +58,21 @@ If you already have a deployed workspace whose schema matches your local table d
|
|
|
58
58
|
|
|
59
59
|
1. Add the `migration` block to `tailor.config.ts`.
|
|
60
60
|
2. Run `tailor tailordb migration generate` to create `0000/schema.json` from current local tables.
|
|
61
|
-
3. Run `tailor deploy`.
|
|
61
|
+
3. Run `tailor deploy`. It first checks that the deployed tables match `0000`. Because they do, no script runs; only the migration label is set.
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
Until a deploy sets the migration label, `tailor deploy` and `tailor tailordb migration validate` compare the deployed tables with `0000`. When they differ, `tailor deploy` stops with [remote schema drift](#remote-schema-drift-detected) and `migration validate` fails, for example when a table was edited in the console, or when a local change had not been deployed before you generated `0000`. Run `tailor tailordb migration validate` before the first deploy to check, and reconcile the difference before deploying:
|
|
64
|
+
|
|
65
|
+
- To keep the deployed tables, update your local tables to match them, then recreate `0000` with `tailor tailordb migration generate --init`. `--init` deletes every migration of the namespace, so do this only while no workspace has been deployed with these migrations.
|
|
66
|
+
- To replace the deployed tables with `0000`, run `tailor tailordb migration sync 0000`. Tables and fields that `0000` does not have are deleted together with their data.
|
|
67
|
+
|
|
68
|
+
If an earlier deploy stopped after creating only some of the tables, the next deploy reports the missing tables as drift; `tailor tailordb migration sync 0000` creates them.
|
|
64
69
|
|
|
65
70
|
### Resetting
|
|
66
71
|
|
|
67
72
|
`tailor tailordb migration generate --init` deletes the existing `migrations/` directory of every namespace with migrations configured and creates `0000` from the current local tables. Add `--namespace <name>` to reset only that namespace and leave the others untouched. Use it only before the project is deployed. For a deployed migration history, use [`migration rebaseline`](#re-baselining-a-deployed-migration-history), which verifies the history and connected workspace before replacing any files.
|
|
68
73
|
|
|
74
|
+
Declining the `--init` confirmation leaves existing migrations in place and fails with `MIGRATION_GENERATE_CANCELLED`.
|
|
75
|
+
|
|
69
76
|
## Migration Workflow
|
|
70
77
|
|
|
71
78
|
A typical change cycle:
|
|
@@ -122,6 +129,10 @@ A typical change cycle:
|
|
|
122
129
|
```
|
|
123
130
|
The pre-migration phase relaxes the new field to optional, the script runs and populates values, then the post-migration phase enforces `required: true`.
|
|
124
131
|
|
|
132
|
+
When you decline a namespace's breaking-change confirmation, `migration generate` skips that namespace, continues generating migrations for the others, and exits successfully with a `Skipped: <namespaces>` summary. Declining every namespace also succeeds without writing migrations. Check the summary before deploying if you intended to generate every namespace.
|
|
133
|
+
|
|
134
|
+
JSON output includes `skippedNamespaces` alongside `migrations`. It is always an empty array in actual `--json` runs because JSON mode does not prompt. Programmatic callers of `migrateGenerate()` receive a `MigrateGenerateResult` and can inspect `skippedNamespaces` before continuing.
|
|
135
|
+
|
|
125
136
|
### Warnings and optional migration scripts
|
|
126
137
|
|
|
127
138
|
Some non-breaking changes can still cause data loss — most notably removing a field (`field_removed`), removing a table (`table_removed`), or removing a member inside a nested field (reported on the nested field's `field_modified` change). `migration generate` reports these as **warnings**:
|
|
@@ -226,9 +237,9 @@ tailor tailordb migration generate --rename "User:Person"
|
|
|
226
237
|
tailor tailordb migration generate --drop "User"
|
|
227
238
|
```
|
|
228
239
|
|
|
229
|
-
Two tables qualify as a rename pair only when copying every row preserves the data: every field must keep its name, type, array-ness, required/unique constraints, foreign key target, and decimal scale; enum fields may gain values but not lose them; indexes must match. A self-referential foreign key is compared against the new table name and must be optional. Tables with serial fields (their values cannot be written by a script) or file fields (file contents are not copied) are never candidates. Name-derived and data-independent settings — `pluralForm`, description, table settings, permissions, hooks, and validations — may differ.
|
|
240
|
+
Two tables qualify as a rename pair only when copying every row preserves the data: every field must keep its name, type, array-ness, required/unique constraints, foreign key target, and decimal scale; enum fields may gain values but not lose them; indexes must match. A self-referential foreign key, including one on a field inside a nested field, is compared against the new table name and must be optional. A table is also not a candidate when a self-referential foreign key points at another column of the table that is itself a self-referential foreign key, or when a nested field holding a self-referential foreign key is covered by a unique constraint. Tables with serial fields (their values cannot be written by a script) or file fields (file contents are not copied) are never candidates. Name-derived and data-independent settings — `pluralForm`, description, table settings, permissions, hooks, and validations — may differ.
|
|
230
241
|
|
|
231
|
-
A confirmed rename is recorded as a single `table_renamed` change and treated as **breaking** for two reasons: existing records must be copied by the migration script, and the table's GraphQL API names (derived from the table name and `pluralForm`) change, which breaks API clients. The generated `migrate.ts` copies every row from the old table into the new one in id-ordered batches, preserving ids so stored foreign key references stay valid, and the generated `db.ts` exposes both the old table (readable) and the new table (writable). Self-referential foreign keys are inserted as null and backfilled after every row exists, so a reference to a row in a later batch cannot fail the copy.
|
|
242
|
+
A confirmed rename is recorded as a single `table_renamed` change and treated as **breaking** for two reasons: existing records must be copied by the migration script, and the table's GraphQL API names (derived from the table name and `pluralForm`) change, which breaks API clients. The generated `migrate.ts` copies every row from the old table into the new one in id-ordered batches, preserving ids so stored foreign key references stay valid, and the generated `db.ts` exposes both the old table (readable) and the new table (writable). Self-referential foreign keys, including those on fields inside nested fields, are inserted as null and backfilled after every row exists, so a reference to a row in a later batch cannot fail the copy.
|
|
232
243
|
|
|
233
244
|
Two caveats apply to the copy. The old table is not write-protected: rows written to it after the script's transaction commits — and before post-migration cleanup drops it — are not carried over, so pause writers to the renamed table for the duration of the deploy. And platform-managed record metadata (creation/update timestamps and actors) cannot be written by the script, so the new table's records carry the migration run's metadata instead of the original values.
|
|
234
245
|
|
|
@@ -271,7 +282,8 @@ export default defineConfig({
|
|
|
271
282
|
files: ["./tailordb/*.ts"],
|
|
272
283
|
migration: {
|
|
273
284
|
directory: "./migrations",
|
|
274
|
-
// Optional. Defaults to the first machine user in auth.machineUsers
|
|
285
|
+
// Optional. Defaults to the first machine user in auth.machineUsers,
|
|
286
|
+
// and must name one of them.
|
|
275
287
|
machineUser: "admin-machine-user",
|
|
276
288
|
},
|
|
277
289
|
},
|
|
@@ -282,7 +294,7 @@ export default defineConfig({
|
|
|
282
294
|
| Option | Type | Description |
|
|
283
295
|
| ----------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
284
296
|
| `migration.directory` | string | Directory path for migration files. Required when migrations are enabled for the namespace. Each namespace needs its own directory. |
|
|
285
|
-
| `migration.machineUser` | string | Machine user used to run migration scripts. Optional; defaults to the first entry
|
|
297
|
+
| `migration.machineUser` | string | Machine user used to run migration scripts. Must be defined in `auth.machineUsers`. Optional; defaults to the first entry there. |
|
|
286
298
|
|
|
287
299
|
## Generated Files
|
|
288
300
|
|
|
@@ -438,8 +450,9 @@ Because steps commit separately, a failure does not undo the steps that already
|
|
|
438
450
|
- Fix the failing step and run `tailor deploy` again. The deploy resumes the migration: completed steps do not run again, and the failed step and the steps after it run with the updated script. A completed step is treated like an applied migration — editing it afterwards does not run it again.
|
|
439
451
|
- If the steps changed since the earlier run, or that run is no longer available, every step runs again from the beginning. See [Editing steps of a migration in progress](#editing-steps-of-a-migration-in-progress).
|
|
440
452
|
- If every step completed but the post-migration schema changes fail (for example, a field the migration makes required still has empty values), the migration also stays in progress with its pre-migration schema, and the next deploy retries those schema changes without running the steps again.
|
|
453
|
+
- If the deploy stops during or after the post-migration schema changes but before it records the migration as applied, for example because the process was killed or recording the checkpoint failed, the migration also stays in progress, with each table in either its pre-migration or its post-migration schema. The next deploy resumes it: it applies the pre-migration schema again, so a field the migration makes required is optional until the post-migration schema changes are applied again. Completed steps do not run again unless you add, remove, or rename a step, change the order the steps run in, or the earlier run is no longer available (see [Editing steps of a migration in progress](#editing-steps-of-a-migration-in-progress)).
|
|
441
454
|
- To run a completed step again (because it had a bug, or to fix rows the post-migration schema changes reject), change the steps: rename that step and update the `dependsOn` lists that name it, or add a step that fixes the rows. Every step then runs again from the beginning, so this relies on every step being safe to run again; to keep the other completed steps from running again, skip them as described below.
|
|
442
|
-
-
|
|
455
|
+
- Finish a multi-step migration left in progress with `tailor deploy`, or settle it with `migration resolve`. Until then, the commands listed in [Settling a migration that stays in progress](#settling-a-migration-that-stays-in-progress) refuse to run.
|
|
443
456
|
|
|
444
457
|
#### Editing steps of a migration in progress
|
|
445
458
|
|
|
@@ -461,6 +474,7 @@ tailor deploy --migration-skip-steps main-db/backfillUser,main-db/backfillInvoic
|
|
|
461
474
|
- A skipped step is reported as completed and is not run. Only steps that succeeded in the migration's earlier run can be skipped, so a step you renamed cannot be.
|
|
462
475
|
- The option applies to the migration an earlier deploy left in progress. Deploy fails before changing anything when an entry names a step that did not succeed, a step the migration does not define, a namespace without a migration in progress, or a namespace that no deployed config defines. It also fails when the earlier run's step results cannot be read, because then it cannot confirm which steps succeeded; deploy again to retry.
|
|
463
476
|
- It takes effect for the deploy you pass it to. If that run fails, the next `tailor deploy` resumes it as usual, and the skipped steps stay completed without passing the option again.
|
|
477
|
+
- To check the entries before deploying, pass the same option to `tailor tailordb migration validate`. It reports the entries that deploy would reject for the namespaces of the config it validates.
|
|
464
478
|
|
|
465
479
|
Write every step so that running it again is safe: besides the cases above, a step can run a second time when a deploy is interrupted right after it commits. Use `where` clauses that skip rows a step already migrated, as in the example. Rows written while a migration is in progress are not seen by steps that already completed. [Maintenance mode](#maintenance-mode) blocks GraphQL writes but not the writes your resolvers, executors, or workflows make through Kysely, and without it GraphQL clients can write too, so stop such writers until the migration finishes or write steps that tolerate them.
|
|
466
480
|
|
|
@@ -481,10 +495,12 @@ export const steps = {
|
|
|
481
495
|
- Steps that already completed stay committed. Their changes to existing fields remain in the database, and nothing is recorded as in progress, so the next deploy runs every step again from the beginning. Every step must be safe to run again, or a rolled-back run applies those changes twice. Do not rely on data a step wrote to a field or table that the rollback removed.
|
|
482
496
|
- If `tailor deploy` cannot tell whether a step ran, or the migration's workflow execution may still be running (for example the connection to it was lost), it does not roll anything back even with `"rollback"`: the migration stays in progress as described for a `main` script below. A migration an earlier deploy left in progress is rolled back only when its earlier run is confirmed to have ended, so a failure before that run is inspected, such as a schema error while applying the Pre-phase, keeps it in progress.
|
|
483
497
|
- If the in-progress record cannot be cleared, `tailor deploy` does not roll the schema back. It logs a warning and keeps the migration in progress with its tables in maintenance mode, because a record that outlives a rollback would make the next deploy resume against a schema its completed steps no longer match. Deploy again to resume it as described above, or roll it back without deploying with `tailor tailordb migration resolve --rollback`.
|
|
484
|
-
- If the schema or GraphQL permission of some tables cannot be rolled back, `tailor deploy` still fails with the step's original error. It also warns `Migration <namespace>/<N> was not rolled back completely` and lists the tables that need manual repair, and separately the tables whose GraphQL permission could not be set back.
|
|
498
|
+
- If the schema or GraphQL permission of some tables cannot be rolled back, `tailor deploy` still fails with the step's original error. It also warns `Migration <namespace>/<N> was not rolled back completely` and lists the tables that need manual repair, and separately the tables whose GraphQL permission could not be set back. A table that still has the migration's pre-migration schema does not stop the next deploy, which runs every step again (see [Failure Recovery](#failure-recovery)). Otherwise the next deploy stops with remote schema drift, so check the tables in the workspace and repair them by hand.
|
|
485
499
|
|
|
486
500
|
### Settling a migration that stays in progress
|
|
487
501
|
|
|
502
|
+
While a migration is in progress, `migration sync` and `migration rebaseline` refuse to run, and `migration test` refuses to use that workspace as its source. `tailor tailordb migration status` reports the migration as in progress and lists the commands that get it out of that state: `tailor deploy` to resume a multi-step migration, and `tailor tailordb migration resolve` to roll it back or complete it. For a migration whose script run a deploy could not confirm, it lists only `resolve`, because a deploy does not resume that migration.
|
|
503
|
+
|
|
488
504
|
A deploy resumes a multi-step migration left in progress. When you do not want it to — you abandoned the migration, or you repaired the data by hand — settle the migration with `tailor tailordb migration resolve`. Pass exactly one of two options:
|
|
489
505
|
|
|
490
506
|
- `--rollback` sends the schema of the migration before the failed one, clears the in-progress record, and leaves the checkpoint where it was. The next `tailor deploy` runs the failed migration again from its first step, so every step must be safe to run again. Data changes made by steps that already completed are not undone, and tables that exist only in the failed migration's schema are deleted with their data.
|
|
@@ -492,6 +508,8 @@ A deploy resumes a multi-step migration left in progress. When you do not want i
|
|
|
492
508
|
|
|
493
509
|
Tables that the failed migration removes are deleted with their data under `--complete`. The command refuses to run while an execution of the failed migration is still running; wait for it to finish first. Both options take the namespace's tables out of [maintenance mode](#maintenance-mode) and remove the temporary resources of the failed run. The command shows what it will change and asks for confirmation (`--yes` skips it). As with `migration sync`, the local migration history must reproduce the current table definitions, so settle the migration before you change the tables. If sending the schema stops partway, run the same command again.
|
|
494
510
|
|
|
511
|
+
`--rollback` also accepts a migration that no deploy recorded as in progress, but whose pre-migration schema or maintenance mode a deploy left in place: the deploy stopped before it recorded the migration, or failed to roll it back or to end maintenance mode (see [Maintenance mode](#maintenance-mode)). The command runs only when every table of the namespace has the schema of the checkpoint or the migration's pre-migration schema. With maintenance mode on, a table that has the pre-migration schema must also be in maintenance mode. If only maintenance mode is left, the command runs only when a local migration follows the checkpoint. A deploy that is still running looks the same until it records the migration, so make sure none is running. `--complete` refuses such a migration.
|
|
512
|
+
|
|
495
513
|
The same command settles a migration whose script run a deploy could not confirm (see [Failure Recovery](#failure-recovery)). A deploy does not resume such a migration; it stops until this command settles it. The command reads how that run ended and shows it before asking for confirmation. Pass `--complete` when the run succeeded, and `--rollback` when it failed, was canceled, or did not start; `--rollback` deletes the tables and fields the migration introduced together with the data the script wrote to them, and the next deploy runs the script again. The command warns when the option you passed does not fit how the run ended, or when it cannot read the run.
|
|
496
514
|
|
|
497
515
|
## Supported Schema Changes
|
|
@@ -644,7 +662,7 @@ Some changes are still rejected and need a temporary field you add yourself —
|
|
|
644
662
|
|
|
645
663
|
The command performs the following sequence:
|
|
646
664
|
|
|
647
|
-
1. Reads each migration-enabled namespace's `sdk-migration` checkpoint from the source workspace and reconstructs that exact snapshot from local migration history. A deployed namespace that has no checkpoint is treated as migration 0
|
|
665
|
+
1. Reads each migration-enabled namespace's `sdk-migration` checkpoint from the source workspace and reconstructs that exact snapshot from local migration history. A deployed namespace that has no checkpoint is treated as migration 0 when its schema matches the `0000` snapshot, as `tailor deploy` does; otherwise the command fails and lists the differences. A namespace that was never deployed, or has no tables yet, also fails.
|
|
648
666
|
2. Creates a temporary workspace in the same region as the source, unless `--target-workspace-id` names an existing throwaway workspace. By default it is created in the source's organization and folder. `--organization-id` places it at the root of that organization, and `--folder-id` places it in that folder (together with `--organization-id` when the folder is in another organization or the source is not in an organization). With `--target-workspace-id`, the given values must match where that workspace already is.
|
|
649
667
|
3. Deploys the checkpoint snapshots and writes their checkpoint labels.
|
|
650
668
|
4. Loads fixture data or clones source records.
|
|
@@ -668,7 +686,7 @@ tailor tailordb migration test --data seed
|
|
|
668
686
|
|
|
669
687
|
Rows are loaded only for tables present in the deployed pre-migration snapshots (and current schemas without migrations), in foreign-key dependency order. Fields introduced by pending migrations, including timestamp and nested fields, are removed before insertion so current fixtures can be loaded into the baseline schema. Missing table files are treated as empty. IdP `_User` fixtures are not loaded by this command.
|
|
670
688
|
|
|
671
|
-
Use `--machine-user` to
|
|
689
|
+
Use `--machine-user` to run the seed, the pending migration scripts, and the assertion as that machine user, in place of `db.<namespace>.migration.machineUser` and the first entry in `auth.machineUsers` (and, for the seed, the seed plugin's `machineUserName`). For the pending migration scripts, it must be defined in `auth.machineUsers`.
|
|
672
690
|
|
|
673
691
|
### Clone mode
|
|
674
692
|
|
|
@@ -724,7 +742,7 @@ When you run `tailor deploy`, the SDK detects pending migrations (anything past
|
|
|
724
742
|
For each pending migration:
|
|
725
743
|
|
|
726
744
|
1. **Pre-migration**: Schema changes that would be breaking are applied in a relaxed form first. A verified in-place field type change keeps its complete previous field contract until Post-migration, including field and table-level hooks or validators changed by the same migration. Newly-required fields are added as optional; fields whose `optional → required` transition is breaking are temporarily kept optional. Fields that are being removed in this migration are temporarily kept on the table so that `migrate.ts` can still read them (for example, to `innerJoin` through a foreign key that is about to be dropped); members removed from a nested field are kept the same way, and the new member of a confirmed nested rename is added as optional and non-unique. Added or newly required nested members are optional and removed nested enum values remain allowed until Post-migration. For a renamed field, the old field is kept and the new field is added with its constraints relaxed, so the script can read the old field and write the new one. For a renamed table, the new table is created with its full constraints while the old table stays on the namespace until post-migration cleanup, so the script can copy rows between them. A foreign key added to an existing top-level field is withheld until Post-migration, so `migrate.ts` can update rows whose values point at no record; Post-migration adds it without checking the stored values. Breaking table-level index changes are relaxed the same way: a newly-added unique index is withheld, and an index gaining a unique constraint (or a unique index changing its field set) keeps its previous definition, so `migrate.ts` can resolve duplicates first. Non-breaking changes that are part of the same migration are also applied here.
|
|
727
|
-
2. **Script execution**: If `migrate.ts` exists on disk for this migration, it is bundled and runs on the platform as the configured machine user inside a transaction — or, for a script that exports [`steps`](#splitting-a-migration-into-steps), one transaction per step. The script is hard-required for breaking changes (`diff.requiresMigrationScript`) — deploy fails if the file is missing, unless a `--no-script` acknowledgment was recorded (see [Breaking changes without a script](#breaking-changes-without-a-script)). It is also executed when present for warning-tier diffs — see [Warnings and optional migration scripts](#warnings-and-optional-migration-scripts).
|
|
745
|
+
2. **Script execution**: If `migrate.ts` exists on disk for this migration, it is bundled and runs on the platform as the [configured machine user](#machine-user-and-permissions) inside a transaction — or, for a script that exports [`steps`](#splitting-a-migration-into-steps), one transaction per step. The script is hard-required for breaking changes (`diff.requiresMigrationScript`) — deploy fails if the file is missing, unless a `--no-script` acknowledgment was recorded (see [Breaking changes without a script](#breaking-changes-without-a-script)). It is also executed when present for warning-tier diffs — see [Warnings and optional migration scripts](#warnings-and-optional-migration-scripts).
|
|
728
746
|
3. **Post-migration schema**: Required constraints and the target field definitions are applied. Do not assume that removing a field clears its underlying stored JSON value.
|
|
729
747
|
4. **Checkpoint and cleanup**: The `sdk-migration` label is bumped to this migration's number, then removed GQL permissions and tables — including the old table left behind by a rename — are deleted. Advancing the checkpoint first prevents a failed checkpoint write from requiring the SDK to recreate irreversibly deleted records.
|
|
730
748
|
|
|
@@ -757,11 +775,13 @@ Maintenance mode restricts GraphQL writes and record events only. Resolvers, exe
|
|
|
757
775
|
|
|
758
776
|
**When a deploy stops early:**
|
|
759
777
|
|
|
760
|
-
- If a migration fails, the tables leave maintenance mode before the error is reported: they return to the settings of the last checkpoint that completed. A migration that did not reach its checkpoint returns existing tables to their previous settings and
|
|
778
|
+
- If a migration fails, the tables leave maintenance mode before the error is reported: they return to the settings of the last checkpoint that completed. A migration that did not reach its checkpoint returns existing tables to their previous settings and drops the tables it created (see [Failure Recovery](#failure-recovery)). A created table that the rollback cannot drop stays in maintenance mode, and the deploy names it; deploying again runs the migration again. The settings are not restored if the checkpoint number or migration history changed concurrently, or if checkpoint ownership cannot be verified. A table left behind by a failed post-checkpoint deletion stays in maintenance mode until the next deploy deletes it (see [Failure Recovery](#failure-recovery)).
|
|
779
|
+
- With `--no-schema-check`, if a local table definition that the migrations do not include cannot be applied after they complete, the existing tables leave maintenance mode with the definitions of the last migration before the error is reported (see [Schema verification](#schema-verification)).
|
|
761
780
|
- A [multi-step migration](#splitting-a-migration-into-steps) left in progress keeps its tables in maintenance mode until a deploy completes it.
|
|
762
781
|
- A migration whose script run a deploy could not confirm keeps its tables in maintenance mode until you settle it with `tailor tailordb migration resolve` (see [Failure Recovery](#failure-recovery)).
|
|
763
782
|
- With `"deploy"`, if a later part of the deploy fails, the tables leave maintenance mode before the error is reported. When the deploy ends maintenance mode, it leaves the tables of a namespace unchanged if that namespace's checkpoint number or migration history changed concurrently, or if checkpoint ownership cannot be verified, and reports it.
|
|
764
|
-
- If the deploy process is interrupted after a namespace's migrations completed but before maintenance mode ended, that namespace's tables stay in maintenance mode until a later `tailor deploy` releases them when it applies its TailorDB changes, before it replaces resolvers and executors. A namespace whose migrations had not all completed is not released this way: the next deploy resumes a multi-step migration left in progress, stops at a migration whose script was running until you settle it
|
|
783
|
+
- If the deploy process is interrupted after a namespace's migrations completed but before maintenance mode ended, that namespace's tables stay in maintenance mode until a later `tailor deploy` releases them when it applies its TailorDB changes, before it replaces resolvers and executors. A namespace whose migrations had not all completed is not released this way: the next deploy resumes a multi-step migration left in progress, and stops at a migration whose script was running until you settle it. Every migration checkpoint of a namespace records the maintenance mode, so with pending migrations `0001` and `0002`, a deploy interrupted right after the checkpoint of `0001` leaves the tables in maintenance mode; the next deploy keeps them there while it applies `0002` and releases them afterwards (with `"deploy"`, after the whole deploy).
|
|
784
|
+
- A deploy interrupted before it recorded a migration as in progress (for example, right after the migration's pre-migration schema changes reached some or all of its tables) leaves no record of that migration. The next deploy accepts tables that have the schema of the checkpoint or the migration's pre-migration schema, and runs the migration again from the start. To return the tables to the checkpoint without deploying, run `tailor tailordb migration resolve --rollback` (see [Settling a migration that stays in progress](#settling-a-migration-that-stays-in-progress)).
|
|
765
785
|
|
|
766
786
|
#### Keeping maintenance mode short
|
|
767
787
|
|
|
@@ -774,17 +794,17 @@ Maintenance mode lasts for the whole migration job, including the time the platf
|
|
|
774
794
|
|
|
775
795
|
When [maintenance mode](#maintenance-mode) is on, `tailor deploy` reports how long the migrating namespaces' tables were restricted, split into phases. With `"deploy"`, the window also includes the remaining deployment changes and ends when their restrictions are lifted. No maintenance report is emitted with `maintenanceMode: false`.
|
|
776
796
|
|
|
777
|
-
| Phase | Covers
|
|
778
|
-
| ------------------ |
|
|
779
|
-
| `restrict` | Putting the tables into maintenance mode
|
|
780
|
-
| `pre-migration` | Pre-migration schema changes
|
|
781
|
-
| `job setup` | Bundling `migrate.ts` and registering it as a job
|
|
782
|
-
| `waiting to start` | Time when the platform has accepted the job but none of its code runs yet
|
|
783
|
-
| `running` | Time when the script runs
|
|
784
|
-
| `job cleanup` | Collecting the script's logs and removing its job, unless its steps run as separate jobs
|
|
785
|
-
| `post-migration` | Post-migration schema changes, the checkpoint update, and
|
|
786
|
-
| `remaining deploy` | With `"deploy"`, applying the remaining deployment changes while tables stay restricted
|
|
787
|
-
| `restore` | Taking the tables out of maintenance mode
|
|
797
|
+
| Phase | Covers |
|
|
798
|
+
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
799
|
+
| `restrict` | Putting the tables into maintenance mode |
|
|
800
|
+
| `pre-migration` | Pre-migration schema changes |
|
|
801
|
+
| `job setup` | Bundling `migrate.ts` and registering it as a job |
|
|
802
|
+
| `waiting to start` | Time when the platform has accepted the job but none of its code runs yet |
|
|
803
|
+
| `running` | Time when the script runs |
|
|
804
|
+
| `job cleanup` | Collecting the script's logs and removing its job, unless its steps run as separate jobs |
|
|
805
|
+
| `post-migration` | Post-migration schema changes, the checkpoint update, cleanup, and [local definitions](#schema-verification) no migration includes |
|
|
806
|
+
| `remaining deploy` | With `"deploy"`, applying the remaining deployment changes while tables stay restricted |
|
|
807
|
+
| `restore` | Taking the tables out of maintenance mode |
|
|
788
808
|
|
|
789
809
|
Phases that repeat across several migrations are added up. The report is printed only after the migrations succeed and the tables leave maintenance mode; when a migration fails, deploy reports the error instead (see [Failure Recovery](#failure-recovery)). When deploy resumes a migration that an earlier deploy left in progress, the tables were already in maintenance mode before it started, and the report covers only this deploy. A job can be reported as started on the platform well before its code runs, so deploy tells waiting from running by a line every job of a migration logs before your script: `[tailor-sdk] migration script started`. You may see that line in function execution logs; deploy leaves it out of the logs it prints. A script that exports [`steps`](#splitting-a-migration-into-steps) waits for each step's job to start, and that time counts as `waiting to start` too. Time when deploy cannot tell whether the script is running — because the run or a running job's logs could not be read, or because an older SDK version started the run and it never logs the line — is reported as `waiting to start or running` instead.
|
|
790
810
|
|
|
@@ -795,7 +815,7 @@ Deploy checks the run every few seconds, so a boundary between `waiting to start
|
|
|
795
815
|
Before running migrations, `apply` performs two checks:
|
|
796
816
|
|
|
797
817
|
1. **Local schema check** — your current table definitions must match the latest snapshot in `migrations/`. If they don't, you forgot to run `migration generate`.
|
|
798
|
-
2. **Remote schema check** — the deployed schema is reconstructed from migration history; the actual remote schema must match. Drift here means someone applied a different set of migrations or edited the schema out-of-band.
|
|
818
|
+
2. **Remote schema check** — the deployed schema is reconstructed from migration history; the actual remote schema must match. Drift here means someone applied a different set of migrations or edited the schema out-of-band. A namespace that has tables but no migration label yet must match `0000` (see [Adding migrations to an existing project](#adding-migrations-to-an-existing-project)). When no migration is recorded as in progress, a table may also have the pre-migration schema of the next migration, which an interrupted or failed deploy left; the deploy then runs that migration again from the start (see [Maintenance mode](#maintenance-mode)). With maintenance mode on, such a table must be in maintenance mode.
|
|
799
819
|
|
|
800
820
|
On drift you'll see something like:
|
|
801
821
|
|
|
@@ -808,7 +828,7 @@ Namespace: tailordb
|
|
|
808
828
|
- Field 'email': required: remote=false, expected=true
|
|
809
829
|
```
|
|
810
830
|
|
|
811
|
-
The error also points you at `migration status`, `migration generate`,
|
|
831
|
+
The error also points you at `migration status`, `migration generate`, and `migration sync` — see [Remote schema drift detected](#remote-schema-drift-detected) for which one applies.
|
|
812
832
|
|
|
813
833
|
To run the same checks without deploying — plus migration file integrity (numbering, parseable contents, a `migrate.ts` or a recorded `--no-script` acknowledgment for every migration that requires a script, and no `TODO()` call left in a `migrate.ts`):
|
|
814
834
|
|
|
@@ -826,6 +846,10 @@ To bypass both checks during deploy (not recommended outside of recovery scenari
|
|
|
826
846
|
tailor deploy --no-schema-check
|
|
827
847
|
```
|
|
828
848
|
|
|
849
|
+
With pending migrations, each migration still applies its own table definitions in its [phases](#per-migration-phases), so `migrate.ts` sees the schema it was written for. Local table definitions that differ from the last pending migration are applied after every pending migration has completed, and the deploy lists those tables. With [maintenance mode](#maintenance-mode) on, existing tables stay in it until their local definitions are applied. If one of them cannot be applied, for example a unique constraint on a field whose records hold duplicate values, the deploy fails with `MIGRATION_LOCAL_DEFINITIONS_FAILED`: the migrations stay applied, tables already created for their local definitions remain, and the existing tables keep the definitions of the last migration and leave maintenance mode.
|
|
850
|
+
|
|
851
|
+
`--no-schema-check` does not bypass the check that the remote migration checkpoint is in the local migration history. See ["Remote migration checkpoint is not in the local migration history" error](#remote-migration-checkpoint-is-not-in-the-local-migration-history-error).
|
|
852
|
+
|
|
829
853
|
### Example output
|
|
830
854
|
|
|
831
855
|
```
|
|
@@ -858,32 +882,15 @@ tailor tailordb migration rebaseline --namespace tailordb
|
|
|
858
882
|
|
|
859
883
|
The command validates the migration files, verifies that replaying the latest migration exactly reproduces the local table definitions, and checks that the connected workspace is at that latest migration with no schema drift. After confirmation, it replaces the local history with the reconstructed baseline, records a new migration history ID in both `0000/schema.json` and remote metadata, and resets the connected workspace's `sdk-migration` label to `0000`. Use `--yes` only after arranging the same operational preconditions in non-interactive automation.
|
|
860
884
|
|
|
885
|
+
When the connected workspace records another migration history ID, or one that cannot be read, the command refuses to run. Run it from a checkout of the migration history deployed to that workspace. To replace the workspace's history with the local one on purpose, first run `tailor tailordb migration sync <N> --force` with the latest local migration as `<N>`, which rewrites the workspace's tables to that migration, removing the fields it does not have and deleting the tables it does not have together with their data (see [`migration sync` Semantics](#migration-sync-semantics)). When the workspace's tables differ from the latest migration, the command also refuses to run; see [Remote schema drift detected](#remote-schema-drift-detected), where `tailor tailordb migration sync <N>` rewrites the tables to the latest migration.
|
|
886
|
+
|
|
861
887
|
Commit the resulting `migrations/` change before generating any new migrations. For another environment still carrying the exact checkpoint and history ID that the new baseline replaced, the next `tailor deploy` checks whether its remote schema exactly matches the new `0000`. If it does, deploy offers to reset the checkpoint to `0000` and move the environment to the new history ID before applying any later local migrations. A markerless history is eligible only for the first rebaseline, at the exact migration recorded as replaced. Any other checkpoint or history ID is rejected without changing remote metadata, even if its schema happens to match the baseline.
|
|
862
888
|
|
|
863
889
|
Partial squashing is not supported: re-baselining always replaces the full history for one namespace.
|
|
864
890
|
|
|
865
|
-
## `migration set` Semantics
|
|
866
|
-
|
|
867
|
-
`tailor tailordb migration set <N>` updates the `sdk-migration` label on the deployed namespace's metadata. **It does not modify any data or schema.** It only changes which migrations the next `apply` will consider pending. The command also aligns the remote migration history ID with the local baseline, removing a stale ID when the local history predates re-baselining.
|
|
868
|
-
|
|
869
|
-
The migration number is validated before anything is sent to the remote: it must be a 4-digit value (e.g. `0001`) or a bare integer (e.g. `1`) within 0–9999, and must exist in the working tree's migration history, which is itself validated (a gapped history is rejected). `0` is always accepted as the baseline (even when no migrations directory exists yet), provided the history passes validation.
|
|
870
|
-
|
|
871
|
-
| Movement | Effect on next `apply` | Effect on data |
|
|
872
|
-
| -------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------- |
|
|
873
|
-
| Forward (e.g., `0001` → `0003`) | Migrations `0002` and `0003` are skipped — they will not run. | None. |
|
|
874
|
-
| Backward (e.g., `0003` → `0001`) | Migrations `0002` and `0003` become pending and will re-execute on apply. | None directly — but the re-executed scripts may rewrite data. |
|
|
875
|
-
|
|
876
|
-
Use cases:
|
|
877
|
-
|
|
878
|
-
- **Recovery from drift** — you investigated, manually fixed the remote, and want the SDK's bookkeeping to reflect reality.
|
|
879
|
-
- **Re-running a faulty migration** in a development workspace — set backward, fix `migrate.ts`, apply.
|
|
880
|
-
- **Skipping a migration** that you know was already applied out-of-band.
|
|
881
|
-
|
|
882
|
-
`migration set` does not perform a true rollback. To undo a schema/data change in production, write a new forward migration that reverses it (see [Rollback Strategy](#rollback-strategy)).
|
|
883
|
-
|
|
884
891
|
## `migration sync` Semantics
|
|
885
892
|
|
|
886
|
-
`tailor tailordb migration sync <N>` reconstructs the schema snapshot at migration `N` from the working tree's migration history and **overwrites the remote schema to match it**, then sets the `sdk-migration` label to `N` and
|
|
893
|
+
`tailor tailordb migration sync <N>` reconstructs the schema snapshot at migration `N` from the working tree's migration history and **overwrites the remote schema to match it**, then sets the `sdk-migration` label to `N` and records the migration history ID of the local baseline. It never runs `migrate.ts` scripts itself — it only changes what the next `apply` considers pending:
|
|
887
894
|
|
|
888
895
|
| Movement | Effect on next `apply` | Effect on data |
|
|
889
896
|
| -------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
@@ -892,9 +899,16 @@ Use cases:
|
|
|
892
899
|
|
|
893
900
|
Before anything is sent to the remote, `sync` verifies that replaying the full migration history reproduces the current local table definitions. If it does not — because migration files were edited and no longer match, or because a schema change has not been recorded with `migration generate` yet — the command fails without touching the remote. This means a rewritten migration history is validated before it can overwrite the deployed schema.
|
|
894
901
|
|
|
902
|
+
`sync` refuses to run when the namespace records another migration history ID, or one that cannot be read, before it reads or changes any table, unless the namespace has neither a checkpoint nor a history ID yet. Run it from a checkout of the migration history deployed to the workspace. To write the local history over another one on purpose, for example after `migration rebaseline` re-baselined the local history but could not update the workspace, pass `--force`: it overwrites the tables with those of the local history and replaces the history ID with the local one, or removes it when the local history has none, and still asks for confirmation unless you pass `--yes`.
|
|
903
|
+
|
|
895
904
|
Because syncing backward causes already-applied scripts to re-execute on the next deploy, **write `migrate.ts` scripts to be idempotent** (see [Performance and Large Tables](#performance-and-large-tables) for resumable `where` clauses).
|
|
896
905
|
|
|
897
|
-
The main use
|
|
906
|
+
The main use cases are:
|
|
907
|
+
|
|
908
|
+
- Recovering from drift after a `deploy --no-schema-check`, which deploys the local table definitions without checking them against the migration snapshots: run `migration sync <N>` to restore the remote to a known snapshot, then `tailor deploy` to apply the remaining migrations from the working tree.
|
|
909
|
+
- Moving a checkpoint that `tailor deploy` reports as not in the local migration history back to that history on purpose (see ["Remote migration checkpoint is not in the local migration history" error](#remote-migration-checkpoint-is-not-in-the-local-migration-history-error)).
|
|
910
|
+
- Recording that the tables already match migration `N`, for example after you fixed them by hand or applied a migration outside the migration history. `sync <N>` sends the same table definitions again, so only the checkpoint changes, although its confirmation still lists the tables as updated.
|
|
911
|
+
- Re-running a faulty migration in a development workspace (see [Rollback Strategy](#rollback-strategy)).
|
|
898
912
|
|
|
899
913
|
## Team Workflow and CI/CD
|
|
900
914
|
|
|
@@ -920,7 +934,7 @@ When your branch and main each generated the same number, merging or rebasing st
|
|
|
920
934
|
### CI / CD
|
|
921
935
|
|
|
922
936
|
- For non-interactive environments, pass `--yes` to `migration generate` and `--yes` to `apply`. `apply` runs migrations automatically when the `migrations/` directory is configured.
|
|
923
|
-
- Run `tailor tailordb migration validate` in CI to catch uncommitted migrations, broken migration files, unreviewed generated normalization logic,
|
|
937
|
+
- Run `tailor tailordb migration validate` in CI to catch, before deploying, uncommitted migrations, broken migration files, unreviewed generated normalization logic, remote schema drift, and pending migration scripts that `tailor deploy` could not run. It exits with a non-zero code when validation fails and supports `--json`. Add `--strict` to also require an explicit acknowledgment (a `migrate.ts` or a recorded `--no-script` reason) for every pending migration that can drop data, so destructive changes cannot merge unnoticed.
|
|
924
938
|
- `tailor tailordb migration status` validates the layout and file-format compatibility of the full local history, compares its history ID with the deployed namespace, and shows applied and pending migrations for a human-readable comparison. Its exit code is non-zero on invalid or incompatible files, migration history mismatches, a remote checkpoint ahead of the latest local migration, and remote read errors, so check the output.
|
|
925
939
|
- Avoid running migrations in parallel against the same workspace — there is no locking. Serialize deploys per environment.
|
|
926
940
|
|
|
@@ -936,13 +950,13 @@ A script that exports `steps` follows different rules once one of its steps has
|
|
|
936
950
|
- **The pre-migration schema changes are rolled back** to the prior checkpoint: tables that already existed are restored to their previous shape and GraphQL permissions, and tables the migration newly introduced are dropped. The workspace is left at its prior checkpoint and prior schema — not half-applied.
|
|
937
951
|
- The whole `apply` aborts and the checkpoint label is not bumped. Subsequent migrations in the same run do not execute.
|
|
938
952
|
|
|
939
|
-
The rollback is best-effort per table; if reverting a table fails, a warning is logged and the original migration error is still reported.
|
|
953
|
+
The rollback is best-effort per table; if reverting a table fails, a warning is logged and the original migration error is still reported. A table left with the migration's pre-migration schema does not stop the next deploy, which runs the failed migration again from the start. This happens, for example, when the script wrote records without a value for a field the migration makes required: the platform refuses to make the field required again while such records exist. `tailor tailordb migration resolve --rollback` returns such tables to the checkpoint without deploying, once those records have a value. A table left in any other shape makes the next deploy stop with remote schema drift on that table. Run `tailor tailordb migration validate` to see which tables differ, return the namespace to its checkpoint with `tailor tailordb migration sync <N>`, where `<N>` is the checkpoint `tailor tailordb migration status` reports, and deploy again. `sync` deletes the tables and fields that are not in that migration's snapshot, together with any rows the failed migration wrote to them; the next deploy runs the failed migration again.
|
|
940
954
|
|
|
941
|
-
If `tailor deploy` cannot tell whether a `main` script ran, for example because the connection dropped while it started or waited for the script, it does not roll anything back: the pre-migration schema changes stay, the namespace's tables stay in [maintenance mode](#maintenance-mode) if it is on, the migration stays recorded as in progress, and the deploy reports that it could not confirm the outcome. The same holds when the deploy process stops while the script runs. Until you settle the migration, `tailor deploy` stops before changing anything, including the other namespaces and resources of the application, and reports how the run stands, even with `--no-schema-check
|
|
955
|
+
If `tailor deploy` cannot tell whether a `main` script ran, for example because the connection dropped while it started or waited for the script, it does not roll anything back: the pre-migration schema changes stay, the namespace's tables stay in [maintenance mode](#maintenance-mode) if it is on, the migration stays recorded as in progress, and the deploy reports that it could not confirm the outcome. The same holds when the deploy process stops while the script runs. Until you settle the migration, `tailor deploy` stops before changing anything, including the other namespaces and resources of the application, and reports how the run stands, even with `--no-schema-check`. Run `tailor workflow executions --workflow-name <name>` with the workflow name the error reports until the execution has finished. If it succeeded, run `tailor tailordb migration resolve --complete`, which applies the migration's schema without running the script again; otherwise run `tailor tailordb migration resolve --rollback`, and the next deploy runs the script again. See [Settling a migration that stays in progress](#settling-a-migration-that-stays-in-progress), which also lists the commands that refuse to run until then.
|
|
942
956
|
|
|
943
957
|
If the post-migration schema changes fail after a `main` script succeeded and the deploy cannot clear the in-progress record, it keeps the pre-migration schema instead of rolling it back, so the data the script wrote stays. Settle the migration as above: `--complete` once the data meets the migration's schema, or `--rollback`.
|
|
944
958
|
|
|
945
|
-
|
|
959
|
+
When a steps migration's post-migration schema changes fail and the deploy cannot return its tables to the pre-migration schema, it logs a warning. The next deploy accepts each table in either the pre-migration or the post-migration schema: it applies the pre-migration schema again, skips the completed steps unless the steps changed, and retries the post-migration schema changes.
|
|
946
960
|
|
|
947
961
|
After a failure:
|
|
948
962
|
|
|
@@ -952,9 +966,13 @@ After a failure:
|
|
|
952
966
|
|
|
953
967
|
If a migration **succeeds in script** but its reversible **post-migration schema update** fails (rare; usually a constraint violation the script should have prevented), the SDK makes the same best-effort restoration to the prior-checkpoint schema. The script's committed data changes remain, so write migration scripts to tolerate re-execution.
|
|
954
968
|
|
|
955
|
-
|
|
969
|
+
Before a migration's script starts, `tailor deploy` checks that the namespace's checkpoint and migration history are still the ones it read before applying, or the checkpoint it committed itself. If another deploy or a `tailor tailordb migration` command changed them in the meantime, or the deploy cannot read them, the script does not start and the migration is not recorded as in progress: the deploy handles the pre-migration schema as for a script that failed before it ran, and fails with `MIGRATION_CHECKPOINT_CONFLICT` (`MIGRATION_CHECKPOINT_UNVERIFIED` when it cannot read them). Run `tailor tailordb migration status` to see the checkpoint. Wait for the other deploy to finish, or, when no other deploy is running, return the namespace to the checkpoint the error names with `tailor tailordb migration sync <N>`, which also lifts the maintenance mode the deploy left in place, and deploy again. If the error says the checkpoint changed in a different migration history, or with a migration history label that cannot be read, `sync` also needs `--force`, which replaces the workspace's migration history ID with the local one. Pass it only when the local migration history should replace the deployed one; otherwise deploy from a checkout of the migration history deployed to the workspace.
|
|
970
|
+
|
|
971
|
+
The checkpoint is advanced only after the reversible post-migration schema updates succeed. If the checkpoint write reports an error, the SDK reads it back: a matching value is treated as committed. Any other observed value leaves the post-migration schema unchanged rather than risk rolling back a concurrent deployment; a value beyond the current migration confirms a concurrent deploy, while an older or missing value means the checkpoint must be repaired before retrying, unless the value is the previous checkpoint and the multi-step migration is still recorded as in progress, which the next deploy resumes. If read-back also fails, the SDK likewise leaves the post-migration schema unchanged; verify the remote checkpoint before retrying.
|
|
956
972
|
|
|
957
|
-
Removed tables are deleted only after the checkpoint is committed. If that cleanup fails, the checkpoint remains at the new migration and the
|
|
973
|
+
Removed tables are deleted only after the checkpoint is committed. The deploy records with the checkpoint that these deletions are still to run, and clears the record once they finish. If that cleanup fails or the deploy is interrupted, the checkpoint remains at the new migration, and the next deploy finishes the cleanup: it lists the tables that migration removed among the tables to delete, and deletes them and their GQL permissions with their data before it runs any pending migration. `tailor tailordb migration validate` reports them as tables the next deploy deletes. To delete them without deploying, run `tailor tailordb migration sync <N>` with the committed migration as `<N>` (when the cleanup fails, the deploy error's suggestion names the command). A same-named remote table is still reported as remote schema drift when no unfinished cleanup is recorded, for example a table created again after the cleanup completed or one left by an SDK version that did not record the cleanup, and when a later migration adds the table back; delete it with `migration sync <N>` or by hand, and then deploy again. A deploy with `--no-schema-check` does not finish the cleanup of a namespace that has pending migrations, and once those migrations commit, the leftover tables are reported as drift as well.
|
|
974
|
+
|
|
975
|
+
With `--no-schema-check`, local table definitions that the pending migrations do not include are applied after every migration has committed (see [Schema verification](#schema-verification)). If one of them cannot be applied, the deploy fails with `MIGRATION_LOCAL_DEFINITIONS_FAILED`: the migrations stay committed, the existing tables go back to the definitions of the last migration, and tables already created for their local definitions remain. Fix the cause and deploy again. When existing records refuse the definition, for example a unique constraint on a field whose records hold duplicate values, run `tailor tailordb migration generate` to add the change in a migration whose script updates those records, then deploy again; the error's suggestion names the command.
|
|
958
976
|
|
|
959
977
|
## Rollback Strategy
|
|
960
978
|
|
|
@@ -964,7 +982,7 @@ There is no automatic down-migration. To roll back a schema/data change in produ
|
|
|
964
982
|
2. `migration generate --name "rollback 0005 email"` produces `0006` with a removal diff.
|
|
965
983
|
3. Apply.
|
|
966
984
|
|
|
967
|
-
In **development workspaces**, a quicker option is to fix `0005/migrate.ts` in place, run `migration
|
|
985
|
+
In **development workspaces**, a quicker option is to fix `0005/migrate.ts` in place, run `migration sync <previous>` to return the tables to the previous migration and re-mark `0005` pending, and apply. `sync` removes the fields `0005` added and deletes the tables it added together with their data, and stops before moving the checkpoint when existing rows have no value for a field the previous migration requires. Do not do this on production — it confuses migration history across environments.
|
|
968
986
|
|
|
969
987
|
## Machine User and Permissions
|
|
970
988
|
|
|
@@ -973,7 +991,9 @@ Migration scripts execute server-side under a machine user identity. The CLI sel
|
|
|
973
991
|
1. `db.<namespace>.migration.machineUser` if set in `tailor.config.ts`.
|
|
974
992
|
2. The first entry in `auth.machineUsers` otherwise.
|
|
975
993
|
|
|
976
|
-
The CLI logs the selected user before running scripts (`Using machine user: ...`).
|
|
994
|
+
The selected user must be defined in `auth.machineUsers`. The CLI logs the selected user before running scripts (`Using machine user: ...`).
|
|
995
|
+
|
|
996
|
+
When a pending migration has a `migrate.ts`, `tailor deploy` checks while planning that auth is configured, that a machine user is selected and defined in `auth.machineUsers`, and that each script can be bundled. A failure stops the deploy before anything is applied, and `tailor deploy --dry-run` reports it too. `tailor tailordb migration validate` runs the same checks for the migrations that are pending in the workspace it validates.
|
|
977
997
|
|
|
978
998
|
**Permissions required**
|
|
979
999
|
|
|
@@ -982,17 +1002,23 @@ The machine user needs read/write access to every table the migration script tou
|
|
|
982
1002
|
If you see `No machine user available for migration execution`, either:
|
|
983
1003
|
|
|
984
1004
|
- Add `machineUsers: { ... }` to your auth config and `tailor deploy` it, or
|
|
985
|
-
- Set `migration.machineUser` to
|
|
1005
|
+
- Set `migration.machineUser` to a machine user defined in `auth.machineUsers`.
|
|
986
1006
|
|
|
987
1007
|
## Multi-Namespace Coordination
|
|
988
1008
|
|
|
989
1009
|
If your project defines multiple TailorDB namespaces (`db: { ns1: { ... }, ns2: { ... } }`), each has its own `migrations/` directory and its own migration label. During `apply`:
|
|
990
1010
|
|
|
991
|
-
-
|
|
992
|
-
-
|
|
993
|
-
-
|
|
1011
|
+
- Pending migrations run one namespace at a time, in alphabetical order of the namespace names, and within a namespace in migration number order. With pending migrations in `inventory` and `billing`, every one of `billing` runs before any of `inventory`.
|
|
1012
|
+
- With [maintenance mode](#maintenance-mode) on, every namespace of the config that has pending migrations enters maintenance mode before the first migration runs, and they leave it together: after the last migration with `"migration"`, and after the whole deploy with `"deploy"`. [Maintenance mode](#maintenance-mode) describes the exceptions when a deploy stops early.
|
|
1013
|
+
- The order follows the namespace names, not dependencies between namespaces. Do not write a migration in `ns1` that depends on data produced by a migration in `ns2` running first.
|
|
994
1014
|
- Each namespace can specify its own `migration.machineUser`.
|
|
995
1015
|
|
|
1016
|
+
### Several configs in one deploy
|
|
1017
|
+
|
|
1018
|
+
When one deploy applies several configs (see [Multiple Config Deploys](../../cli/application.md#deploy)), it applies each kind of resource for every config, in the order the configs are listed, before it moves on to the next kind. For `tailor deploy --config supplier.ts,buyer.ts`, the secrets, static websites, AI gateways, IdPs, auth services and machine users, and function registries of both configs are applied first. Then the TailorDB changes and migrations of `supplier` are applied, then those of `buyer`, then the resolvers of `supplier` and `buyer`, and so on through the applications, executors, and workflows. Each config's `maintenanceMode` covers only its own namespaces, so with `"deploy"` in `supplier`, its tables stay in maintenance mode while the migrations of `buyer` run.
|
|
1019
|
+
|
|
1020
|
+
If a migration of `buyer` fails, the deploy stops there and leaves `supplier` in this state: its migrations have completed and its checkpoint has advanced, its tables are out of maintenance mode even with `"deploy"`, and nothing after TailorDB has been applied, including its resolvers, executors, and workflows. Its tables therefore have the new schema while the resolvers and executors of the previous deploy still use them. When you fix the migration of `buyer` and deploy both configs again, `supplier` has no pending migrations, and the deploy applies the rest of its changes. If the migration of `buyer` must first be settled with `tailor tailordb migration resolve` (see [Failure Recovery](#failure-recovery)), every deploy of the two configs stops before changing anything until then.
|
|
1021
|
+
|
|
996
1022
|
## Performance and Large Tables
|
|
997
1023
|
|
|
998
1024
|
The migration script runs in a single transaction. For tables with many rows:
|
|
@@ -1048,7 +1074,7 @@ describe("0005 add required email", () => {
|
|
|
1048
1074
|
});
|
|
1049
1075
|
```
|
|
1050
1076
|
|
|
1051
|
-
Stage the rows each query returns with `mock.enqueueResult(...)` or `mock.setQueryResolver(...)` when the script reads before writing; call `main(trx, { env: { ... } })` when the script takes a `MigrationContext`. See [Kysely-layer mock](../../testing.md#kysely-layer-mock-createkyselymock) for the full mock API.
|
|
1077
|
+
Stage the rows each query returns with `mock.enqueueResult(...)` or `mock.setQueryResolver(...)` when the script reads before writing; call `main(trx, { env: { ... } })` when the script takes a `MigrationContext`. See [Kysely-layer mock](../../testing.md#kysely-layer-mock-createkyselymock-beta) for the full mock API.
|
|
1052
1078
|
|
|
1053
1079
|
These tests need no platform connection and no `tailor-runtime` environment — they run in a plain Vitest setup. Vitest's default `include` pattern already picks up `migrations/**/migrate.test.ts`; if your config narrows `include`, add the migrations directory. The test file is ignored by `tailor deploy` and never ships to the platform.
|
|
1054
1080
|
|
|
@@ -1174,19 +1200,19 @@ For genuinely different schemas across environments, prefer separate workspaces
|
|
|
1174
1200
|
|
|
1175
1201
|
### Remote schema drift detected
|
|
1176
1202
|
|
|
1177
|
-
**Cause:** Remote schema doesn't match what the migration history says it should be.
|
|
1203
|
+
**Cause:** Remote schema doesn't match what the migration history says it should be. When `tailor deploy` shows `Remote migration: <unset>`, or `migration validate` shows `no checkpoint yet`, the namespace has no migration label yet and its tables differ from `0000`; see [Adding migrations to an existing project](#adding-migrations-to-an-existing-project) instead of the steps below.
|
|
1178
1204
|
|
|
1179
1205
|
**Resolution:**
|
|
1180
1206
|
|
|
1181
1207
|
1. `tailor tailordb migration status` to see local vs remote.
|
|
1182
1208
|
2. Compare with teammates — has someone applied different migrations?
|
|
1183
|
-
3. If remote was changed manually, decide whether to update local
|
|
1209
|
+
3. If remote was changed manually, decide whether to update the local tables to match and run `migration generate`, or to return the remote to a snapshot as in the next step.
|
|
1184
1210
|
4. To force the remote schema back to a known snapshot, use `migration sync <N>` (see [`migration sync` Semantics](#migration-sync-semantics)). If the drift follows a failed deploy that warned it could not restore a table's schema, see [Failure Recovery](#failure-recovery) instead.
|
|
1185
|
-
5. As a last resort in non-production environments, `--no-schema-check` skips both checks. Do not use this as a routine workaround.
|
|
1211
|
+
5. As a last resort in non-production environments, `--no-schema-check` skips both checks. Do not use this as a routine workaround. It does not skip the checkpoint check described next.
|
|
1186
1212
|
|
|
1187
1213
|
### "Remote migration checkpoint is not in the local migration history" error
|
|
1188
1214
|
|
|
1189
|
-
**Cause:** The deployed namespace's checkpoint refers to a migration number, or a migration history ID, that the local `migrations/` directory no longer has a record of. This is a different code path from schema drift above: it fires before any schema comparison, because the CLI cannot even locate the remote's recorded position in the local history.
|
|
1215
|
+
**Cause:** The deployed namespace's checkpoint refers to a migration number, or a migration history ID, that the local `migrations/` directory no longer has a record of. This is a different code path from schema drift above: it fires before any schema comparison, because the CLI cannot even locate the remote's recorded position in the local history. `tailor deploy` stops with this error even with `--no-schema-check`, so a deploy from an outdated checkout never moves the checkpoint back or overwrites the tables with an older schema.
|
|
1190
1216
|
|
|
1191
1217
|
One specific cause is a `migration rebaseline` run on a different environment while this one had not yet caught up to the latest pre-rebaseline migration. `migration rebaseline` requires every other environment to already be at the latest migration (see [Re-baselining a deployed migration history](#re-baselining-a-deployed-migration-history)), but the CLI only verifies the one workspace it runs against. If this environment was behind, the error message names the migration this environment must reach (the migration every environment was required to be at before the rebaseline) alongside the migration it is actually at.
|
|
1192
1218
|
|
|
@@ -1196,7 +1222,13 @@ One specific cause is a `migration rebaseline` run on a different environment wh
|
|
|
1196
1222
|
2. Deploy this environment against that restored history until its checkpoint reaches the migration named in the error, running any `migrate.ts` scripts it still needs.
|
|
1197
1223
|
3. Switch back to the current (rebaselined) migration files and deploy again. The remote schema now matches the new baseline, so this deploy offers the automatic checkpoint reset to `0000` under the new history ID.
|
|
1198
1224
|
|
|
1199
|
-
**Resolution (any other cause):** Run `tailor tailordb migration status` to compare local and remote,
|
|
1225
|
+
**Resolution (any other cause):** Run `tailor tailordb migration status` to compare local and remote, and pull the latest migration files if your checkout is stale. To move the checkpoint back to the local migration history on purpose, run `tailor tailordb migration sync <N>` with the latest local migration as `<N>` (the error suggests the command). It also rewrites the tables to snapshot `<N>`, removing the fields that snapshot does not have and deleting the tables it does not have together with their data. When the namespace records another migration history ID, or one that cannot be read, the command also needs `--force`, which replaces that history ID with the local one, or removes it when the local history has none (see [`migration sync` Semantics](#migration-sync-semantics)). Pass `--force` only when the local migration history should replace the deployed one; otherwise work from a checkout of the migration history deployed to the workspace. Then deploy again.
|
|
1226
|
+
|
|
1227
|
+
### `MIGRATION_FILES_INVALID` error
|
|
1228
|
+
|
|
1229
|
+
**Cause:** The `migrations/` directory of a namespace does not form a valid history: a migration number is missing, `0000` has no `schema.json` or has a `diff.json`, or a later migration has a `schema.json` or no `diff.json`. A deleted directory or a merge that kept only part of a migration is a common cause. `tailor deploy` and the `tailor tailordb migration` commands that read the history report this error, listing every problem.
|
|
1230
|
+
|
|
1231
|
+
**Resolution:** Follow the suggestion for each problem in the error. Otherwise restore the migration files from version control. If no workspace has been deployed with these migrations, you can instead recreate `0000` from the local tables with `tailor tailordb migration generate --init --namespace <name>`, which deletes every migration of the namespace.
|
|
1200
1232
|
|
|
1201
1233
|
### "Invalid schema snapshot" or "Invalid migration diff" error
|
|
1202
1234
|
|
|
@@ -1205,7 +1237,7 @@ One specific cause is a `migration rebaseline` run on a different environment wh
|
|
|
1205
1237
|
**Resolution:**
|
|
1206
1238
|
|
|
1207
1239
|
1. Read the error message — it includes the file path and the offending field.
|
|
1208
|
-
2. Restore the file from version control (`git checkout -- <path>`),
|
|
1240
|
+
2. Restore the file from version control (`git checkout -- <path>`); `migration generate` reads every migration file and stops with the same error until then. If the broken file belongs to the latest migration and no environment has deployed it, you can instead recreate that migration: copy out the files you edited in its directory (such as `migrate.ts` and its tests), delete the directory, run `migration generate` with the options that created it (such as `--data-only`, `--rename`, or `--drop`), copy your edits back, and record any `--no-script` reason again with `migration script`. A migration pair created with `--expand-contract` cannot be recreated this way, so restore its files from version control.
|
|
1209
1241
|
3. Do not hand-edit `schema.json` or `diff.json`; they are managed by the CLI.
|
|
1210
1242
|
|
|
1211
1243
|
### "Unsupported migration file format version" error
|
|
@@ -1216,15 +1248,21 @@ One specific cause is a `migration rebaseline` run on a different environment wh
|
|
|
1216
1248
|
|
|
1217
1249
|
### "No machine user available for migration execution"
|
|
1218
1250
|
|
|
1219
|
-
**Cause:** Neither `migration.machineUser` is set nor are there any machine users in `auth.machineUsers`.
|
|
1251
|
+
**Cause:** Neither `migration.machineUser` is set nor are there any machine users in `auth.machineUsers`. `tailor deploy` reports this while planning, including with `--dry-run`, before anything is applied, and `tailor tailordb migration validate` reports it too.
|
|
1252
|
+
|
|
1253
|
+
**Resolution:** Add a machine user to `auth.machineUsers`, then run `tailor deploy` again. The deploy creates the machine user before it runs the migration scripts.
|
|
1254
|
+
|
|
1255
|
+
### "Machine user for migration execution is not defined in auth"
|
|
1256
|
+
|
|
1257
|
+
**Cause:** `migration.machineUser`, or `--machine-user` of `tailor tailordb migration test`, names a machine user that is not in `auth.machineUsers`. `tailor deploy` reports this while planning, including with `--dry-run`, before anything is applied, and `tailor tailordb migration validate` reports it too.
|
|
1220
1258
|
|
|
1221
|
-
**Resolution:**
|
|
1259
|
+
**Resolution:** Either add the machine user to `auth.machineUsers`, or name one that is defined there.
|
|
1222
1260
|
|
|
1223
1261
|
### "Machine user not found"
|
|
1224
1262
|
|
|
1225
|
-
**Cause:** `migration
|
|
1263
|
+
**Cause:** In `tailor tailordb migration test`, the machine user that runs the seed or the assertion (from `--machine-user`, the seed plugin's `machineUserName`, or `migration.machineUser`) is not in `auth.machineUsers`, so the temporary workspace does not have it.
|
|
1226
1264
|
|
|
1227
|
-
**Resolution:** Either add the machine user to `auth.machineUsers
|
|
1265
|
+
**Resolution:** Either add the machine user to `auth.machineUsers`, or name one that is defined there.
|
|
1228
1266
|
|
|
1229
1267
|
### Migration script execution fails
|
|
1230
1268
|
|
|
@@ -352,7 +352,7 @@ export default createResolver({
|
|
|
352
352
|
});
|
|
353
353
|
```
|
|
354
354
|
|
|
355
|
-
Wait points can be imported and used in any file (workflow jobs, resolvers, executors). For local testing, see [Jobs that wait on approval](../testing.md#jobs-that-wait-on-approval) in the testing guide.
|
|
355
|
+
Wait points can be imported and used in any file (workflow jobs, resolvers, executors). For local testing, see [Jobs that wait on approval](../testing.md#jobs-that-wait-on-approval-beta) in the testing guide.
|
|
356
356
|
|
|
357
357
|
### Keys With Runtime Values
|
|
358
358
|
|