Skip to content

[Blueprints] Allow skipping theme install failures - #3854

Merged
adamziel merged 1 commit into
trunkfrom
add/theme-install-on-error
Jul 1, 2026
Merged

[Blueprints] Allow skipping theme install failures#3854
adamziel merged 1 commit into
trunkfrom
add/theme-install-on-error

Conversation

@adamziel

@adamziel adamziel commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

What it does

Adds installTheme.options.onError with two modes:

Value Behavior
throw Preserve current behavior: installation, activation, or starter-content failures abort the Blueprint.
skip-theme Log a warning and continue running the Blueprint.

Also adds installTheme.options.humanReadableName so skip warnings and progress captions can use the v2 declaration name instead of deriving one from the archive or directory.

Rationale

Blueprint v2 needs theme installation to match the plugin failure policy that just landed. A Blueprint author can now declare that a non-critical theme install should not prevent later steps from running.

This PR keeps the change intentionally narrow: it does not add directory-resource path hardening, directory ifAlreadyInstalled handling, or WXR controls. Those stay as separate reviewable changes.

Implementation

installTheme() now wraps install, activation, and starter-content import in one try/catch block. When installTheme.options.onError is set toskip-theme, it logs:

Skipping theme installation for <theme name> after failure: <error>

The theme name comes from humanReadableName, then the derived archive/directory name, then unknown theme if the failure happens before a name can be derived.

The public Blueprint schema and validator were regenerated so onError and humanReadableName are accepted under installTheme.options.

Testing instructions

Validated locally:

npm exec nx run playground-blueprints:build:blueprint-schema
npm run format:uncommitted
npm exec nx run playground-blueprints:test:vite -- --testFiles=packages/playground/blueprints/src/tests/steps/install-theme.spec.ts
npm exec nx run playground-blueprints:lint
npm exec nx run playground-blueprints:typecheck
git diff --check
@adamziel
adamziel marked this pull request as ready for review July 1, 2026 17:46
@adamziel
adamziel requested review from a team, Copilot and zaerl July 1, 2026 17:46
@adamziel
adamziel merged commit d1afc57 into trunk Jul 1, 2026
54 of 55 checks passed
@adamziel
adamziel deleted the add/theme-install-on-error branch July 1, 2026 17:48

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.

Adds an installTheme.options.onError policy to allow Blueprint authors to continue when theme installation/activation/starter-content import fails, and introduces humanReadableName for clearer progress/warning text.

Changes:

  • Add onError: 'skip-theme' | 'throw' and humanReadableName to the installTheme step options and implementation.
  • Wrap install + activate + starter-content import in a single try/catch and warn/continue when configured to skip.
  • Regenerate the public Blueprint schema and add tests for the new skip + naming behaviors.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.

File Description
packages/playground/blueprints/src/lib/steps/install-theme.ts Adds onError handling + humanReadableName and implements skip-on-failure behavior.
packages/playground/blueprints/src/tests/steps/install-theme.spec.ts Adds tests asserting skip behavior and name selection in warnings.
packages/playground/blueprints/public/blueprint-schema.json Updates schema to accept onError and humanReadableName under installTheme.options.

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

Comment on lines 101 to +102
let assetNiceName = '';
if (themeData instanceof File) {
// @TODO: Consider validating whether this is a zip file?
const zipFileName = themeData.name.split('/').pop() || 'theme.zip';
assetNiceName = zipNameToHumanName(zipFileName);
const progressName = () => options.humanReadableName || assetNiceName;
Comment on lines +164 to 175
} catch (error) {
if (onError === 'skip-theme') {
const skippedThemeName = progressName() || 'unknown theme';
logger.warn(
`Skipping theme installation for ${skippedThemeName} after failure: ${
error instanceof Error ? error.message : String(error)
}`
);
return;
}
throw error;
}
Comment on lines +105 to +125
const loggerWarnSpy = vi
.spyOn(logger, 'warn')
.mockImplementation(() => {});
try {
await installTheme(php, {
themeData: new File(['not a zip'], 'broken-theme.zip'),
ifAlreadyInstalled: 'overwrite',
options: {
onError: 'skip-theme',
},
});

expect(loggerWarnSpy).toHaveBeenCalledWith(
expect.stringContaining(
'Skipping theme installation for Broken theme after failure'
)
);
expect(php.fileExists(expectedThemeIndexPhpPath)).toBe(false);
} finally {
loggerWarnSpy.mockRestore();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment