@tailor-platform/sdk 2.23.0 → 2.25.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 +89 -0
- package/dist/application-ChqHuhZW.mjs +1 -0
- package/dist/application-DS0XKBtK.mjs +200 -0
- package/dist/application-DS0XKBtK.mjs.map +1 -0
- package/dist/cli/cache/bundle-cache.d.mts +1 -0
- package/dist/cli/commands/deploy/deployment-target.d.mts +1 -0
- package/dist/cli/commands/machineuser/list.d.mts +1 -0
- package/dist/cli/commands/show.d.mts +13 -1
- package/dist/cli/lib.d.mts +2 -2
- package/dist/cli/lib.mjs +1 -1
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/cli/main.mjs +43 -43
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/services/application.d.mts +1 -0
- package/dist/cli/services/workflow/bundler.d.mts +2 -1
- package/dist/cli/shared/forbidden-runtime-globals.d.mts +1 -0
- package/dist/cli/shared/start-context.d.mts +1 -0
- package/dist/cli/ts-hook.mjs +3 -3
- package/dist/completion/zsh-worker.zsh +3 -3
- package/dist/configure/config/types.d.mts +42 -2
- package/dist/configure/index.d.mts +2 -2
- package/dist/configure/index.mjs +1 -1
- package/dist/configure/index.mjs.map +1 -1
- package/dist/plugin/index.mjs +1 -1
- package/dist/plugin/index.mjs.map +1 -1
- package/dist/plugin/types.d.mts +97 -0
- package/dist/register-ts-hook-DPAW0Z4M.mjs +924 -0
- package/dist/register-ts-hook-DPAW0Z4M.mjs.map +1 -0
- package/dist/vitest/mocks/file.d.mts +1 -1
- package/docs/cli/application.md +23 -0
- package/docs/cli/secret.md +24 -16
- package/docs/cli-reference.md +25 -13
- package/docs/configuration.md +28 -3
- package/docs/github-actions.md +236 -56
- package/docs/migration/v3.md +46 -0
- package/docs/multi-environment.md +3 -1
- package/docs/plugin/custom.md +76 -1
- package/docs/plugin/frontend.md +124 -0
- package/docs/plugin/index.md +24 -2
- package/docs/services/auth.md +2 -0
- package/docs/services/secret.md +5 -4
- package/docs/services/staticwebsite.md +2 -0
- package/docs/services/tailordb-migration.md +1 -1
- package/docs/services/workflow.md +3 -0
- package/package.json +8 -8
- package/dist/application-BtZ8hmx9.mjs +0 -1
- package/dist/application-m2G91kKI.mjs +0 -199
- package/dist/application-m2G91kKI.mjs.map +0 -1
- package/dist/register-ts-hook-ztnEFW6n.mjs +0 -922
- package/dist/register-ts-hook-ztnEFW6n.mjs.map +0 -1
package/docs/github-actions.md
CHANGED
|
@@ -33,9 +33,11 @@ tailor setup ci tag --name my-app-prod \
|
|
|
33
33
|
--branch main --environment production
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
After running the command, follow the **Next steps** printed to the terminal
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
After running the command, follow the **Next steps** printed to the terminal:
|
|
37
|
+
run `tailor setup ci env` to get the commands that set the secrets and
|
|
38
|
+
variables each GitHub Environment needs (see
|
|
39
|
+
[Setting secrets and variables](#setting-secrets-and-variables)), then commit
|
|
40
|
+
the generated files.
|
|
39
41
|
|
|
40
42
|
The generated workflow deploys to whichever workspace its
|
|
41
43
|
`TAILOR_PLATFORM_WORKSPACE_ID` Environment variable points at — it never
|
|
@@ -170,10 +172,13 @@ Because the variable is scoped to a GitHub Environment, both the `plan` and
|
|
|
170
172
|
```
|
|
171
173
|
|
|
172
174
|
2. Set the id as the Environment variable (the environment name is your
|
|
173
|
-
`--environment` value, or the workspace name when omitted)
|
|
175
|
+
`--environment` value, or the workspace name when omitted).
|
|
176
|
+
`tailor setup ci env` prints this command together with the other secrets
|
|
177
|
+
and variables each environment needs (see
|
|
178
|
+
[Setting secrets and variables](#setting-secrets-and-variables)):
|
|
174
179
|
|
|
175
180
|
```bash
|
|
176
|
-
gh variable set TAILOR_PLATFORM_WORKSPACE_ID --env
|
|
181
|
+
gh variable set TAILOR_PLATFORM_WORKSPACE_ID --env=my-app-stg
|
|
177
182
|
```
|
|
178
183
|
|
|
179
184
|
If `TAILOR_PLATFORM_WORKSPACE_ID` is unset, `deploy` fails because the target
|
|
@@ -194,6 +199,14 @@ Running a workflow setup subcommand creates or updates:
|
|
|
194
199
|
The workflow file. The `name:` field is set to `Tailor (<workspace-name>)` so
|
|
195
200
|
you can distinguish multiple workspaces in the Actions UI.
|
|
196
201
|
|
|
202
|
+
Every checkout in the workflow sets `persist-credentials: false`, so the GitHub
|
|
203
|
+
token is not left in `.git/config` while the job installs and runs your
|
|
204
|
+
project's code. The tag guard step passes the job token only to its
|
|
205
|
+
`git fetch`, and the plan step passes it to its `git fetch` and to the step that
|
|
206
|
+
posts the plan comment on the pull request; neither writes it to `.git/config`.
|
|
207
|
+
If installing your dependencies fetches git repositories
|
|
208
|
+
that require authentication, configure the credentials in your own step.
|
|
209
|
+
|
|
197
210
|
See [Customizing the generated workflow](#customizing-the-generated-workflow)
|
|
198
211
|
for what you can edit.
|
|
199
212
|
|
|
@@ -204,39 +217,83 @@ top-level keys it writes (`name:`, `on:`, and `permissions:` in a workflow; the
|
|
|
204
217
|
metadata, inputs, and outputs of a composite action). Do not edit or rename
|
|
205
218
|
them. Everything else is yours, and re-running `setup` keeps it:
|
|
206
219
|
|
|
207
|
-
- **Your own jobs and steps.** Add them anywhere,
|
|
208
|
-
|
|
220
|
+
- **Your own jobs and steps.** Add them anywhere, with an `id` (if any) that
|
|
221
|
+
does not start with `tailor-`: the prefix is reserved for the SDK, even in a
|
|
222
|
+
job of your own. A step you add inside a managed job stays right after the managed step it
|
|
209
223
|
followed. For example, add private registry authentication or a system
|
|
210
224
|
dependency _before_ the managed `tailor-setup` step, and post-install extras
|
|
211
225
|
(such as `playwright install`) _after_ it. A job of your own can depend on a
|
|
212
226
|
managed job with `needs: tailor-deploy`.
|
|
213
227
|
- **Your own top-level keys**, such as a workflow-level `env:` or `defaults:`.
|
|
214
228
|
- **Runtime settings of managed jobs:** `runs-on`, `timeout-minutes`,
|
|
215
|
-
`container`, and `env`.
|
|
229
|
+
`container`, and `env`. On a managed job generated without an
|
|
230
|
+
`environment:` (such as `tailor-tag-guard` or `tailor-erd-preview`), you can
|
|
231
|
+
also add one, for example so a step you added there can read that GitHub
|
|
232
|
+
Environment's secrets. The `environment:` of `tailor-plan`, `tailor-deploy`,
|
|
233
|
+
and the preview jobs comes from `--environment`, so change it with that
|
|
234
|
+
option instead.
|
|
216
235
|
- **These inputs of managed steps:** `ignore` on `tailor-generate-check` and
|
|
217
236
|
`tailor-drift-check`, `fail-on-drift` on `tailor-drift-check`,
|
|
218
237
|
`install-command` on `tailor-install`, `node-version-file` on
|
|
219
238
|
`tailor-setup`, `label` on `tailor-plan`, and `user-mapping` on
|
|
220
239
|
`tailor-notify` and on a coordinator's steps that call an app action.
|
|
221
|
-
- **The `run:` command of the `build-site` step** in a composite action.
|
|
240
|
+
- **The `run:` command of the `tailor-build-site` step** in a composite action.
|
|
241
|
+
|
|
242
|
+
In a preview workflow, the `tailor-preview-deploy` job exposes the per-PR
|
|
243
|
+
workspace as the outputs `workspace-id`, `workspace-name`, and `app-url`, so a
|
|
244
|
+
job of your own can run tests or deploy extra assets against it:
|
|
245
|
+
|
|
246
|
+
```yaml
|
|
247
|
+
deploy-assets:
|
|
248
|
+
needs: tailor-preview-deploy
|
|
249
|
+
runs-on: ubuntu-latest
|
|
250
|
+
environment: my-app
|
|
251
|
+
env:
|
|
252
|
+
TAILOR_PLATFORM_WORKSPACE_ID: ${{ needs.tailor-preview-deploy.outputs.workspace-id }}
|
|
253
|
+
TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID }}
|
|
254
|
+
TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET }}
|
|
255
|
+
steps:
|
|
256
|
+
# checkout, dependency installation, and your tailor commands
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
A job that runs `tailor` against the workspace needs the machine-user
|
|
260
|
+
[secrets](#secrets), so it declares the preview target's GitHub Environment
|
|
261
|
+
(the `--environment` value, or the workspace name when omitted) as above. A job
|
|
262
|
+
that only uses `app-url`, such as end-to-end tests, does not.
|
|
263
|
+
|
|
264
|
+
The job is skipped whenever `tailor-preview-deploy` is skipped: when a pull
|
|
265
|
+
request is closed, for draft and fork pull requests, and for unlabeled ones with
|
|
266
|
+
`--require-preview-label`.
|
|
267
|
+
|
|
268
|
+
Likewise, the `tailor-deploy` job of a branch or tag workflow exposes the
|
|
269
|
+
deployed workspace as the outputs `workspace-id` and `app-url` to a job with
|
|
270
|
+
`needs: tailor-deploy`. Reading them does not require the target's GitHub
|
|
271
|
+
Environment; a job that runs `tailor` against the workspace declares it for the
|
|
272
|
+
machine-user secrets, as in the preview example above.
|
|
222
273
|
|
|
223
274
|
Comments above your own jobs and steps and at the end of the file are kept too.
|
|
224
275
|
Comments inside managed jobs and steps, and edits to the header comment, are
|
|
225
276
|
not kept.
|
|
226
277
|
|
|
227
278
|
`setup check` reports an edit to a managed part, and re-running `setup` stops
|
|
228
|
-
on it
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
279
|
+
on it; both name the edited job, step, or top-level key. Revert the edit, or
|
|
280
|
+
pass `--force` to reset the managed parts to the current template; `--force`
|
|
281
|
+
still keeps your own jobs, steps, and settings. A managed step you renamed to
|
|
282
|
+
an id without the `tailor-` prefix counts as your own, so `--force` adds the
|
|
283
|
+
managed one back next to it; rename it back instead of forcing. A managed job
|
|
284
|
+
you renamed still holds the SDK's `tailor-` steps, so `setup check` reports
|
|
285
|
+
them as reserved ids and `setup` stops on them, even with `--force`; rename the
|
|
286
|
+
job back. To start over from a clean template, delete the file and re-run
|
|
287
|
+
`setup`.
|
|
233
288
|
|
|
234
289
|
When a template update removes a managed job that contains steps of yours, or
|
|
235
290
|
a job of yours `needs` a removed job, `setup` stops and names them. Move those
|
|
236
291
|
steps into a job of your own (or update the `needs`) and re-run. `--force` drops
|
|
237
|
-
steps left inside a removed job.
|
|
238
|
-
|
|
239
|
-
|
|
292
|
+
steps left inside a removed job.
|
|
293
|
+
|
|
294
|
+
`setup check` reports a job or step of yours whose `id` starts with `tailor-`,
|
|
295
|
+
and re-running `setup` stops on it, naming the id. Rename it; `--force` does
|
|
296
|
+
not rename or remove it.
|
|
240
297
|
|
|
241
298
|
Files generated by an older SDK version are compared as a whole, so the first
|
|
242
299
|
re-run after upgrading stops if you edited the file in any way. Re-run once with
|
|
@@ -296,7 +353,8 @@ the move.
|
|
|
296
353
|
|
|
297
354
|
## Secrets
|
|
298
355
|
|
|
299
|
-
The generated workflow
|
|
356
|
+
The generated workflow requires two secrets (the optional Slack token is listed in
|
|
357
|
+
[Setting secrets and variables](#setting-secrets-and-variables)):
|
|
300
358
|
|
|
301
359
|
| Secret | Description |
|
|
302
360
|
| -------------------------------------------- | -------------------------- |
|
|
@@ -304,12 +362,8 @@ The generated workflow reads two secrets:
|
|
|
304
362
|
| `TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET` | Machine user client secret |
|
|
305
363
|
|
|
306
364
|
Set them on the target GitHub Environment (the `--environment` value, or the
|
|
307
|
-
workspace name when omitted)
|
|
308
|
-
|
|
309
|
-
```bash
|
|
310
|
-
gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID --env my-app-stg
|
|
311
|
-
gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET --env my-app-stg
|
|
312
|
-
```
|
|
365
|
+
workspace name when omitted); `tailor setup ci env` prints the commands (see
|
|
366
|
+
[Setting secrets and variables](#setting-secrets-and-variables)).
|
|
313
367
|
|
|
314
368
|
Setting them at the environment level isolates each target's credentials and
|
|
315
369
|
keeps them alongside that environment's `TAILOR_PLATFORM_WORKSPACE_ID`
|
|
@@ -317,6 +371,62 @@ variable. You can also set them as repository-level secrets if every target
|
|
|
317
371
|
shares one machine user, but then any workflow on any branch can read them, so
|
|
318
372
|
the environment's protection rules no longer guard your deploys.
|
|
319
373
|
|
|
374
|
+
### Setting secrets and variables
|
|
375
|
+
|
|
376
|
+
`tailor setup ci env` reads `.github/tailor.lock` and prints, for every GitHub
|
|
377
|
+
Environment the generated workflows use, the commands that create the
|
|
378
|
+
environment (only when it does not exist yet) and set its secrets and
|
|
379
|
+
variables. It is read-only, so re-run it whenever you add a target. When the
|
|
380
|
+
`origin` remote points at github.com, the output names that repository, so the
|
|
381
|
+
commands work from any directory; otherwise `gh` resolves the repository from
|
|
382
|
+
the current directory and the Terraform output leaves it as a placeholder.
|
|
383
|
+
|
|
384
|
+
```bash
|
|
385
|
+
tailor setup ci env # gh CLI commands (default)
|
|
386
|
+
tailor setup ci env --format terraform # Terraform for the integrations/github provider
|
|
387
|
+
tailor setup ci env --environment my-app-stg # only one environment (repeat for several)
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
The list follows what each generated workflow actually reads:
|
|
391
|
+
|
|
392
|
+
| Name | Kind | Targets | Required | Where the value comes from |
|
|
393
|
+
| -------------------------------------------- | -------- | ----------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
394
|
+
| `TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID` | secret | all | yes | Client ID of the platform machine user CI signs in as; it needs an editor or admin role on the organization or folder that holds the workspace. Contact [Tailor support](https://docs.tailor.tech/administration/support) to get one |
|
|
395
|
+
| `TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET` | secret | all | yes | Client secret of the same platform machine user |
|
|
396
|
+
| `TAILOR_PLATFORM_WORKSPACE_ID` | variable | branch, tag, coordinate | yes | `id` printed by `tailor workspace create`, or listed by `tailor workspace list` |
|
|
397
|
+
| `TAILOR_PLATFORM_ORGANIZATION_ID` | variable | preview | yes | Organization to create the per-PR workspaces in (a machine user cannot create a workspace without one): `organizationId` listed by `tailor organization list` |
|
|
398
|
+
| `TAILOR_PLATFORM_FOLDER_ID` | variable | preview | no | Folder to create the per-PR workspaces in: `id` listed by `tailor organization folder list -o <organization id>`. When unset they go directly under the organization, which needs the machine user's role on the organization itself |
|
|
399
|
+
| `TAILOR_PLATFORM_FAIL_ON_DRIFT` | variable | all | no | `true` to fail the drift check when it finds drift |
|
|
400
|
+
| `TAILOR_SLACK_BOT_TOKEN` | secret | branch, tag, coordinate | no | Bot User OAuth Token (`xoxb-...`) of a Slack app with the `chat:write` scope |
|
|
401
|
+
| `TAILOR_SLACK_CHANNEL_ID` | variable | branch, tag, coordinate | no | Channel ID (`C...`) from the channel details in Slack; invite the bot to the channel |
|
|
402
|
+
| `TAILOR_SLACK_USER_MAPPING` | variable | branch, tag | no | JSON object mapping GitHub usernames to Slack member IDs (for example `{"alice":"U0123456"}`) so notifications mention the actor; read only after you uncomment the `user-mapping` input of the `tailor-notify` step |
|
|
403
|
+
|
|
404
|
+
See [Account management](https://docs.tailor.tech/administration/account-management)
|
|
405
|
+
for how organizations, folders, workspaces, and machine users relate.
|
|
406
|
+
|
|
407
|
+
Composite actions (`setup ci action`) read nothing themselves; the coordinator
|
|
408
|
+
that calls them does. Set `TAILOR_SLACK_BOT_TOKEN` and `TAILOR_SLACK_CHANNEL_ID`
|
|
409
|
+
together to enable Slack deploy notifications.
|
|
410
|
+
|
|
411
|
+
The `gh` output creates an environment only when GitHub reports it missing and
|
|
412
|
+
leaves optional entries commented out. Run the commands one at a time: each
|
|
413
|
+
`gh secret set` / `gh variable set` prompts for its value.
|
|
414
|
+
|
|
415
|
+
The Terraform output takes every value from an input variable (secrets are
|
|
416
|
+
`sensitive`) and creates an optional entry only when its variable is set, so no
|
|
417
|
+
value is written to the output. Terraform still stores the secret values in its
|
|
418
|
+
state in plain text, so keep the state encrypted and access-restricted, or set
|
|
419
|
+
the secrets with the `gh` output instead. Its header lists the steps with the variable
|
|
420
|
+
names for your environments: authenticate the provider, put non-secret values in
|
|
421
|
+
`terraform.tfvars`, pass secrets as `TF_VAR_<name>` environment variables, and
|
|
422
|
+
import each environment and variable that already exists (for example
|
|
423
|
+
`terraform import github_repository_environment.production my-repo:production`)
|
|
424
|
+
before `terraform apply`: creating a variable that already exists fails, while
|
|
425
|
+
secrets are overwritten. The generated environments ignore changes to their
|
|
426
|
+
protection settings (reviewers, wait timer, branch policy), so importing an
|
|
427
|
+
environment keeps the approval gate you configured; remove the `lifecycle` block
|
|
428
|
+
to manage those settings in Terraform instead.
|
|
429
|
+
|
|
320
430
|
## GitHub Environments (approval gate)
|
|
321
431
|
|
|
322
432
|
Both the `plan` and `deploy` jobs are associated with a GitHub Environment — the
|
|
@@ -382,9 +492,61 @@ For a monorepo where your SDK app lives in a subdirectory, pass `--dir`:
|
|
|
382
492
|
tailor setup ci branch --name my-app --dir apps/backend
|
|
383
493
|
```
|
|
384
494
|
|
|
385
|
-
The
|
|
386
|
-
|
|
387
|
-
|
|
495
|
+
The `working-directory` for SDK commands is set accordingly, and the workflow
|
|
496
|
+
only plans and deploys when that subdirectory changes. The workflow itself
|
|
497
|
+
starts on every pull request and push: a `tailor-changes` job checks whether
|
|
498
|
+
the change touches `apps/backend/**`, and the plan, deploy, and ERD preview jobs
|
|
499
|
+
are skipped when it does not. A skipped job reports success, so you can make
|
|
500
|
+
these checks required in branch protection; a workflow that a `paths` trigger
|
|
501
|
+
filter never started would leave them pending instead. If the `tailor-changes` job
|
|
502
|
+
itself fails (for example, on a GitHub API error), the plan, deploy, and ERD
|
|
503
|
+
preview jobs fail too instead of being skipped, so a required check blocks
|
|
504
|
+
merging and nothing is deployed. Re-run the failed jobs once the cause is gone.
|
|
505
|
+
|
|
506
|
+
### Deploying several apps together
|
|
507
|
+
|
|
508
|
+
To deploy several apps to the same workspace from one workflow, repeat `--dir`
|
|
509
|
+
and pass `--name` for the workflow:
|
|
510
|
+
|
|
511
|
+
```bash
|
|
512
|
+
tailor setup ci branch --name erp --dir apps/erp/backend --dir apps/users/backend
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
`setup ci branch`, `setup ci tag`, and `setup ci preview` accept repeated
|
|
516
|
+
`--dir`. The workflow plans and deploys every app's `tailor.config.ts` in one
|
|
517
|
+
[multi-config deploy](./cli/application.md#deploy) from the repository root, so
|
|
518
|
+
an app can reference resources of another app with `external: true`. Add
|
|
519
|
+
`@tailor-platform/sdk` to the root `package.json` so the `tailor` CLI resolves
|
|
520
|
+
there; setup stops until it is declared. The generate check runs for each app
|
|
521
|
+
directory, as do seed validation and the migration drift check on branch and tag
|
|
522
|
+
workflows, and a change under any app directory runs the workflow's jobs.
|
|
523
|
+
|
|
524
|
+
With `--erd-preview`, each TailorDB namespace is previewed from the app that
|
|
525
|
+
owns it. A namespace may be owned by only one app; the others reference it with
|
|
526
|
+
`external: true`.
|
|
527
|
+
|
|
528
|
+
With more than one app, the preview comment does not link an application URL.
|
|
529
|
+
|
|
530
|
+
### Running on changes outside the app directories
|
|
531
|
+
|
|
532
|
+
When the apps depend on code outside their directories, such as a frontend or
|
|
533
|
+
shared packages, add those paths with `--paths` on `setup ci branch` or
|
|
534
|
+
`setup ci preview`. Repeat it for each pattern:
|
|
535
|
+
|
|
536
|
+
```bash
|
|
537
|
+
tailor setup ci preview --name erp --region asia-northeast \
|
|
538
|
+
--dir apps/erp/backend --dir apps/users/backend \
|
|
539
|
+
--paths "apps/*/frontend/**" --paths "modules/**" --paths pnpm-lock.yaml
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
The patterns are checked after the app directories, in order, and the last
|
|
543
|
+
pattern that matches a changed file decides whether it counts. `*` matches
|
|
544
|
+
within one path segment, `**` matches any number of segments, and a pattern
|
|
545
|
+
starting with `!` excludes matching paths, so it can also exclude files inside
|
|
546
|
+
an app directory, for example `--paths '!apps/erp/backend/**/*.md'`. Other glob
|
|
547
|
+
characters (`?`, `+`, `[ ]`, `{ }`, `( )`, and `\`) are not supported, and
|
|
548
|
+
`setup ci` rejects a pattern that contains them. An app at the repository root already
|
|
549
|
+
runs on every change, so `--paths` is not accepted with `--dir .`.
|
|
388
550
|
|
|
389
551
|
## Rollback
|
|
390
552
|
|
|
@@ -453,18 +615,13 @@ tailor setup ci tag --name my-app-prod \
|
|
|
453
615
|
--branch main --environment production
|
|
454
616
|
```
|
|
455
617
|
|
|
456
|
-
Then provision each workspace and set its id
|
|
457
|
-
staging target's environment defaults to
|
|
458
|
-
`production`)
|
|
618
|
+
Then provision each workspace and set its id and the machine-user credentials
|
|
619
|
+
on the matching environment (the staging target's environment defaults to
|
|
620
|
+
`my-app-stg`; production uses `production`). `tailor setup ci env` prints the
|
|
621
|
+
commands for both environments:
|
|
459
622
|
|
|
460
623
|
```bash
|
|
461
|
-
|
|
462
|
-
gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID --env my-app-stg
|
|
463
|
-
gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET --env my-app-stg
|
|
464
|
-
|
|
465
|
-
gh variable set TAILOR_PLATFORM_WORKSPACE_ID --env production
|
|
466
|
-
gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID --env production
|
|
467
|
-
gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET --env production
|
|
624
|
+
tailor setup ci env
|
|
468
625
|
```
|
|
469
626
|
|
|
470
627
|
Commit both workflow files and `.github/tailor.lock`.
|
|
@@ -502,19 +659,21 @@ them. To remove it, delete the file.
|
|
|
502
659
|
|
|
503
660
|
Renovate updates the SDK dependency and action pins, but it does not regenerate
|
|
504
661
|
the workflow template. After an SDK update, `tailor setup check` reports a
|
|
505
|
-
template-version warning until you
|
|
506
|
-
|
|
662
|
+
template-version warning until you run
|
|
663
|
+
[`tailor setup update`](#updating-the-generated-workflow).
|
|
507
664
|
|
|
508
665
|
## Checking for drift
|
|
509
666
|
|
|
510
667
|
`tailor setup check` audits the workflows recorded in
|
|
511
668
|
`.github/tailor.lock` against your current config and repository, without
|
|
512
669
|
writing anything. It reports when a workflow file is missing or its SDK-managed
|
|
513
|
-
parts were edited by hand, a
|
|
514
|
-
newer template is available, `tailor.config.ts` is no longer under the recorded
|
|
670
|
+
parts were edited by hand, a job or step of yours uses the reserved `tailor-`
|
|
671
|
+
prefix, a newer template is available, `tailor.config.ts` is no longer under the recorded
|
|
515
672
|
`--dir`, or the repository default branch no longer matches a branch target's
|
|
516
673
|
trigger. It exits non-zero when it finds drift, so you can run it in CI. Each
|
|
517
|
-
finding names a stable rule key for future suppression.
|
|
674
|
+
finding names a stable rule key for future suppression. Run
|
|
675
|
+
[`tailor setup update`](#updating-the-generated-workflow) to regenerate the
|
|
676
|
+
targets it reports.
|
|
518
677
|
|
|
519
678
|
Workflows generated by `setup ci branch`, `setup ci tag`, `setup ci preview`, and
|
|
520
679
|
`setup ci coordinate` self-audit: each contains a `tailor-drift-check` step that
|
|
@@ -529,21 +688,42 @@ Drift findings are advisory by default. Set the repository variable
|
|
|
529
688
|
`TAILOR_PLATFORM_FAIL_ON_DRIFT` to `true` to make unsuppressed findings fail
|
|
530
689
|
the job. Execution and configuration errors fail regardless of this variable.
|
|
531
690
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
verification there, since the deploy job resolves the Environment variable
|
|
537
|
-
itself at runtime.
|
|
691
|
+
`check` compares only the generated files, `.github/tailor.lock`, and the
|
|
692
|
+
config; it does not read the GitHub Environment secrets and variables, so it
|
|
693
|
+
runs the same on your own machine and in CI. Run `tailor setup ci env` to list
|
|
694
|
+
what each environment needs.
|
|
538
695
|
|
|
539
696
|
## Updating the generated workflow
|
|
540
697
|
|
|
541
|
-
When you upgrade the SDK,
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
698
|
+
When you upgrade the SDK, run `tailor setup update` from the repository root to
|
|
699
|
+
pick up template improvements:
|
|
700
|
+
|
|
701
|
+
```bash
|
|
702
|
+
tailor setup update
|
|
703
|
+
```
|
|
547
704
|
|
|
548
|
-
|
|
549
|
-
|
|
705
|
+
It regenerates every workflow and composite action recorded in
|
|
706
|
+
`.github/tailor.lock` with the flags each one was generated with, so you do not
|
|
707
|
+
have to re-type `setup ci branch`, `setup ci tag`, and the rest one by one.
|
|
708
|
+
Your own jobs, steps, and settings are kept (see
|
|
709
|
+
[Customizing the generated workflow](#customizing-the-generated-workflow)). A
|
|
710
|
+
branch that was detected from the repository default branch is detected again,
|
|
711
|
+
and the parts that follow your config — the migration drift check, seed
|
|
712
|
+
validation, static website builds, and ERD preview namespaces — are derived
|
|
713
|
+
from the current `tailor.config.ts`.
|
|
714
|
+
|
|
715
|
+
A target that cannot be regenerated, for example because you edited a managed
|
|
716
|
+
part, does not stop the others: `update` regenerates the rest, then lists the
|
|
717
|
+
targets it could not update and exits non-zero. Revert the edit, or run
|
|
718
|
+
`tailor setup update --force` to reset the managed parts of every target.
|
|
719
|
+
|
|
720
|
+
Coordinators generated by an older plugin version did not record how their
|
|
721
|
+
`--action` values were grouped, so `update` lists them instead of guessing
|
|
722
|
+
which apps deploy together. Re-run `tailor setup ci coordinate` once with all
|
|
723
|
+
of its original flags and its original `--action` groups. The message `update`
|
|
724
|
+
prints fills in the recorded flags (`--tag`, `--branch`, `--environment`,
|
|
725
|
+
`--restrict-dispatch`), so you only add the `--action` values. Later updates
|
|
726
|
+
pick the grouping up from the lock.
|
|
727
|
+
|
|
728
|
+
To change a flag for one target, re-run its `setup ci` subcommand with the new
|
|
729
|
+
flags. `.github/tailor.lock` records them, and later updates reuse them.
|
package/docs/migration/v3.md
CHANGED
|
@@ -128,6 +128,52 @@ property, which is the relation's cardinality (e.g. "n-1", "1-1",
|
|
|
128
128
|
|
|
129
129
|
</details>
|
|
130
130
|
|
|
131
|
+
## defineConfig inlineSourcemap / logLevel → buildOptions
|
|
132
|
+
|
|
133
|
+
**Migration:** Partially automatic
|
|
134
|
+
|
|
135
|
+
Move the top-level `inlineSourcemap` and `logLevel` of `defineConfig()` into `buildOptions`, which groups the settings that control how functions are bundled. The top-level fields keep working until they are removed in v3; setting the same option in both places is rejected.
|
|
136
|
+
|
|
137
|
+
Before:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
export default defineConfig({
|
|
141
|
+
name: "my-app",
|
|
142
|
+
inlineSourcemap: false,
|
|
143
|
+
logLevel: "WARN",
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
After:
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
export default defineConfig({
|
|
151
|
+
name: "my-app",
|
|
152
|
+
buildOptions: {
|
|
153
|
+
inlineSourcemap: false,
|
|
154
|
+
logLevel: "WARN",
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
<details>
|
|
160
|
+
<summary>Prompt for an AI agent (to finish the cases the codemod could not migrate)</summary>
|
|
161
|
+
|
|
162
|
+
```text
|
|
163
|
+
In Tailor SDK v3, the top-level `inlineSourcemap` and `logLevel` options of
|
|
164
|
+
`defineConfig()` from `@tailor-platform/sdk` are removed in favor of
|
|
165
|
+
`buildOptions.inlineSourcemap` and `buildOptions.logLevel`. For each flagged
|
|
166
|
+
config, move those two properties into a `buildOptions` object (create it if
|
|
167
|
+
it does not exist) without changing their values. When the config is built
|
|
168
|
+
from a variable or a spread, move them in the object that actually defines
|
|
169
|
+
them. If an option is set both at the top level and in `buildOptions`, keep
|
|
170
|
+
the value that the deployed app should use and delete the other; the build
|
|
171
|
+
rejects a config that sets both. Leave `logLevel` options of other tools
|
|
172
|
+
(for example a Vite or Vitest config) unchanged.
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
</details>
|
|
176
|
+
|
|
131
177
|
## String file uploads → explicit encoding
|
|
132
178
|
|
|
133
179
|
**Migration:** Manual
|
|
@@ -64,7 +64,9 @@ tailor deploy -w <production-workspace-id> --env-file .env.production
|
|
|
64
64
|
```typescript
|
|
65
65
|
export default defineConfig({
|
|
66
66
|
name: "my-app",
|
|
67
|
-
|
|
67
|
+
buildOptions: {
|
|
68
|
+
logLevel: process.env.TAILOR_APP_LOG_LEVEL ?? "DEBUG",
|
|
69
|
+
},
|
|
68
70
|
});
|
|
69
71
|
```
|
|
70
72
|
|
package/docs/plugin/custom.md
CHANGED
|
@@ -6,7 +6,7 @@ Create your own plugins by implementing the `Plugin` interface.
|
|
|
6
6
|
|
|
7
7
|
## Requirements
|
|
8
8
|
|
|
9
|
-
**Plugins must use default export**:
|
|
9
|
+
**Plugins with definition-time hooks must use default export**:
|
|
10
10
|
|
|
11
11
|
```typescript
|
|
12
12
|
// plugin.ts
|
|
@@ -48,6 +48,9 @@ interface Plugin<TableConfig = unknown, PluginConfig = unknown> {
|
|
|
48
48
|
onExecutorReady?(
|
|
49
49
|
context: ExecutorReadyContext<PluginConfig>,
|
|
50
50
|
): GeneratorResult | Promise<GeneratorResult>;
|
|
51
|
+
onDeployed?(
|
|
52
|
+
context: DeployedContext<PluginConfig>,
|
|
53
|
+
): void | DeployedHookResult | Promise<void | DeployedHookResult>;
|
|
51
54
|
}
|
|
52
55
|
```
|
|
53
56
|
|
|
@@ -254,6 +257,78 @@ onExecutorReady(ctx) {
|
|
|
254
257
|
},
|
|
255
258
|
```
|
|
256
259
|
|
|
260
|
+
### onDeployed
|
|
261
|
+
|
|
262
|
+
Runs once after every application in the deploy has been applied, including when
|
|
263
|
+
there are no resource changes. Hooks run sequentially in config order, then in
|
|
264
|
+
`definePlugins()` registration order. No `importPath` or table attachment is required.
|
|
265
|
+
|
|
266
|
+
Use `ctx.application` for the registering application's ID, URL, domain, AI
|
|
267
|
+
Gateway URLs, static websites, and public OAuth client IDs. `ctx.application.id`
|
|
268
|
+
is the `id` from `defineConfig()` and is `undefined` when the config has none.
|
|
269
|
+
`ctx.applications` contains all applications in a multi-config deploy with the
|
|
270
|
+
same fields. OAuth client secrets are never included.
|
|
271
|
+
|
|
272
|
+
`ctx.configPath` is the absolute path of the registering config. `ctx.workspaceId`
|
|
273
|
+
and `ctx.pluginConfig` identify the deployment workspace and the plugin's options.
|
|
274
|
+
Use `ctx.logger.info`, `warn`, and `success` for diagnostics; they write to stderr
|
|
275
|
+
and preserve deploy's JSON stdout.
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
import { definePlugins, type Plugin } from "@tailor-platform/sdk";
|
|
279
|
+
|
|
280
|
+
const deployedInfo: Plugin = {
|
|
281
|
+
id: "@example/deployed-info",
|
|
282
|
+
description: "Reports the deployed application URL",
|
|
283
|
+
onDeployed(ctx) {
|
|
284
|
+
const url = ctx.application.url;
|
|
285
|
+
if (!url) return;
|
|
286
|
+
ctx.logger.success(`Application ready: ${url}`);
|
|
287
|
+
return { outputs: { url } };
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
export const plugins = definePlugins(deployedInfo);
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
To publish assets, look up the site with `ctx.application.staticWebsites[name]`
|
|
295
|
+
and await its `publish(dir)` with an absolute directory path. Only websites
|
|
296
|
+
declared in the registering config appear there; any other name is `undefined`,
|
|
297
|
+
so check the site before publishing. Websites of other configs are listed under
|
|
298
|
+
`ctx.applications` with their `name` and `url` only, so a plugin can read their
|
|
299
|
+
URLs but cannot publish to them. The result contains `url` and `skippedFiles`; report skipped
|
|
300
|
+
files so users can correct files that could not be uploaded.
|
|
301
|
+
|
|
302
|
+
To run a shell command such as a build, await `ctx.exec(command, { workingDir, env })`.
|
|
303
|
+
It rejects when the command exits with a non-zero code. By default the command's
|
|
304
|
+
stdout and stderr both go to stderr so `tailor deploy --json` stdout stays parseable;
|
|
305
|
+
pass `output: "capture"` to receive them as `stdout` and `stderr` instead, or
|
|
306
|
+
`output: "ignore"` to discard them. Use `ctx.exec` rather than importing
|
|
307
|
+
`node:child_process` in the plugin: `tailor.config.ts` is also bundled into
|
|
308
|
+
functions that run on the Tailor Platform, such as auth hooks, and a plugin module
|
|
309
|
+
that imports Node.js-only modules makes that bundle fail.
|
|
310
|
+
|
|
311
|
+
Return JSON-serializable `outputs` to include a result in `deployedHooks` under
|
|
312
|
+
`tailor deploy --json`. Each entry identifies the application and plugin. This
|
|
313
|
+
key is omitted when no hook supplies outputs. `outputs` must be a plain object whose
|
|
314
|
+
values are only strings, finite numbers, booleans, `null`, arrays, and plain objects;
|
|
315
|
+
any other value, such as `undefined`, a function, or a `Date`, fails the hook.
|
|
316
|
+
Output values may be typed with an `interface`. The type checker rejects a
|
|
317
|
+
`Date`, function, `Map`, or other non-JSON value placed directly in `outputs` or in
|
|
318
|
+
an object or array literal, but a `Date` or class instance nested inside an
|
|
319
|
+
interface-typed value is caught only when `tailor deploy` runs the hook.
|
|
320
|
+
|
|
321
|
+
A failed hook stops later hooks with `DEPLOYED_HOOK_FAILED`. The same error is
|
|
322
|
+
reported when the deployed information passed to hooks cannot be loaded. Platform
|
|
323
|
+
resources have already been applied and are not rolled back. The error lists any hooks
|
|
324
|
+
that did not run, with the application each belongs to. Fix the hook and run `tailor deploy` again; hooks run again even
|
|
325
|
+
if there are no resource changes.
|
|
326
|
+
|
|
327
|
+
Hooks do not run during dry-run, build-only, or migration test deployments.
|
|
328
|
+
Dry-run lists the pending hooks; with `--json`, they appear under
|
|
329
|
+
`pendingDeployedHooks` as `{ application, pluginId }` entries. Calling `deploy()` from the programmatic CLI
|
|
330
|
+
API runs hooks under the same conditions as `tailor deploy`.
|
|
331
|
+
|
|
257
332
|
## Hook Scheduling Rules
|
|
258
333
|
|
|
259
334
|
Each generation-time hook runs at its own pipeline phase, regardless of what other hooks the same plugin implements:
|