Skip to content

feat(sdk): add workflowMock.setEnv() and deprecate WORKFLOW_TEST_ENV_KEY#1186

Draft
toiroakr wants to merge 6 commits into
mainfrom
fix/workflow-mock
Draft

feat(sdk): add workflowMock.setEnv() and deprecate WORKFLOW_TEST_ENV_KEY#1186
toiroakr wants to merge 6 commits into
mainfrom
fix/workflow-mock

Conversation

@toiroakr
Copy link
Copy Markdown
Contributor

Summary

  • Add workflowMock.setEnv() so tests using the tailor-runtime Vitest environment can configure the env passed to job bodies through the same helper used for setJobHandler / setWaitHandler — without touching process.env.
  • .trigger() now reads env from a globalThis key written by workflowMock.setEnv(), falling back to process.env[WORKFLOW_TEST_ENV_KEY] when the global is unset.
  • Mark WORKFLOW_TEST_ENV_KEY (TAILOR_TEST_WORKFLOW_ENV) as @deprecated; the export and env-var path remain supported for backwards compatibility. workflowMock.setEnv() takes priority when both are set.
  • Update packages/create-sdk workflow template (order-fulfillment.test.ts, README) to demonstrate the new helper instead of vi.stubEnv(WORKFLOW_TEST_ENV_KEY, ...).
  • Update packages/sdk/docs/testing.md accordingly.

Motivation

workflowMock is the canonical entry point for mocking workflow behavior in tests. Routing the env injection through it (instead of a magic env var) removes the only env-var-based mock in the SDK, makes the API discoverable alongside the rest of workflowMock, and lets tests scope env state via workflowMock.reset() between cases.

A longer-term plan to fully align local .trigger() semantics with the platform's tailor.workflow.triggerJobFunction() is tracked separately; this PR is the incremental step that ships now while preserving the existing public API.

Compatibility

Non-breaking. Existing tests using vi.stubEnv(WORKFLOW_TEST_ENV_KEY, ...) continue to work via the fallback path.

Adds workflowMock.setEnv() so tests using the tailor-runtime Vitest
environment can configure the env passed to job bodies through the
same helper they use for setJobHandler / setWaitHandler — without
touching process.env.

The legacy WORKFLOW_TEST_ENV_KEY (TAILOR_TEST_WORKFLOW_ENV) env-var
path remains supported as a fallback; the export is now marked
@deprecated. workflowMock.setEnv() takes priority when both are set.
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 18, 2026

🦋 Changeset detected

Latest commit: 3c35a3c

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

This PR includes changesets to release 2 packages
Name Type
@tailor-platform/sdk Minor
@tailor-platform/create-sdk Minor

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

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 18, 2026

⚡ pkg.pr.new

@tailor-platform/sdk

pnpm add https://pkg.pr.new/@tailor-platform/sdk@3c35a3c
pnpm dlx https://pkg.pr.new/@tailor-platform/sdk@3c35a3c --help

@tailor-platform/create-sdk

pnpm add https://pkg.pr.new/@tailor-platform/create-sdk@3c35a3c
pnpm dlx https://pkg.pr.new/@tailor-platform/create-sdk@3c35a3c my-app

commit: 3c35a3c

@github-actions

This comment has been minimized.

Self-review revealed two gaps:
- mock.test.ts did not verify that workflowMock.setEnv() wins over
  vi.stubEnv(WORKFLOW_TEST_ENV_KEY, ...), or that the deprecated env-var
  path still works when setEnv is not called.
- The workflow template's integration test exercised .trigger() but
  never called workflowMock.setEnv() / workflowMock.reset(), so it did
  not demonstrate the new helper.

Add two mock.test.ts cases for the priority/fallback contract, and
update the template to call workflowMock.reset() in beforeEach and
workflowMock.setEnv({ STAGE: 'test' }) in the integration test.
@github-actions

This comment has been minimized.

This comment was marked as outdated.

Match the docs decision (testing.md does not mention WORKFLOW_TEST_ENV_KEY
either): the changeset still records the deprecation, but no longer names
the legacy export. Users who relied on the env var will see the
@deprecated JSDoc warning at the import site.
@github-actions

This comment has been minimized.

This comment was marked as outdated.

- Shallow-copy global env in trigger() so job bodies cannot mutate the source object across triggers, matching the env-var path which returns a fresh object from JSON.parse each call.
- Tighten workflowMock.setEnv() parameter from Record<string, unknown> to TailorEnv to match the value type job bodies receive in their context.
- Add afterEach(vi.unstubAllEnvs) to workflowMock describe block so a failing test cannot leak env stubs into subsequent tests.
- Add drift-guard test asserting WORKFLOW_ENV_GLOBAL_KEY is identical between configure/job.ts and vitest/mock.ts. mock.ts must remain free of @/-alias imports because nested Vitest configs for integration tests do not resolve them, so the constant is re-declared instead of imported.
- Reword testing.md "without any mocking" to "with real job bodies" since workflowMock.setEnv() is itself a mock helper.
@github-actions

This comment has been minimized.

This comment was marked as outdated.

Address Copilot review on #1186:

- Validate fromGlobal is a non-null object before spreading. A non-object value
  (string, number, etc.) accidentally assigned to the global key now falls back
  to the env-var path instead of producing a surprising env shape.
- Update WORKFLOW_ENV_GLOBAL_KEY JSDoc to accurately describe the duplicate
  declaration in src/vitest/mock.ts (it's re-declared, not re-exported, because
  the nested tailor-runtime Vitest config does not resolve @/ aliases), and
  point readers at the drift-guard test.
- Add a regression test exercising the non-object fallback path.
@github-actions

This comment has been minimized.

This comment was marked as outdated.

Address Copilot review on #1186: the previous comment said the fallback
path was used for "non-plain-object" values, but the runtime check
(typeof === "object" && !== null) actually accepts arrays, class
instances, etc. Rewrite the comment to describe what the check really
does (reject null and non-object primitives) and note that
non-plain-object cases can only arise from direct globalThis misuse,
since the setEnv() type constrains callers to TailorEnv.

No behavior change.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@github-actions
Copy link
Copy Markdown

Code Metrics Report (packages/sdk)

main (d3d984f) #1186 (b31316f) +/-
Coverage 61.9% 61.9% +0.0%
Code to Test Ratio 1:0.4 1:0.4 +0.0
Details
  |                    | main (d3d984f) | #1186 (b31316f) |  +/-  |
  |--------------------|----------------|-----------------|-------|
+ | Coverage           |          61.9% |           61.9% | +0.0% |
  |   Files            |            363 |             363 |     0 |
  |   Lines            |          12651 |           12657 |    +6 |
+ |   Covered          |           7833 |            7840 |    +7 |
+ | Code to Test Ratio |          1:0.4 |           1:0.4 |  +0.0 |
  |   Code             |          82915 |           82992 |   +77 |
+ |   Test             |          34645 |           34709 |   +64 |

Code coverage of files in pull request scope (87.7% → 88.4%)

Files Coverage +/- Status
packages/sdk/src/configure/services/workflow/job.ts 100.0% +16.6% modified
packages/sdk/src/vitest/mock.ts 88.0% +0.2% modified

SDK Configure Bundle Size

main (d3d984f) #1186 (b31316f) +/-
configure-index-size 17KB 17.05KB 0.05KB
dependency-chunks-size 34.43KB 35.41KB 0.98KB
total-bundle-size 51.43KB 52.46KB 1.03KB

Runtime Performance

main (d3d984f) #1186 (b31316f) +/-
Generate Median 3,036ms 2,947ms -89ms
Generate Max 3,076ms 3,030ms -46ms
Apply Build Median 3,077ms 2,982ms -95ms
Apply Build Max 3,126ms 3,020ms -106ms

Type Performance (instantiations)

main (d3d984f) #1186 (b31316f) +/-
tailordb-basic 35,130 35,131 1
tailordb-optional 3,841 3,841 0
tailordb-relation 7,428 7,428 0
tailordb-validate 2,566 2,566 0
tailordb-hooks 5,767 5,767 0
tailordb-object 12,136 12,136 0
tailordb-enum 2,462 2,462 0
resolver-basic 9,424 9,424 0
resolver-nested 26,111 26,111 0
resolver-array 18,187 18,187 0
executor-schedule 4,234 4,234 0
executor-webhook 873 873 0
executor-record 8,166 8,166 0
executor-resolver 4,369 4,369 0
executor-operation-function 869 869 0
executor-operation-gql 869 869 0
executor-operation-webhook 888 888 0
executor-operation-workflow 1,714 1,714 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