Skip to content

test(sdk-plugin-seed): add e2e coverage for tailor seed apply - #1941

Draft
toiroakr wants to merge 951 commits into
mainfrom
test/seed-apply-e2e
Draft

test(sdk-plugin-seed): add e2e coverage for tailor seed apply#1941
toiroakr wants to merge 951 commits into
mainfrom
test/seed-apply-e2e

Conversation

@toiroakr

Copy link
Copy Markdown
Contributor

Summary

  • Add an e2e vitest project to packages/sdk-plugin-seed (mirroring packages/sdk's e2e project + globalSetup.ts workspace-provisioning pattern) since the package previously had none.
  • Add e2e/apply.e2e.test.ts, covering tailor seed apply end to end against a real deployed workspace:
    • basic TailorDB seeding without --upsert
    • --upsert insert + update behavior for TailorDB rows
    • --upsert for the Built-In IdP _User entity (create, update, and skip an attribute-less row)
    • --truncate clearing tables before a fresh seed
  • Wire a new seed-plugin-e2e CI job into .github/workflows/sdk-e2e.yml, required by the existing sdk-e2e-result gate.
  • Add a patch changeset.

All 4 e2e tests were run locally against a real, disposable workspace before opening this PR.

Notes

  • Targets v2 (not main) — this fills a gap identified while merging feat/seed-upsert from main into v2, where --upsert had to be ported to sdk-plugin-seed's CLI-plugin architecture.

toiroakr and others added 30 commits July 15, 2026 16:54
The .validate() callback's issues() field parameter used a self-generic
<P extends DottedPaths<...>> signature. Comparing two such generic call
signatures requires TypeScript to check the inner constraint for identity
rather than assignability, which spuriously rejected structurally-equal
TailorDBType instances built from the same custom fields but derived
through different generic instantiation paths (e.g. a table passed across
a module factory boundary), surfacing as TS2719 ("Two different types
with this name exist, but they are unrelated"). Making the parameter a
plain (non-generic) union keeps strict field-path checking while using
ordinary assignability for these comparisons.
Comment restated design rationale already covered by the commit message
and regression test; per the code-comments convention, source comments
should express constraints the code can't otherwise convey, not PR
rationale.
Rename to make clear this documents assignability when a factory's
parameter type is derived via explicit type-argument passthrough,
rather than serving as a direct regression guard for the TS2719
false-positive reported upstream. A standalone repro of that exact
compiler behavior could not be constructed without the consuming
package's full module composition.
Resolve conflicts by taking v2's dependency bumps and generated workflow
types, and drop the pkg.pr.new zinfer override now that zinfer 0.2.5
includes commit 054a3a5.
fix(tailordb): make issues() field param non-generic
… to .start()

Remove the pre-alignment `tailor.workflow` names `triggerWorkflow`,
`triggerJobFunction`, and `resumeWorkflow` (and their `TriggerWorkflowOptions`
/ `TriggerJobFunctionOptions` option types) from `@tailor-platform/sdk/runtime`,
the ambient `@tailor-platform/sdk/runtime/globals` types, and the
`mockWorkflow()` test facade. Use the canonical `startWorkflow`,
`startJobFunction`, and `resumeWorkflowExecution` names instead.

Also rename `Workflow.trigger()` (from `createWorkflow()`) and
`WorkflowJob.trigger()` (from `createWorkflowJob()`) to `.start()`, aligning
the SDK's ergonomic verb with the platform's `start*` RPC vocabulary.
`mockWorkflow()`'s `wf.job()`/`wf.workflow()` mocks, `wf.setTriggerHandler` /
`wf.triggeredJobs`, and the CLI bundler's trigger detection/codegen are
updated to match.

Adds the `v2/workflow-trigger-rename` codemod (automatic) for the low-level
rename, and registers `v2/workflow-start-rename` (manual, guided by prompt)
for the `.trigger()` -> `.start()` call-site rename, since distinguishing a
workflow/job `.trigger()` call from an unrelated object's own method isn't
reliably decidable from a single file's syntax.
…rgs-contract

fix(executor): align workflow argument contracts
`docs/services/workflow.md` links to
`example/resolvers/startWorkflow.ts` on `main`, but that file only exists
on the `v2` branch until it merges. Exclude the URL from lychee's link
check so this known, temporary, non-blocking gap doesn't fail CI; it
self-resolves once `v2` lands on `main`.
# Conflicts:
#	packages/sdk/src/configure/services/executor/executor.ts
- Rename the internal `getTriggerCallInfo`/`TriggerCallInfo` AST helper to
  `getStartCallInfo`/`StartCallInfo`: it now detects `.start(...)` calls, and
  its JSDoc already said so, so the old name was misleading next to it.
- Fix `packages/sdk/src/vitest/globals.ts`'s comment on the default workflow
  runtime: it doesn't run the real job chain locally (that's
  `runWorkflowLocally()`) — job/wait/resolve calls throw a helpful error by
  default, and workflow starts return a placeholder execution id.
- Fix "in separated job" -> "in a separate job" in docs/services/workflow.md.
…ch helper

Share the plugin slug computation between dispatch and the install hint,
and move the hint branch out of runMain so it can be unit tested.
The v2 branch releases under the npm next dist-tag while changesets
pre-release mode is active; a plain install would resolve to the 0.0.0
bootstrap version on latest.
- The bundler's and trigger-transformer's `.start(` pre-checks used a plain
  substring match, which misses whitespace/newline-formatted calls (e.g.
  `.start (` or `.start\n(`) and would silently skip the AST transform,
  leaving an untransformed `.start(...)` call to throw at runtime in the
  bundle. Add a shared `hasStartCall()` regex helper and use it in all three
  call sites (trigger-transformer.ts, bundler.ts x2).
- Fix stale "trigger"/"triggerJobFunction" wording in
  ast-transformer.test.ts comments and titles that no longer match the
  `startJobFunction` assertions they describe.
The v2 merge bumped tsdown to 0.22.5 everywhere else, dropping the
0.22.4 lockfile entry the plugin still referenced and breaking
frozen-lockfile installs.
install-deps now consumes the pending-rebuild state while the plugin's
dist is still missing, so the later rebuild --pending no longer relinks
the skipped bin. Linking at install time against a stub removes the
relink dependency entirely.
…h the public API rename

Rename trigger-context.ts/trigger-transformer.ts and their exported
identifiers (TriggerContext, TriggerTarget, TriggerModuleBindings,
ResolvedTriggerCall, transformFunctionTriggers,
createTriggerTransformPlugin, detectResolvedTriggerCalls, etc.) to
their Start* equivalents, aligning internal AST/bundler naming with
the .start() rename. Unrelated Trigger usages (executor/IdP event
triggers) are untouched.
…kflow-trigger-dispatch

sdk-codemod's CLI applies all applicable codemods in a single --from/--to
pass. v2/workflow-start-rename has no scriptPath, so it never
auto-transforms .trigger() to .start() within that pass, and pre-migration
v1 code cannot contain .start( at all (the method did not exist under that
name). The scenario this pattern guarded against — a file already renamed
to .start( before workflow-trigger-dispatch's suspiciousPatterns are
checked — is unreachable in the tool's actual single-shot usage.
…lugin

feat(sdk)!: extract tailordb erd into a CLI plugin package
…ase versions

`v2/db-type-to-table` and `v2/runtime-subpath-namespace` declared
`prereleaseUntil: 2.0.0-next.3`, but their breaking changes shipped in
`2.0.0-next.4`. `v2/forward-relation-name`, `v2/tailordb-validate-simplify`,
and `v2/tailordb-hook-redesign` declared `2.0.0-next.4`, but shipped in
`2.0.0-next.5`.

Because getApplicableCodemods() requires fromVersion < boundary <= toVersion,
upgrading exactly across the real release boundary (e.g. --from 2.0.0-next.4
on a 2.0.0-next.5 project) matched none of these codemods.
removeLegacyBundleFiles (packages/sdk/src/cli/services/stale-cleanup.ts)
was a backward-compat shim that cleaned up on-disk bundle artifacts
written by pre-virtual-entry SDK versions. Bundlers no longer write
those files, so the shim is now dead code.

- Delete stale-cleanup.ts
- Remove the removeLegacyBundleFiles call and import in deploy.ts
- Remove the legacy-file generation in __test_fixtures__/prepare.ts
  and the corresponding assertion in integration.test.ts
Add a V2_NEXT_PENDING sentinel prereleaseUntil for a codemod whose exact
2.0.0-next.N release boundary is not known yet at implementation time,
since that number is only decided once the release PR bumps the version.

A codemod pinned to V2_NEXT_PENDING never applies via
getApplicableCodemods() until resolved. `pnpm codemod:resolve-pending`
rewrites it to the concrete V2_NEXT_N constant (reusing an existing one
when its value already matches) once the real version is known.

Wire this into release.yml: right after changesets/action creates or
updates the release PR, checkout that PR branch, run the resolver, and
push any fixup through the GitHub Contents API (like
ensure-github-releases.sh) rather than a local git commit, since this
token has no configured git identity or signing key.
toiroakr and others added 12 commits July 30, 2026 15:36
# Conflicts:
#	example/seed/exec.mjs
#	example/tests/fixtures/expected/seed/exec.mjs
#	packages/create-sdk/templates/generators/src/seed/exec.mjs
#	packages/sdk/src/cli/services/auth/bundler.ts
#	packages/sdk/src/cli/services/executor/bundler.ts
#	packages/sdk/src/cli/services/resolver/bundler.ts
#	packages/sdk/src/cli/services/workflow/bundler.ts
#	packages/sdk/src/cli/shared/virtual-entry.ts
#	packages/sdk/src/plugin/builtin/seed/index.ts
- Bundle cache save() now skips storing an entry instead of failing the
  build when a dependency file cannot be hashed for a reason other than
  being missing, matching tryRestore()'s existing tolerance.
- Share one tsconfig paths-alias lookup cache across every resolver,
  executor, workflow job, auth hook, and HTTP adapter bundled in a
  single command, instead of each bundle reading and parsing its
  ancestor tsconfigs from scratch. A shared cache hit still reports its
  tsconfig dependencies to the current caller so per-bundle cache
  invalidation stays correct.
- Apply the same import-rebasing guard to a bundler's inline virtual
  entry that the on-disk generated-entry resolver already used.
- Document tsconfig paths alias support and the unresolved-import
  build failure in the Configuration guide.
- Fix bundling any resolver, executor, workflow job, auth hook, or
  HTTP adapter failing with "Could not resolve node:async_hooks": a
  workflow job's test-only invoker propagation is unreachable in a
  platform bundle but still needed resolving before this fix.
- Add get-tsconfig as a direct dependency of the SDK package.
- Port the seed apply command's config-directory-relative bundling fix
  to the sdk-plugin-seed package.
# Conflicts:
#	packages/sdk/docs/cli-reference.md
#	packages/sdk/docs/services/tailordb-migration.md
#	packages/sdk/src/cli/commands/deploy/tailordb/index.ts
#	packages/sdk/src/cli/commands/tailordb/migrate/set.ts
The new `tailordb migration validate` command and a remote-checkpoint
error path in `deploy` still referenced the removed `tailor-sdk` CLI
bin in user-facing messages.
createWaitPoints replaced defineWaitPoints in v2, but a JSDoc @link
tag, a pure-type-module comment, and the Workflow guide still named
the old function.
The apply command resolves --workspace-id, --profile, and --config from
TAILOR_PLATFORM_WORKSPACE_ID, TAILOR_PLATFORM_PROFILE, and
TAILOR_CONFIG_PATH when the flags are omitted. The tests assert the
resolved values but inherited the ambient shell environment, so any of
those exports made three truncation tests fail locally while CI stayed
green. Stub the three variables in beforeEach and unstub after each
test.
…lation

test(sdk-plugin-seed): isolate env-bound args in apply tests
Brings in feat/seed-upsert (PR #1910) from main.

v2 already extracts seed execution into the sdk-plugin-seed CLI plugin,
so the --upsert flag is ported to that architecture instead of merged
as generated exec.mjs code:
- sdk-plugin-seed: add --upsert to `tailor seed apply`, wiring it
  through seedNamespace/seedIdpUser and the TailorDB probe-and-update
  script that bundler.ts already generates
- jsonl.ts: enforce requireId/requiredFieldsByType when --upsert is set
- seed-type-processor.ts: compute per-type requiredFields for seed-context

Also applies review follow-ups from #1910:
- treat a _User seed row with only `name` as skipped, not updated
- suppress the _User success line when every row fails
- preserve the IdP lookup error alongside a create failure
- document that --upsert updates run through hooks/validation and fire
  recordUpdatedTrigger executors

# Conflicts:
#	example/seed/exec.mjs
#	example/tests/fixtures/expected/seed/exec.mjs
#	packages/create-sdk/templates/generators/src/seed/exec.mjs
#	packages/sdk/docs/generator/builtin.md
#	packages/sdk/src/cli/commands/generate/seed/bundler.test.ts
#	packages/sdk/src/plugin/builtin/seed/index.test.ts
#	packages/sdk/src/plugin/builtin/seed/index.ts
…ion guide

The v2/seed-exec-to-cli-plugin migration entry listed the tailor seed
apply options that mirror the old exec.mjs script, but the script never
had --upsert (it was added to seed apply after the CLI plugin
extraction). Add it to the option list in both the description and the
prompt so the migration guide stays accurate.
Cover `tailor seed apply` end to end against a real deployed workspace:
basic TailorDB seeding, --upsert insert/update behavior, --upsert for
the Built-In IdP _User entity (create/update/skip), and --truncate
before seeding. Mirrors packages/sdk/e2e's workspace-provisioning
pattern (own vitest "e2e" project, globalSetup, CI job).
@changeset-bot

changeset-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: bf9334f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@tailor-platform/sdk-plugin-seed Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 31, 2026

Copy link
Copy Markdown

Open in StackBlitz

@tailor-platform/create-sdk

pnpm add https://pkg.pr.new/tailor-platform/sdk/@tailor-platform/create-sdk@bf9334f

@tailor-platform/eslint-plugin-sdk

pnpm add https://pkg.pr.new/tailor-platform/sdk/@tailor-platform/eslint-plugin-sdk@bf9334f

@tailor-platform/sdk

pnpm add https://pkg.pr.new/tailor-platform/sdk/@tailor-platform/sdk@bf9334f

@tailor-platform/sdk-plugin-seed

pnpm add https://pkg.pr.new/tailor-platform/sdk/@tailor-platform/sdk-plugin-seed@bf9334f

@tailor-platform/sdk-plugin-tailordb-erd

pnpm add https://pkg.pr.new/tailor-platform/sdk/@tailor-platform/sdk-plugin-tailordb-erd@bf9334f

commit: bf9334f

CI refuses to auto-generate a tailor.config.ts app id (each run would
otherwise be treated as a separate app), so the dynamically generated
config this suite deploys needs to supply one itself, the same way
packages/sdk/e2e/deploy.test.ts already does. Locally the id gets
auto-injected, which is why this passed there but failed in CI.
@github-actions

This comment has been minimized.

@toiroakr
toiroakr force-pushed the v2 branch 3 times, most recently from 77bc78c to a3c4978 Compare July 31, 2026 09:51
Base automatically changed from v2 to main July 31, 2026 09:56
PR #1941 was retargeted from v2 to main after v2 merged into main and
the v2 branch was deleted (PR #1808). This brings in ~1000 commits of
main's subsequent evolution (the 2.0.0 stable release, TailorDB
labels/TRN/dependency tracking, publish-events rename, etc.).

Conflict resolution:
- packages/sdk-plugin-seed/{tsconfig.json,vitest.config.ts}: kept ours
  (the e2e project this PR adds; main doesn't have it yet).
- .changeset/{pre.json,seed-upsert-flag.md,v2-baseline.md}: accepted
  main's deletion (already consumed by the 2.0.0 release).
- Every other conflicting file (CHANGELOGs, package.json versions,
  generated docs, and deploy/tailordb/migrate source this branch never
  touched): took main's version wholesale, verified by spot-checking
  that the relevant content (e.g. the --upsert migration-guide mention
  in registry.ts) was already present there.
- pnpm-lock.yaml: regenerated via `pnpm install` after resolving the
  above.

Also fixed a duplicate test block in
packages/sdk/src/cli/commands/deploy/tailordb/index.test.ts: the
non-conflicting 3-way auto-merge combined two independent additions of
the same "treats permission policy order differences as unchanged"
test (one already on this branch's old v2 base, one added on main),
which surfaced as a spurious test failure. Restored main's single copy.

Verified: pnpm build, pnpm check, and the full unit test suite
(pnpm -r run test --project 'unit*') all pass.

# Conflicts:
#	.changeset/pre.json
#	.changeset/seed-upsert-flag.md
#	.changeset/v2-baseline.md
#	llm-challenge/package.json
#	packages/create-sdk/CHANGELOG.md
#	packages/create-sdk/package.json
#	packages/eslint-plugin-sdk/CHANGELOG.md
#	packages/eslint-plugin-sdk/package.json
#	packages/sdk-codemod/CHANGELOG.md
#	packages/sdk-codemod/package.json
#	packages/sdk-codemod/src/registry.ts
#	packages/sdk-plugin-seed/CHANGELOG.md
#	packages/sdk-plugin-seed/package.json
#	packages/sdk-plugin-seed/tsconfig.json
#	packages/sdk-plugin-seed/vitest.config.ts
#	packages/sdk-plugin-tailordb-erd/CHANGELOG.md
#	packages/sdk-plugin-tailordb-erd/README.md
#	packages/sdk-plugin-tailordb-erd/package.json
#	packages/sdk/CHANGELOG.md
#	packages/sdk/docs/cli/tailordb.md
#	packages/sdk/docs/cli/tailordb.template.md
#	packages/sdk/docs/configuration.md
#	packages/sdk/docs/github-actions.md
#	packages/sdk/docs/migration/v2.md
#	packages/sdk/docs/services/executor.md
#	packages/sdk/docs/services/idp.md
#	packages/sdk/docs/services/resolver.md
#	packages/sdk/docs/services/tailordb-migration.md
#	packages/sdk/docs/services/tailordb.md
#	packages/sdk/package.json
#	packages/sdk/src/cli/commands/deploy/application.ts
#	packages/sdk/src/cli/commands/deploy/idp.plan.test.ts
#	packages/sdk/src/cli/commands/deploy/idp.ts
#	packages/sdk/src/cli/commands/deploy/label.test.ts
#	packages/sdk/src/cli/commands/deploy/label.ts
#	packages/sdk/src/cli/commands/deploy/resolver.ts
#	packages/sdk/src/cli/commands/deploy/tailordb/index.ts
#	packages/sdk/src/cli/commands/deploy/tailordb/migration.ts
#	packages/sdk/src/cli/commands/deploy/workflow.ts
#	packages/sdk/src/cli/commands/tailordb/migrate/set.ts
#	packages/sdk/src/cli/commands/tailordb/migrate/snapshot-manifest.ts
#	packages/sdk/src/cli/commands/tailordb/migrate/status.ts
#	packages/sdk/src/cli/commands/tailordb/migrate/sync.ts
#	pnpm-lock.yaml
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

🗺️ ERD preview

No relevant ERD changes in this update.

@github-actions

This comment has been minimized.

The merge into main resurrected ~97 changeset files that were part of
v2's history but had already been consumed by main's changeset-release
process (two "Version Packages" commits, one right after the v2 merge
and one since). Non-conflicting deletions like these should apply
cleanly in a 3-way merge, but this branch's criss-cross history with
main (repeated "Merge origin/main into v2" commits) appears to have
confused the merge-base computation for this directory. Delete them;
`npx changeset status` now only reports the 3 changesets this branch
actually owns.
@github-actions

This comment has been minimized.

Same class of issue as the changeset cleanup: main already dropped v2
from this workflow's push trigger (and updated the matching test
assertion) ahead of the v2 merge, but this branch's criss-cross history
with main resurrected the old "branches: [main, v2]" / matching test
expectation. Restore both from main.
@github-actions

This comment has been minimized.

seed-upsert-idp-user-fixes.md and seed-upsert-migration-doc.md
described idp-user-processor.ts, apply.ts, README.md, and registry.ts
changes from the earlier v2-branch work — all already merged and
present on main, none of them part of this branch's actual diff. Only
seed-apply-e2e-coverage.md (the e2e test addition this PR introduces)
belongs here.
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

Code Metrics Report (packages/sdk)

main (4af8a70) #1941 (583675d) +/-
Coverage 78.5% 78.5% +0.0%
Code to Test Ratio 1:0.4 1:0.4 0.0
Details
  |                    | main (4af8a70) | #1941 (583675d) |  +/-  |
  |--------------------|----------------|-----------------|-------|
+ | Coverage           |          78.5% |           78.5% | +0.0% |
  |   Files            |            462 |             462 |     0 |
  |   Lines            |          17731 |           17731 |     0 |
+ |   Covered          |          13920 |           13922 |    +2 |
  | Code to Test Ratio |          1:0.4 |           1:0.4 |   0.0 |
  |   Code             |         126565 |          126565 |     0 |
  |   Test             |          61876 |           61876 |     0 |

Code coverage of files in pull request scope (72.8% → 75.0%)

Files Coverage +/- Status
packages/sdk/src/cli/commands/workflow/waiter.ts 75.0% +2.1% affected

SDK Configure Bundle Size

main (4af8a70) #1941 (583675d) +/-
configure-index-size 39.25KB 39.25KB 0KB
dependency-chunks-size 24.96KB 24.96KB 0KB
total-bundle-size 64.22KB 64.22KB 0KB

Runtime Performance

main (4af8a70) #1941 (583675d) +/-
Generate Median 2,304ms 2,443ms 139ms
Generate Max 2,342ms 2,460ms 118ms
Apply Build Median 2,355ms 2,514ms 159ms
Apply Build Max 2,382ms 2,560ms 178ms

Type Performance (instantiations)

main (4af8a70) #1941 (583675d) +/-
tailordb-basic 40,450 40,450 0
tailordb-optional 4,535 4,535 0
tailordb-relation 3,854 3,854 0
tailordb-validate 666 666 0
tailordb-hooks 5,499 5,499 0
tailordb-object 16,345 16,345 0
tailordb-enum 1,538 1,538 0
resolver-basic 12,120 12,120 0
resolver-nested 35,419 35,419 0
resolver-array 24,056 24,056 0
executor-schedule 4,489 4,489 0
executor-webhook 1,130 1,130 0
executor-record 4,542 4,542 0
executor-resolver 5,808 5,808 0
executor-operation-function 1,118 1,118 0
executor-operation-gql 1,126 1,126 0
executor-operation-webhook 1,137 1,137 0
executor-operation-workflow 1,931 1,931 0

Reported by octocov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants