Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/cli/ai/tools/create-site.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import path from 'path';
import { DEFAULT_PHP_VERSION } from '@studio/common/constants';
import { SITE_FILE_ACCESS_SITE_DIRECTORY } from '@studio/common/lib/site-file-access';
import { SITE_RUNTIME_NATIVE_PHP } from '@studio/common/lib/site-runtime';
import { Type } from 'typebox';
import { emitLocalSiteSelected } from 'cli/ai/site-selection';
import { runCommand as runCreateSiteCommand } from 'cli/commands/site/create';
Expand Down Expand Up @@ -29,6 +31,8 @@ export const createSiteTool = defineTool(
name: args.name,
wpVersion: 'latest',
phpVersion: DEFAULT_PHP_VERSION,
runtime: SITE_RUNTIME_NATIVE_PHP,
fileAccess: SITE_FILE_ACCESS_SITE_DIRECTORY,
enableHttps: false,
noStart: false,
skipBrowser: true,
Expand Down
14 changes: 8 additions & 6 deletions apps/cli/commands/blueprint/use.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import fs from 'fs';
import path from 'path';
import { select, input } from '@inquirer/prompts';
import { SupportedPHPVersions, type SupportedPHPVersion } from '@php-wasm/universal';
import { DEFAULT_PHP_VERSION, DEFAULT_WORDPRESS_VERSION } from '@studio/common/constants';
import {
createBlueprintTempDir,
Expand All @@ -10,17 +9,18 @@ import {
} from '@studio/common/lib/blueprint-bundle';
import { isOnline } from '@studio/common/lib/network-utils';
import { readSharedConfig } from '@studio/common/lib/shared-config';
import { SITE_FILE_ACCESS_SITE_DIRECTORY } from '@studio/common/lib/site-file-access';
import { SITE_RUNTIME_NATIVE_PHP } from '@studio/common/lib/site-runtime';
import { fetchStudioBlueprints, type Blueprint } from '@studio/common/lib/studio-blueprints-api';
import { BlueprintCommandLoggerAction as LoggerAction } from '@studio/common/logger-actions';
import { SupportedPHPVersions, type SupportedPHPVersion } from '@studio/common/types/php-versions';
import { __, _n, sprintf } from '@wordpress/i18n';
import { runCommand as runCreateSiteCommand } from 'cli/commands/site/create';
import { getDefaultSitePath } from 'cli/lib/site-paths';
import { untildify } from 'cli/lib/utils';
import { Logger, LoggerError } from 'cli/logger';
import { StudioArgv } from 'cli/types';

const ALLOWED_PHP_VERSIONS = [ ...SupportedPHPVersions ];

const logger = new Logger< LoggerAction >();

async function resolveBlueprint( blueprint: Blueprint ): Promise< {
Expand Down Expand Up @@ -52,7 +52,7 @@ export async function runCommand(
options: {
name?: string;
wpVersion?: string;
phpVersion?: string;
phpVersion?: SupportedPHPVersion;
customDomain?: string;
enableHttps: boolean;
adminUsername?: string;
Expand Down Expand Up @@ -123,7 +123,9 @@ export async function runCommand(
await runCreateSiteCommand( sitePath, {
name: options.name,
wpVersion: options.wpVersion ?? DEFAULT_WORDPRESS_VERSION,
phpVersion: ( options.phpVersion ?? DEFAULT_PHP_VERSION ) as SupportedPHPVersion,
phpVersion: options.phpVersion ?? DEFAULT_PHP_VERSION,
runtime: SITE_RUNTIME_NATIVE_PHP,
fileAccess: SITE_FILE_ACCESS_SITE_DIRECTORY,
customDomain: options.customDomain,
enableHttps: options.enableHttps,
blueprint: {
Expand Down Expand Up @@ -166,7 +168,7 @@ export const registerCommand = ( yargs: StudioArgv ) => {
.option( 'php', {
type: 'string',
describe: __( 'PHP version' ),
choices: ALLOWED_PHP_VERSIONS,
choices: SupportedPHPVersions,
defaultDescription: DEFAULT_PHP_VERSION,
} )
.option( 'domain', {
Expand Down
10 changes: 8 additions & 2 deletions apps/cli/commands/pull-reprint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { generateNumberedName } from '@studio/common/lib/generate-site-name';
import { encodePassword } from '@studio/common/lib/passwords';
import { portFinder } from '@studio/common/lib/port-finder';
import { readAuthToken, type StoredAuthToken } from '@studio/common/lib/shared-config';
import { SITE_RUNTIME_PLAYGROUND } from '@studio/common/lib/site-runtime';
import { sortSites } from '@studio/common/lib/sort-sites';
import { PullReprintCommandLoggerAction as LoggerAction } from '@studio/common/logger-actions';
import { __, sprintf } from '@wordpress/i18n';
Expand Down Expand Up @@ -1365,10 +1366,15 @@ async function findExistingSite( metadata: PullSessionMetadata ): Promise< SiteD
}

function printSiteUrls( localUrl: string ): void {
console.log( __( 'Site URL: ' ), buildAutoLoginUrl( localUrl ) );
// Pulled sites always run on the Playground runtime today.
console.log( __( 'Site URL: ' ), buildAutoLoginUrl( SITE_RUNTIME_PLAYGROUND, localUrl ) );
console.log(
__( 'WP Admin: ' ),
buildAutoLoginUrl( localUrl, new URL( '/wp-admin/', localUrl ).toString() )
buildAutoLoginUrl(
SITE_RUNTIME_PLAYGROUND,
localUrl,
new URL( '/wp-admin/', localUrl ).toString()
)
);
console.log( '' );
}
Expand Down
91 changes: 68 additions & 23 deletions apps/cli/commands/site/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,19 @@ import {
removeDbConstants,
} from '@studio/common/lib/remove-default-db-constants';
import { readSharedConfig } from '@studio/common/lib/shared-config';
import { SITE_RUNTIME_NATIVE_PHP } from '@studio/common/lib/site-runtime';
import {
isFileAccessAllowedForRuntime,
SITE_FILE_ACCESS_ALL_FILES,
SITE_FILE_ACCESS_SITE_DIRECTORY,
type SiteFileAccess,
} from '@studio/common/lib/site-file-access';
import {
SITE_MODE_NATIVE,
SITE_MODE_SANDBOX,
SITE_RUNTIME_NATIVE_PHP,
siteRuntimeFromMode,
type SiteRuntime,
} from '@studio/common/lib/site-runtime';
import { sortSites } from '@studio/common/lib/sort-sites';
import { getServerFilesPath } from '@studio/common/lib/well-known-paths';
import {
Expand All @@ -39,7 +51,11 @@ import {
} from '@studio/common/lib/wordpress-version-utils';
import { fetchWordPressVersions } from '@studio/common/lib/wordpress-versions';
import { SiteCommandLoggerAction as LoggerAction } from '@studio/common/logger-actions';
import { type SupportedPHPVersion } from '@studio/common/types/php-versions';
import {
RecommendedPHPVersion,
SupportedPHPVersions,
type SupportedPHPVersion,
} from '@studio/common/types/php-versions';
import { __, sprintf } from '@wordpress/i18n';
import { isStepDefinition, type BlueprintV1Declaration } from '@wp-playground/blueprints';
import { bumpStat, getPlatformMetric } from 'cli/lib/bump-stat';
Expand All @@ -62,13 +78,8 @@ import {
} from 'cli/lib/dependency-management/paths';
import { updateServerFiles } from 'cli/lib/dependency-management/setup';
import { downloadWordPress } from 'cli/lib/dependency-management/wordpress';
import { getSiteRuntime } from 'cli/lib/feature-flags';
import { copyLanguagePackToSite } from 'cli/lib/language-packs';
import {
getRecommendedPhpVersionForSiteRuntime,
getSupportedPhpVersionsForSiteRuntime,
validatePhpVersionForSiteRuntime,
} from 'cli/lib/php-versions';
import { validateSupportedPhpVersion } from 'cli/lib/php-versions';
import { getPreferredSiteLanguage } from 'cli/lib/site-language';
import { generateSiteName } from 'cli/lib/site-name';
import { getDefaultSitePath } from 'cli/lib/site-paths';
Expand All @@ -88,6 +99,8 @@ export type CreateCommandOptions = {
siteId?: string;
wpVersion: string;
phpVersion: SupportedPHPVersion;
runtime: SiteRuntime;
fileAccess: SiteFileAccess;
customDomain?: string;
enableHttps: boolean;
blueprint?: {
Expand All @@ -106,8 +119,15 @@ export async function runCommand(
sitePath: string,
options: CreateCommandOptions
): Promise< void > {
const phpVersion = validatePhpVersionForSiteRuntime( options.phpVersion );
const siteRuntime = getSiteRuntime();
const siteRuntime = options.runtime;
if ( ! isFileAccessAllowedForRuntime( siteRuntime, options.fileAccess ) ) {
throw new LoggerError(
__(
'File access "all-files" requires the native PHP runtime. The sandbox only has access to the site directory.'
)
);
}
const phpVersion = validateSupportedPhpVersion( options.phpVersion );
const isOnlineStatus = await isOnline();

try {
Expand Down Expand Up @@ -308,6 +328,8 @@ export async function runCommand(
adminEmail,
port,
phpVersion,
runtime: siteRuntime,
fileAccess: options.fileAccess,
running: false,
isWpAutoUpdating: options.wpVersion === DEFAULT_WORDPRESS_VERSION,
customDomain: options.customDomain,
Expand Down Expand Up @@ -498,8 +520,6 @@ export const registerCommand = ( yargs: StudioArgv ) => {
command: 'create',
describe: __( 'Create a new site' ),
builder: ( yargs ) => {
const supportedPhpVersions = getSupportedPhpVersionsForSiteRuntime();
const recommendedPhpVersion = getRecommendedPhpVersionForSiteRuntime();
return yargs
.option( 'id', {
type: 'string',
Expand All @@ -520,8 +540,24 @@ export const registerCommand = ( yargs: StudioArgv ) => {
.option( 'php', {
type: 'string',
describe: __( 'PHP version' ),
choices: supportedPhpVersions,
defaultDescription: recommendedPhpVersion,
choices: SupportedPHPVersions,
defaultDescription: RecommendedPHPVersion,
} )
.option( 'runtime', {
type: 'string',
describe: __(
'Run the site with native PHP ("native") or in the Playground sandbox ("sandbox")'
),
choices: [ SITE_MODE_NATIVE, SITE_MODE_SANDBOX ] as const,
default: SITE_MODE_NATIVE,
} )
Comment on lines +546 to +553

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.

Suggested change
.option( 'runtime', {
type: 'string',
describe: __(
'Run the site with native PHP ("native") or in the Playground sandbox ("sandbox")'
),
choices: [ SITE_MODE_NATIVE, SITE_MODE_SANDBOX ],
defaultDescription: SITE_MODE_SANDBOX,
} )
.option( 'runtime', {
type: 'string',
describe: __(
'Run the site with native PHP ("native") or in the Playground sandbox ("sandbox")'
),
choices: [ SITE_MODE_NATIVE, SITE_MODE_SANDBOX ] as const,
default: SITE_MODE_SANDBOX,
} )

I think this behavior is already the intent here, but we aren't actually getting the type guarantees because of a few missing tweaks. We need this and a small tweak in tools/common/lib/site-runtime.ts – see my comment there

.option( 'file-access', {
type: 'string',
describe: __(
'Which files PHP can access with the native PHP runtime: the site directory only, or all files'
),
choices: [ SITE_FILE_ACCESS_SITE_DIRECTORY, SITE_FILE_ACCESS_ALL_FILES ] as const,
default: SITE_FILE_ACCESS_SITE_DIRECTORY,
} )
Comment on lines +554 to 561

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.

Suggested change
.option( 'file-access', {
type: 'string',
describe: __(
'Which files PHP can access with the native PHP runtime: the site directory only, or all files'
),
choices: [ SITE_FILE_ACCESS_SITE_DIRECTORY, SITE_FILE_ACCESS_ALL_FILES ],
defaultDescription: SITE_FILE_ACCESS_SITE_DIRECTORY,
} )
.option( 'file-access', {
type: 'string',
describe: __(
'Which files PHP can access with the native PHP runtime: the site directory only, or all files'
),
choices: [ SITE_FILE_ACCESS_SITE_DIRECTORY, SITE_FILE_ACCESS_ALL_FILES ] as const,
default: SITE_FILE_ACCESS_SITE_DIRECTORY,
} )

Same thing as for runtime. Again, small tweak in tools/common/lib/site-file-access.ts needed

.option( 'domain', {
type: 'string',
Expand Down Expand Up @@ -580,8 +616,18 @@ export const registerCommand = ( yargs: StudioArgv ) => {
let adminUsername = argv.adminUsername;
let adminPassword = argv.adminPassword;
let adminEmail = argv.adminEmail;
const supportedPhpVersions = getSupportedPhpVersionsForSiteRuntime();
const recommendedPhpVersion = getRecommendedPhpVersionForSiteRuntime();
const runtime = siteRuntimeFromMode( argv.runtime );
const fileAccess = argv.fileAccess;
if ( ! isFileAccessAllowedForRuntime( runtime, fileAccess ) ) {
logger.reportError(
new LoggerError(
__(
'File access "all-files" requires the native PHP runtime. The sandbox only has access to the site directory.'
)
)
);
return;
}

// Validate and resolve the WordPress version against available versions before prompting
if ( wpVersion && wpVersion !== 'latest' && wpVersion !== 'nightly' ) {
Expand Down Expand Up @@ -680,11 +726,11 @@ export const registerCommand = ( yargs: StudioArgv ) => {
if ( ! phpVersion ) {
phpVersion = await select( {
message: __( 'PHP version:' ),
choices: supportedPhpVersions.map( ( v ) => ( {
name: v === recommendedPhpVersion ? sprintf( __( '%s (recommended)' ), v ) : v,
choices: SupportedPHPVersions.map( ( v ) => ( {
name: v === RecommendedPHPVersion ? sprintf( __( '%s (recommended)' ), v ) : v,
value: v,
} ) ),
default: recommendedPhpVersion,
default: RecommendedPHPVersion,
} );
}

Expand Down Expand Up @@ -741,15 +787,14 @@ export const registerCommand = ( yargs: StudioArgv ) => {

// Apply defaults for non-interactive mode when flags weren't provided
wpVersion = wpVersion ?? DEFAULT_WORDPRESS_VERSION;
const resolvedPhpVersion = validatePhpVersionForSiteRuntime(
phpVersion ?? recommendedPhpVersion
);

const config: CreateCommandOptions = {
name: siteName,
siteId: argv.id,
wpVersion,
phpVersion: resolvedPhpVersion,
phpVersion: phpVersion ?? RecommendedPHPVersion,
runtime,
fileAccess,
customDomain,
enableHttps,
adminUsername,
Expand Down
Loading