Skip to content

[Blueprints] Compile Blueprint v2 declarations into an execution plan - #3908

Merged
adamziel merged 1 commit into
trunkfrom
compile-blueprint-v2-execution-plan
Jul 4, 2026
Merged

[Blueprints] Compile Blueprint v2 declarations into an execution plan#3908
adamziel merged 1 commit into
trunkfrom
compile-blueprint-v2-execution-plan

Conversation

@adamziel

@adamziel adamziel commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

What it does

Extracts the compile-only part of the native TypeScript Blueprint v2 runner work from #3725. compileBlueprintV2() now turns a parsed v2 declaration into a typed BlueprintV2ExecutionPlan while preserving runtime metadata and applicationOptions.

The plan records the ordered work implied by v2 fields such as constants, siteOptions, muPlugins, themes, activeTheme, plugins, fonts, media, siteLanguage, roles, users, postTypes, content, and additionalStepsAfterExecution.

Rationale

This lets us review the v2 parser/compiler shape separately from execution. The current PR does not resolve resources, lower v2 data references into v1 resources, call v1 step handlers, or wire the plan into existing consumer data flows.

Non-empty v2 plans still fail at run() with an explicit UnsupportedBlueprintV2FeatureError, so callers cannot accidentally treat parsed-but-unwired v2 declarations as executed.

Implementation

Adds BlueprintV2ExecutionPlan and BlueprintV2ExecutionPlanItem types in lib/v2/compile.ts. createBlueprintV2ExecutionPlan() mirrors the ordering from the broader TypeScript runner work while keeping each item in v2-shaped data:

{ type: 'defineWpConfigConsts', consts }
{ type: 'setSiteOptions', options }
{ type: 'installPlugin', plugin, sourcePath: '/plugins/0' }
{ type: 'runStep', step, sourcePath: '/additionalStepsAfterExecution/0' }

Minimal v2 declarations still compile and run as a no-op. Declarations with planned work compile successfully but reject on run() until follow-up PRs wire individual plan items.

Testing instructions

npm run format:uncommitted
npm exec nx run playground-blueprints:test:vite -- --testFiles=packages/playground/blueprints/src/tests/compile.spec.ts
npm exec nx run playground-blueprints:typecheck
npm exec nx run playground-blueprints:lint
npm exec nx run playground-blueprints:build
npm exec nx run playground-blueprints:test:vite
git diff --check

Part of #2592.

Copilot AI left a comment

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.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR extracts the compile-only portion of the Blueprint v2 TypeScript runner by compiling parsed v2 declarations into a typed BlueprintV2ExecutionPlan, while preserving runtime metadata and applicationOptions, and ensuring non-empty plans still reject at run() until execution wiring lands.

Changes:

  • Introduces BlueprintV2ExecutionPlan / BlueprintV2ExecutionPlanItem types and createBlueprintV2ExecutionPlan() to produce an ordered plan from v2 declaration fields.
  • Updates compileBlueprintV2() to return { runtime, applicationOptions, plan } and to reject run() when the plan is non-empty.
  • Expands test coverage to validate plan ordering/shape and the “not runnable yet” guard.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
packages/playground/blueprints/src/lib/v2/compile.ts Adds execution plan types + compiler that produces an ordered plan and gates run() on plan emptiness.
packages/playground/blueprints/src/tests/compile.spec.ts Adds tests for v2 plan compilation, ordering, metadata preservation, and runtime rejection behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/playground/blueprints/src/lib/v2/compile.ts Outdated
@adamziel
adamziel force-pushed the compile-blueprint-v2-execution-plan branch from 973387b to 363995a Compare July 3, 2026 23:57
@adamziel
adamziel merged commit d910858 into trunk Jul 4, 2026
53 checks passed
@adamziel
adamziel deleted the compile-blueprint-v2-execution-plan branch July 4, 2026 00:19
adamziel added a commit that referenced this pull request Jul 4, 2026
## What it does

Adds the next v2-local layer after #3908: `compileBlueprintV2()` now
includes a lowered `steps` array and an `unsupportedPlan` array
alongside the existing v2 `plan`.

In this PR, **lowering** means translating Blueprint v2 declarations
into the older v1 step records that the current TypeScript runner
already understands. For example, a v2 `plugins` declaration becomes an
`installPlugin` step record, and a v2 `siteOptions` declaration becomes
a `setSiteOptions` step record.

This PR does not execute those step records yet. It only converts the
supported v2 plan items into a runner-friendly shape and keeps the rest
visible as unsupported work.

The lowering covers many of the safe, already-understood v2 plan items:

- `constants` -> `defineWpConfigConsts`
- `siteOptions` -> `setSiteOptions`
- `siteLanguage` -> `setSiteLanguage`
- top-level `plugins` -> `installPlugin` step records
- top-level `themes` / `activeTheme` -> `installTheme` step records
- simple `additionalStepsAfterExecution` entries like `mkdir`, `cp`,
`mv`, `rm`, `rmdir`, `defineConstants`, `setSiteOptions`,
`setSiteLanguage`, `installPlugin`, `installTheme`, `activatePlugin`,
`activateTheme`, `importThemeStarterContent`, and `wp-cli`

Unsupported v2-only areas such as media/content/font/user/role/post-type
imports remain in `unsupportedPlan` instead of being silently dropped.

## Rationale

This keeps processing the larger TypeScript Blueprint v2 runner work
from #3725 piece by piece. The previous PR made v2 declarations compile
into an ordered v2 plan. This PR groups the v2-only translation work
that does not need consumer wiring or actual runtime execution yet.

The benefit is that reviewers can inspect the v2-to-v1 mapping
separately from the later execution work. If a v2 declaration maps
cleanly to an existing v1 step shape, this PR makes that explicit. If it
does not, the plan item stays in `unsupportedPlan` for a later focused
PR.

It still does **not** execute the lowered steps, resolve resources at
runtime, import content/media, or touch website/CLI/remote data flows.
Non-empty v2 plans continue to reject at `run()` until a later PR wires
execution.

## Implementation

Adds `lowerBlueprintV2ExecutionPlan()` in `lib/v2/compile.ts`. It
returns:

```ts
{
  steps: StepDefinition[],
  unsupportedPlan: BlueprintV2ExecutionPlan
}
```

The lowering layer:

- walks the ordered v2 execution plan
- converts supported plan items to existing `StepDefinition` records
- keeps unsupported items in `unsupportedPlan`
- converts plugin/theme data references into existing v1 resource shapes
- normalizes target-site paths for simple file steps
- rejects empty paths and parent-directory traversal before producing v1
paths

Plugin/theme data references are lowered for WordPress.org slugs,
versioned slugs, URLs, GitHub/GitLab repo URLs, execution-context paths,
inline files, inline directories, and git directory objects.

## Testing instructions

```bash
npm run format:uncommitted
npm exec nx run playground-blueprints:test:vite -- --testFiles=packages/playground/blueprints/src/tests/compile.spec.ts
npm exec nx run playground-blueprints:typecheck
npm exec nx run playground-blueprints:lint
npm exec nx run playground-blueprints:build
git diff --check
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment