Skip to content

feat: add workos migrations command#149

Merged
nicknisi merged 6 commits into
mainfrom
nicknisi/migrations
May 13, 2026
Merged

feat: add workos migrations command#149
nicknisi merged 6 commits into
mainfrom
nicknisi/migrations

Conversation

@nicknisi
Copy link
Copy Markdown
Member

@nicknisi nicknisi commented May 13, 2026

Summary

  • Adds a workos migrations top-level command that wraps the standalone @workos/migrations CLI via programmatic import
  • Bridges auth automatically: resolves API key from the main CLI's keyring/stored environments and injects it as WORKOS_SECRET_KEY
  • Registers all 12 migration subcommands (import, validate, export-auth0, wizard, etc.) in the help-json registry
  • Filters WorkOS-only global flags before delegating so --mode agent/--mode=ci, --api-key, --insecure-storage, and --json do not leak into Commander args
  • Handles the edge case where a WorkOS-only flag value is literally migrations without treating that value as the command boundary
  • Bumps Node engine to >=22.11 to match @workos/migrations requirement

Review & Testing Checklist for Human

  • Verify workos migrations --help shows Commander help output for the wrapped migrations CLI
  • Verify workos migrations import --csv <file> --mode agent --api-key <key> delegates without Commander rejecting --mode or the key value
  • Verify workos --help --json includes migrations in the commands array

Notes

Validated locally with:

  • pnpm install --frozen-lockfile
  • pnpm test -- src/commands/migrations.spec.ts (Vitest ran full suite: 1795/1795 passing)
  • pnpm lint
  • pnpm format:check
  • pnpm typecheck
  • pnpm build
  • Manual built CLI smoke tests for global flag stripping and migrations validation delegation

Link to Devin session: https://app.devin.ai/sessions/f300e72a5caa41b49efb4d4311c0895a
Requested by: @nicknisi

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

📝 Walkthrough

Walkthrough

This PR adds a new top-level migrations CLI command that integrates the @workos/migrations package, forwards passthrough arguments to the migrations CLI (after stripping WorkOS-only flags), sets WORKOS_SECRET_KEY from an --api-key, and updates package dependencies and Node.js engine requirement to >=22.11.

Changes

Migrations Command Feature

Layer / File(s) Summary
Dependencies and engine requirements
package.json
@workos/migrations added to dependencies at ^2.0.0; engines.node updated to >=22.11.
Core implementation and tests
src/commands/migrations.ts, src/commands/migrations.spec.ts
Adds getMigrationsPassthroughArgs (filters WorkOS-only flags) and runMigrations (sets WORKOS_SECRET_KEY, dynamically imports migrations CLI, calls program.parseAsync(args, { from: 'user' })). Tests cover env assignment, argument forwarding, empty-arg handling, and removal of global flags (tokenized and = forms).
CLI command registration and argument handling
src/bin.ts
Refactors middleware exclusion list and registers a migrations yargs subcommand with help/version/strictness disabled; supports --insecure-storage and --api-key, applies insecure storage, resolves API key, computes passthrough args, and calls runMigrations.
Help documentation registry
src/utils/help-json.ts
Adds a migrations entry to the machine-readable help JSON with insecure-storage/api-key options and multiple migration subcommands (import, import-package, validate, export variants, transforms/merge, analysis, enroll-totp, process-role-definitions, wizard).
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add workos migrations command' directly and clearly describes the main change: adding a new top-level migrations command to the WorkOS CLI.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch nicknisi/migrations

Comment @coderabbitai help to get the list of available commands and usage tips.

nicknisi added 4 commits May 13, 2026 10:06
Programmatically imports the Commander program from workos-migrations
and delegates all arg parsing/execution to it. Auth is bridged
automatically by injecting the resolved API key as WORKOS_SECRET_KEY.

- Register `migrations` top-level command with strict(false) passthrough
- Strip --api-key, --insecure-storage, --json from forwarded args
- Add all 12 migration subcommands to help-json registry
- Link workos-migrations as local dependency
- Bump Node engine to >=22.11 (required by workos-migrations)
Disable yargs help/version interception for the migrations command
so Commander's native help output is shown instead.
Without this, Commander's help displays `Usage: workos-migrate`
which would mislead users into thinking that's the command.
Replace local link with published @workos/migrations@^2.0.0 package.
Update all import paths from workos-migrations/ to @workos/migrations/.
Remove pnpm-workspace.yaml that was only needed for the local link.
@nicknisi nicknisi force-pushed the nicknisi/migrations branch from 3c12454 to bdbcd16 Compare May 13, 2026 15:06
@nicknisi nicknisi marked this pull request as ready for review May 13, 2026 15:09
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 13, 2026

Greptile Summary

This PR adds a workos migrations top-level command that wraps the @workos/migrations standalone CLI via programmatic import, auto-bridging auth by injecting WORKOS_SECRET_KEY from the CLI's keyring. The Node.js engine requirement is bumped from >=20.20 to >=22.11 to match the migrations package's runtime requirement.

  • src/commands/migrations.ts: Implements getMigrationsPassthroughArgs (strips WorkOS-only global flags before delegating) and runMigrations (injects WORKOS_SECRET_KEY, then delegates to the Commander-based migrations CLI via a deep dist/cli/index.js import).
  • src/bin.ts: Registers the migrations yargs command with strictCommands(false).strict(false).help(false).version(false) so all Commander-handled tokens pass through unmodified.
  • src/utils/help-json.ts: Adds all 12 migrations subcommands to the machine-readable command registry for --help --json output.

Confidence Score: 5/5

Safe to merge; the passthrough arg-filtering logic is correct, tests cover all significant edge cases, and the auth bridge is implemented consistently with the rest of the CLI.

The flag-stripping logic in getMigrationsPassthroughArgs correctly handles inline-value flags (--mode=ci), space-separated flags (--mode agent), and ambiguous tokens (migrations as a flag value vs. command). Tests enumerate all these cases. The auth injection pattern and the yargs passthrough setup are consistent with the stated intent. Previously noted concerns around the deep dist/ import and silent --json stripping are known design trade-offs already discussed.

No files require special attention beyond the previously-discussed deep-import coupling in src/commands/migrations.ts.

Important Files Changed

Filename Overview
src/commands/migrations.ts Core migration command: injects WORKOS_SECRET_KEY and delegates to @workos/migrations via a deep dist/ import; flag-stripping logic is correct for all tested cases.
src/commands/migrations.spec.ts Tests cover env injection, passthrough delegation, and all edge cases for WorkOS flag stripping; mocks the deep import correctly.
src/bin.ts Registers the migrations yargs command with passthrough-friendly options; consistent with existing command patterns.
src/utils/help-json.ts Adds all 12 migrations subcommands to the static command registry; correctly mirrors the bin.ts definition.
package.json Adds @workos/migrations dependency and bumps Node engine requirement from >=20.20 to >=22.11 to match the migrations package's constraint.

Reviews (3): Last reviewed commit: "fix: handle migrations flag value edge c..." | Re-trigger Greptile

Comment thread src/bin.ts Outdated
export async function runMigrations(args: string[], apiKey: string): Promise<void> {
process.env.WORKOS_SECRET_KEY = apiKey;

const { program } = (await import('@workos/migrations/dist/cli/index.js')) as {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Deep import into @workos/migrations internals

The import path @workos/migrations/dist/cli/index.js reaches into the package's compiled dist directory rather than using a declared subpath export. If the migrations package reorganizes its build output (e.g., renames the entry file or switches to an exports map that restricts deep imports), this will throw a module-not-found error at runtime. Consider requesting the package expose a named subpath export like @workos/migrations/cli to avoid coupling to the build artifact layout.

Comment thread src/commands/migrations.ts
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 potential issues.

View 3 additional findings in Devin Review.

Open in Devin Review

Comment thread src/bin.ts Outdated
const { runMigrations } = await import('./commands/migrations.js');
const migrationsIdx = rawArgs.indexOf('migrations');
const passthrough: string[] = [];
const skip = new Set(['--insecure-storage', '--json', '--api-key']);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Global --mode flag leaks into migrations passthrough args

The passthrough filter skip set at src/bin.ts:2414 only includes ['--insecure-storage', '--json', '--api-key'] but omits the global --mode option (defined at src/bin.ts:207-211 as a string type taking values human, agent, or ci). When a user places --mode after the migrations keyword (e.g. workos migrations import --csv users.csv --mode agent), both --mode and its value (e.g. agent) are passed through to the Commander-based @workos/migrations CLI, which doesn't recognize them and will error. The --api-key skip correctly handles its value argument, but --mode isn't handled at all.

Suggested change
const skip = new Set(['--insecure-storage', '--json', '--api-key']);
const skip = new Set(['--insecure-storage', '--json', '--api-key', '--mode']);
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread src/bin.ts Outdated
Comment on lines +2419 to +2421
if (skip.has(key)) {
if (key === '--api-key' && !arg.includes('=')) i++;
continue;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Passthrough filter only skips value for --api-key, but --mode also takes a value argument

Even after adding --mode to the skip set, the value-skipping logic at src/bin.ts:2420 only handles --api-key specifically: if (key === '--api-key' && !arg.includes('=')) i++. For --mode agent (without =), only --mode would be skipped but agent would still be pushed to passthrough, corrupting the arguments sent to the migrations CLI. Any string-typed global flag added to the skip set needs its value skipped when passed in --flag value form (not just --flag=value).

Suggested change
if (skip.has(key)) {
if (key === '--api-key' && !arg.includes('=')) i++;
continue;
if ((key === '--api-key' || key === '--mode') && !arg.includes('=')) i++;
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@nicknisi nicknisi merged commit 7f5138f into main May 13, 2026
9 checks passed
@nicknisi nicknisi deleted the nicknisi/migrations branch May 13, 2026 22:45
@coderabbitai coderabbitai Bot mentioned this pull request May 13, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant