feat(seed): run PostGenerationPipeline.VerificationStep for TS SDK fixtures#15845
Conversation
When the TypeScript SDK generator emits .fern/verify.sh alongside generated code (PR #15718), the seed runner now prefers that script over the duplicate build/test commands in seed/ts-sdk/seed.yml. This exercises the same install/build/test contract as 'fern generate --local --verify' on every seed CI run. Detection is file-presence based, so: - ts-sdk fixtures naturally use verify.sh (only generator emitting it today) - Other generators fall back to seed.yml commands unchanged (FER-9681) - Missing verify.sh in any fixture falls back to seed.yml (defensive) The split between the generation semaphore and the separate script container pool is preserved. FER-10455 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
Reviewed FER-10455. The approach is clean — resolveScriptPhaseCommands correctly encapsulates the verify.sh detection logic, the old getCommandsForPhase duplication across both script runners is eliminated, and the fallback semantics (verify.sh absent -> legacy seed.yml commands) are exactly right for the cross-generator story. The delta table in the PR description (frozen-lockfile / unconditional pnpm build / test / no package.json guard) is the right framing — these gaps should surface as CI failures and get fixed in the generator, not papered over. The YAML comment on the seed.yml fallback block is a nice touch for future FER-9681 cleanup. Unit test coverage (9 cases, both branches for legacy list and phase-map shapes) is complete. CI 32/32 green. Flipping ready. |
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.
Tip: disable this comment in your organization's Code Review settings.
Docs Generation Benchmark ResultsComparing PR branch against median of 5 nightly run(s) on
Docs generation runs |
SDK Generation Benchmark ResultsComparing PR branch against median of 5 nightly run(s) on Full benchmark table (click to expand)
main (generator): generator-only time via --skip-scripts (includes Docker image build, container startup, IR parsing, and code generation — this is the same Docker-based flow customers use via |
…K fixtures Replaces the direct `bash .fern/verify.sh` invocation in the seed script runner with the canonical PostGenerationPipeline + VerificationStep flow that `fern generate --local --verify` and Fiddle use in production. - Adds `verify` / `verifyRunner` / `verifyValidatorVersion` to GenerationRunner.RunArgs and instantiates PostGenerationPipeline with only VerificationStep enabled after the generator finishes writing files. Mirrors the verifyOnlyPipelineEnabled branch in runLocalGenerationForWorkspace. - LocalTestRunner and ContainerTestRunner now pass `verify: true` only for generators that emit `.fern/verify.sh` (today: `fernapi/fern-typescript-sdk` + the `fern-typescript-node-sdk` alias). The new `generatorEmitsVerifyScript` helper centralises this allow-list so we can extend it as FER-9681 lands additional language SDKs. - TestRunner.run skips the seed.yml `scripts` block for those generators since the pipeline-driven VerificationStep is the canonical replacement. The block stays in seed.yml as a fallback for any non-TS generator and as the build/test recipe consumed by external tooling. - Validator image tag override: seed runs the generator at the `:local` tag, but no `:local` validator image is built today. Passing `verifyValidatorVersion: "latest"` makes VerificationStep pull the published `fernapi/fern-typescript-sdk-validator:latest` \u2014 the closest analog to what a customer sees from `fern generate --local --verify` against a published generator. - Removes the temporary `resolveScriptPhaseCommands` helper and its unit tests, and reverts the corresponding edits in ContainerScriptRunner / LocalScriptRunner / seed/ts-sdk/seed.yml. Seed CI now exercises the same validator-container code path customers hit. Refs FER-10455. FER-9681 tracks extending self-verification to the remaining language SDK generators.
Extract assertVerifyPipelineSucceeded into its own module so it can be unit-tested in isolation. Key the failure check off pipelineResult.success (canonical signal) rather than steps.verify.success, which only catches the verify-step-returned-failure branch — the orchestrator silently leaves steps.verify unset when the step throws before recording a result (e.g. validator image fails to pull, container fails to start), so the previous shape would silently no-op on those failures. Detail message preference: validator stderr > pipelineResult.errors > step errorMessage > generic fallback. Adds assertVerifyPipelineSucceeded.test.ts (7 cases: happy path, verify.sh absent, validator-stderr failure, no-result-recorded failure, errorMessage fallback, generic fallback, validator-stderr-vs-errors precedence). Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…xtures (#15845) * feat(seed): use generator-emitted verify.sh for ts-sdk fixtures When the TypeScript SDK generator emits .fern/verify.sh alongside generated code (PR #15718), the seed runner now prefers that script over the duplicate build/test commands in seed/ts-sdk/seed.yml. This exercises the same install/build/test contract as 'fern generate --local --verify' on every seed CI run. Detection is file-presence based, so: - ts-sdk fixtures naturally use verify.sh (only generator emitting it today) - Other generators fall back to seed.yml commands unchanged (FER-9681) - Missing verify.sh in any fixture falls back to seed.yml (defensive) The split between the generation semaphore and the separate script container pool is preserved. FER-10455 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(seed): run PostGenerationPipeline.VerificationStep for TS SDK fixtures Replaces the direct `bash .fern/verify.sh` invocation in the seed script runner with the canonical PostGenerationPipeline + VerificationStep flow that `fern generate --local --verify` and Fiddle use in production. - Adds `verify` / `verifyRunner` / `verifyValidatorVersion` to GenerationRunner.RunArgs and instantiates PostGenerationPipeline with only VerificationStep enabled after the generator finishes writing files. Mirrors the verifyOnlyPipelineEnabled branch in runLocalGenerationForWorkspace. - LocalTestRunner and ContainerTestRunner now pass `verify: true` only for generators that emit `.fern/verify.sh` (today: `fernapi/fern-typescript-sdk` + the `fern-typescript-node-sdk` alias). The new `generatorEmitsVerifyScript` helper centralises this allow-list so we can extend it as FER-9681 lands additional language SDKs. - TestRunner.run skips the seed.yml `scripts` block for those generators since the pipeline-driven VerificationStep is the canonical replacement. The block stays in seed.yml as a fallback for any non-TS generator and as the build/test recipe consumed by external tooling. - Validator image tag override: seed runs the generator at the `:local` tag, but no `:local` validator image is built today. Passing `verifyValidatorVersion: "latest"` makes VerificationStep pull the published `fernapi/fern-typescript-sdk-validator:latest` \u2014 the closest analog to what a customer sees from `fern generate --local --verify` against a published generator. - Removes the temporary `resolveScriptPhaseCommands` helper and its unit tests, and reverts the corresponding edits in ContainerScriptRunner / LocalScriptRunner / seed/ts-sdk/seed.yml. Seed CI now exercises the same validator-container code path customers hit. Refs FER-10455. FER-9681 tracks extending self-verification to the remaining language SDK generators. * refactor(seed): harden verify pipeline failure handling + unit-test it Extract assertVerifyPipelineSucceeded into its own module so it can be unit-tested in isolation. Key the failure check off pipelineResult.success (canonical signal) rather than steps.verify.success, which only catches the verify-step-returned-failure branch — the orchestrator silently leaves steps.verify unset when the step throws before recording a result (e.g. validator image fails to pull, container fails to start), so the previous shape would silently no-op on those failures. Detail message preference: validator stderr > pipelineResult.errors > step errorMessage > generic fallback. Adds assertVerifyPipelineSucceeded.test.ts (7 cases: happy path, verify.sh absent, validator-stderr failure, no-result-recorded failure, errorMessage fallback, generic fallback, validator-stderr-vs-errors precedence). Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…xtures (#15845) * feat(seed): use generator-emitted verify.sh for ts-sdk fixtures When the TypeScript SDK generator emits .fern/verify.sh alongside generated code (PR #15718), the seed runner now prefers that script over the duplicate build/test commands in seed/ts-sdk/seed.yml. This exercises the same install/build/test contract as 'fern generate --local --verify' on every seed CI run. Detection is file-presence based, so: - ts-sdk fixtures naturally use verify.sh (only generator emitting it today) - Other generators fall back to seed.yml commands unchanged (FER-9681) - Missing verify.sh in any fixture falls back to seed.yml (defensive) The split between the generation semaphore and the separate script container pool is preserved. FER-10455 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(seed): run PostGenerationPipeline.VerificationStep for TS SDK fixtures Replaces the direct `bash .fern/verify.sh` invocation in the seed script runner with the canonical PostGenerationPipeline + VerificationStep flow that `fern generate --local --verify` and Fiddle use in production. - Adds `verify` / `verifyRunner` / `verifyValidatorVersion` to GenerationRunner.RunArgs and instantiates PostGenerationPipeline with only VerificationStep enabled after the generator finishes writing files. Mirrors the verifyOnlyPipelineEnabled branch in runLocalGenerationForWorkspace. - LocalTestRunner and ContainerTestRunner now pass `verify: true` only for generators that emit `.fern/verify.sh` (today: `fernapi/fern-typescript-sdk` + the `fern-typescript-node-sdk` alias). The new `generatorEmitsVerifyScript` helper centralises this allow-list so we can extend it as FER-9681 lands additional language SDKs. - TestRunner.run skips the seed.yml `scripts` block for those generators since the pipeline-driven VerificationStep is the canonical replacement. The block stays in seed.yml as a fallback for any non-TS generator and as the build/test recipe consumed by external tooling. - Validator image tag override: seed runs the generator at the `:local` tag, but no `:local` validator image is built today. Passing `verifyValidatorVersion: "latest"` makes VerificationStep pull the published `fernapi/fern-typescript-sdk-validator:latest` \u2014 the closest analog to what a customer sees from `fern generate --local --verify` against a published generator. - Removes the temporary `resolveScriptPhaseCommands` helper and its unit tests, and reverts the corresponding edits in ContainerScriptRunner / LocalScriptRunner / seed/ts-sdk/seed.yml. Seed CI now exercises the same validator-container code path customers hit. Refs FER-10455. FER-9681 tracks extending self-verification to the remaining language SDK generators. * refactor(seed): harden verify pipeline failure handling + unit-test it Extract assertVerifyPipelineSucceeded into its own module so it can be unit-tested in isolation. Key the failure check off pipelineResult.success (canonical signal) rather than steps.verify.success, which only catches the verify-step-returned-failure branch — the orchestrator silently leaves steps.verify unset when the step throws before recording a result (e.g. validator image fails to pull, container fails to start), so the previous shape would silently no-op on those failures. Detail message preference: validator stderr > pipelineResult.errors > step errorMessage > generic fallback. Adds assertVerifyPipelineSucceeded.test.ts (7 cases: happy path, verify.sh absent, validator-stderr failure, no-result-recorded failure, errorMessage fallback, generic fallback, validator-stderr-vs-errors precedence). Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
What
Threads
verify: truethroughrunLocalGenerationForWorkspacefor the TypeScript SDK generator, so seed CI exercises the sameverify.shflow customers hit onfern generate --local --verifyand on the Fiddle (remote) path.Refs FER-10455. TS-only — every other generator continues through the existing seed-script-runner path with zero behavior change. FER-9681 will add the rest as each generator's
.fern/verify.shlands.Why this shape (the design choice)
Previously, seed had its own
bash .fern/verify.shreimplementation that bypassedgenerator-cli'sVerificationStep— no validator container, no exit-code handling, no parity with what customers run. This PR deletes that parallel path and drives the canonicalPostGenerationPipeline.VerificationStepinstead, gated by a small allow-list of generators that emitverify.shtoday (justfernapi/fern-typescript-sdk+ its node-sdk alias).The intent matches what Niels asked for in this Slack thread: exercise the TS verification plumbing harder before expanding to the other 7 languages.
Testing
assertVerifyPipelineSucceeded.test.ts(7 cases — happy path, verify.sh absent, validator stderr failure, pipeline-failure-with-no-step-result, errorMessage fallback, generic fallback, precedence)pnpm turbo run test --filter @fern-api/local-workspace-runner --filter @fern-api/seed-cli— green locally (79/79 tasks)pnpm check(Biome) — greenseed-test-results (ts-sdk)is SUCCESSb7443258One note for review
Seed runs the generator at
:local(Docker tag of the current checkout), but no:localvalidator image is built — so seed tests run against publishedfernapi/fern-typescript-sdk-validator:latestrather than the local checkout. This mirrors what a realfern generate --local --verifyuser against a published generator sees. Trade-off: validator-image changes in a given PR aren't exercised by seed CI in that same PR. Those are covered separately bygenerator-cli'sverification-step.test.tsintegration tests.Diff map (file-by-file)
packages/cli/generation/local-generation/local-workspace-runner/src/GenerationRunner.ts—RunArgsgainsverify,verifyRunner,verifyValidatorVersion. Whenverify === true, afterexecuteGeneratorwrites files,GenerationRunner.runinstantiatesPostGenerationPipelinewith onlyVerificationStepenabled — same shape as theverifyOnlyPipelineEnabledbranch inrunLocalGenerationForWorkspace.packages/cli/generation/local-generation/local-workspace-runner/src/assertVerifyPipelineSucceeded.ts(new) — inspects the pipeline result and throws anInternalErrorCliErrorwhenpipelineResult.success === false. Keys offpipelineResult.success(not juststeps.verify.success) so failures whereVerificationStepthrows before recording a result (e.g. validator image fails to pull) still surface. Detail-message preference: validator stderr → accumulated pipeline errors → steperrorMessage→ generic fallback.packages/seed/src/utils/generatorEmitsVerifyScript.ts(new) — allow-list helper. Today:fernapi/fern-typescript-sdk+fern-typescript-node-sdkalias.packages/seed/src/commands/test/test-runner/LocalTestRunner.tsandContainerTestRunner.ts— consult the allow-list and passverify: trueonly for TS SDK; everything else unchanged.packages/seed/src/commands/test/test-runner/TestRunner.ts— skips theseed.ymlscriptsblock for allow-list generators (VerificationStepis the canonical replacement). Block stays inseed.ymlas fallback for every other generator.packages/seed/src/utils/resolveScriptPhaseCommands.ts+ its unit tests; reverted edits inContainerScriptRunner.ts,LocalScriptRunner.ts, comment inseed/ts-sdk/seed.yml.packages/cli/cli/changes/unreleased/seed-verify-pipeline.yml— CLI changelog entry (type: internal).Devin session
Link: https://app.devin.ai/sessions/bdd66d2adeec4acc826dce1b86476c9b
Requested by: @jsklan