diff --git a/.changeset/smart-adults-run.md b/.changeset/smart-adults-run.md
new file mode 100644
index 000000000000..bfcee0d431ae
--- /dev/null
+++ b/.changeset/smart-adults-run.md
@@ -0,0 +1,10 @@
+---
+"wrangler": minor
+---
+
+Add Pages detection to autoconfig flows
+
+When running the autoconfig logic (via `wrangler setup`, `wrangler deploy --x-autoconfig`, or the programmatic autoconfig API), Wrangler now detects when a project appears to be a Pages project and handles it appropriately:
+
+- For `wrangler deploy`, it warns the user but still allows them to proceed
+- For `wrangler setup` and the programmatic autoconfig API, it throws a fatal error
diff --git a/packages/wrangler/src/__tests__/autoconfig/details/get-details-for-auto-config.test.ts b/packages/wrangler/src/__tests__/autoconfig/details/get-details-for-auto-config.test.ts
index 0116a1df036e..b998978e54d8 100644
--- a/packages/wrangler/src/__tests__/autoconfig/details/get-details-for-auto-config.test.ts
+++ b/packages/wrangler/src/__tests__/autoconfig/details/get-details-for-auto-config.test.ts
@@ -1,17 +1,21 @@
import { randomUUID } from "node:crypto";
import { writeFile } from "node:fs/promises";
+import { join } from "node:path";
import { seed } from "@cloudflare/workers-utils/test-helpers";
/* eslint-disable workers-sdk/no-vitest-import-expect -- it.each patterns */
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
/* eslint-enable workers-sdk/no-vitest-import-expect */
import * as details from "../../../autoconfig/details";
+import * as configCache from "../../../config-cache";
import { clearOutputFilePath } from "../../../output";
import {
getPackageManager,
NpmPackageManager,
PnpmPackageManager,
} from "../../../package-manager";
+import { PAGES_CONFIG_CACHE_FILENAME } from "../../../pages/constants";
import { mockConsoleMethods } from "../../helpers/mock-console";
+import { mockConfirm } from "../../helpers/mock-dialogs";
import { useMockIsTTY } from "../../helpers/mock-istty";
import { runInTempDir } from "../../helpers/run-in-tmp";
import type { Config } from "@cloudflare/workers-utils";
@@ -205,4 +209,107 @@ describe("autoconfig details - getDetailsForAutoConfig()", () => {
workerName: "overridden-worker-name",
});
});
+
+ describe("Pages project detection", () => {
+ it("should detect Pages project when pages_build_output_dir is set in wrangler config", async () => {
+ await seed({
+ "public/index.html": `
Hello World
`,
+ });
+
+ const result = await details.getDetailsForAutoConfig({
+ wranglerConfig: {
+ configPath: "/tmp/wrangler.toml",
+ pages_build_output_dir: "./dist",
+ } as Config,
+ });
+
+ expect(result.configured).toBe(false);
+ expect(result.framework?.id).toBe("cloudflare-pages");
+ expect(result.framework?.name).toBe("Cloudflare Pages");
+ });
+
+ it("should detect Pages project when pages.json cache file exists", async () => {
+ const cacheFolder = join(process.cwd(), ".cache");
+ await seed({
+ "public/index.html": `Hello World
`,
+ // Create a cache folder in the temp directory and add pages.json to it
+ [join(cacheFolder, PAGES_CONFIG_CACHE_FILENAME)]: JSON.stringify({
+ account_id: "test-account",
+ }),
+ });
+
+ // Mock getCacheFolder to return our temp cache folder
+ const getCacheFolderSpy = vi
+ .spyOn(configCache, "getCacheFolder")
+ .mockReturnValue(cacheFolder);
+
+ try {
+ const result = await details.getDetailsForAutoConfig();
+
+ expect(result.framework?.id).toBe("cloudflare-pages");
+ expect(result.framework?.name).toBe("Cloudflare Pages");
+ } finally {
+ getCacheFolderSpy.mockRestore();
+ }
+ });
+
+ it("should detect Pages project when functions directory exists, no framework is detected and the user confirms that it is", async () => {
+ await seed({
+ "public/index.html": `Hello World
`,
+ "functions/hello.js": `
+ export function onRequest(context) {
+ return new Response("Hello, world!");
+ }
+ `,
+ });
+
+ mockConfirm({
+ text: "We have identified a `functions` directory in this project, which might indicate you have an active Cloudflare Pages deployment. Is this correct?",
+ result: true,
+ });
+
+ const result = await details.getDetailsForAutoConfig();
+
+ expect(result.framework?.id).toBe("cloudflare-pages");
+ expect(result.framework?.name).toBe("Cloudflare Pages");
+ });
+
+ it("should not detect Pages project when the user denies that, even it the functions directory exists and no framework is detected", async () => {
+ await seed({
+ "public/index.html": `Hello World
`,
+ "functions/hello.js": `
+ export function onRequest(context) {
+ return new Response("Hello, world!");
+ }
+ `,
+ });
+
+ mockConfirm({
+ text: "We have identified a `functions` directory in this project, which might indicate you have an active Cloudflare Pages deployment. Is this correct?",
+ result: false,
+ });
+
+ const result = await details.getDetailsForAutoConfig();
+
+ expect(result.framework?.id).toBe("static");
+ expect(result.framework?.name).toBe("Static");
+ });
+
+ it("should not detect Pages project when functions directory exists but a framework is detected", async () => {
+ await seed({
+ "functions/hello.js":
+ "export const myFun = () => { console.log('Hello!'); };",
+ "package.json": JSON.stringify({
+ dependencies: {
+ astro: "5",
+ },
+ }),
+ });
+
+ const result = await details.getDetailsForAutoConfig();
+
+ // Should detect Astro, not Pages
+ expect(result.framework?.id).toBe("astro");
+ });
+ });
});
diff --git a/packages/wrangler/src/__tests__/autoconfig/run.test.ts b/packages/wrangler/src/__tests__/autoconfig/run.test.ts
index 8bbc23ea3673..4c510fcbfa0d 100644
--- a/packages/wrangler/src/__tests__/autoconfig/run.test.ts
+++ b/packages/wrangler/src/__tests__/autoconfig/run.test.ts
@@ -142,6 +142,42 @@ describe("autoconfig (deploy)", () => {
expect(runSpy).not.toHaveBeenCalled();
});
+ it("should warn and prompt when Pages project is detected", async () => {
+ vi.spyOn(details, "getDetailsForAutoConfig").mockImplementationOnce(() =>
+ Promise.resolve({
+ configured: false,
+ projectPath: process.cwd(),
+ workerName: "my-worker",
+ framework: {
+ id: "cloudflare-pages",
+ name: "Cloudflare Pages",
+ autoConfigSupported: false,
+ configure: async () => ({ wranglerConfig: {} }),
+ isConfigured: () => false,
+ },
+ outputDir: "public",
+ })
+ );
+ const runSpy = vi.spyOn(run, "runAutoConfig");
+
+ // User declines to proceed
+ mockConfirm({
+ text: "Are you sure that you want to proceed?",
+ result: false,
+ });
+
+ // Should not throw - just return early
+ await runWrangler("deploy --x-autoconfig");
+
+ // Should show warning about Pages project
+ expect(std.warn).toContain(
+ "It seems that you have run `wrangler deploy` on a Pages project"
+ );
+
+ // Should NOT run autoconfig since it's a Pages project
+ expect(runSpy).not.toHaveBeenCalled();
+ });
+
describe("runAutoConfig()", () => {
let installSpy: MockInstance;
beforeEach(() => {
@@ -392,5 +428,55 @@ describe("autoconfig (deploy)", () => {
`[AssertionError: The Output Directory is unexpectedly missing]`
);
});
+
+ it("errors with Pages-specific message when framework is cf-pages", async () => {
+ mockConfirm({
+ text: "Do you want to modify these settings?",
+ result: false,
+ });
+
+ await expect(
+ run.runAutoConfig({
+ projectPath: process.cwd(),
+ configured: false,
+ framework: {
+ id: "cloudflare-pages",
+ name: "Cloudflare Pages",
+ autoConfigSupported: false,
+ configure: async () => ({ wranglerConfig: {} }),
+ isConfigured: () => false,
+ },
+ workerName: "my-worker",
+ outputDir: "dist",
+ })
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
+ `[Error: The target project seems to be using Cloudflare Pages. Automatically migrating from a Pages project to a Workers one is not yet supported.]`
+ );
+ });
+
+ it("errors with generic message when unsupported framework is not cf-pages", async () => {
+ mockConfirm({
+ text: "Do you want to modify these settings?",
+ result: false,
+ });
+
+ await expect(
+ run.runAutoConfig({
+ projectPath: process.cwd(),
+ configured: false,
+ framework: {
+ id: "some-unsupported",
+ name: "Some Unsupported Framework",
+ autoConfigSupported: false,
+ configure: async () => ({ wranglerConfig: {} }),
+ isConfigured: () => false,
+ },
+ workerName: "my-worker",
+ outputDir: "dist",
+ })
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
+ `[Error: The detected framework ("Some Unsupported Framework") cannot be automatically configured.]`
+ );
+ });
});
});
diff --git a/packages/wrangler/src/__tests__/deploy.test.ts b/packages/wrangler/src/__tests__/deploy.test.ts
index 5df3f1b0c925..7ecd72da89c1 100644
--- a/packages/wrangler/src/__tests__/deploy.test.ts
+++ b/packages/wrangler/src/__tests__/deploy.test.ts
@@ -579,6 +579,80 @@ describe("deploy", () => {
);
});
+ it("should attempt to run the autoconfig flow when pages_build_output_dir and (--x-autoconfig is used)", async () => {
+ writeWranglerConfig({
+ pages_build_output_dir: "public",
+ name: "test-name",
+ });
+
+ const getDetailsForAutoConfigSpy = vi
+ .spyOn(await import("../autoconfig/details"), "getDetailsForAutoConfig")
+ .mockResolvedValue({
+ configured: false,
+ projectPath: process.cwd(),
+ workerName: "test-name",
+ framework: {
+ id: "cloudflare-pages",
+ name: "Cloudflare Pages",
+ autoConfigSupported: false,
+ configure: async () => ({ wranglerConfig: {} }),
+ isConfigured: () => false,
+ },
+ outputDir: "public",
+ });
+
+ mockConfirm({
+ text: "Are you sure that you want to proceed?",
+ options: { defaultValue: false },
+ result: false,
+ });
+
+ await runWrangler("deploy --x-autoconfig");
+
+ expect(getDetailsForAutoConfigSpy).toHaveBeenCalled();
+
+ expect(std.warn).toContain(
+ "It seems that you have run `wrangler deploy` on a Pages project"
+ );
+ });
+
+ it("in non-interactive mode, attempts to deploy a Pages project when --x-autoconfig is used", async () => {
+ setIsTTY(false);
+ writeWranglerConfig({
+ pages_build_output_dir: "public",
+ name: "test-name",
+ });
+
+ const getDetailsForAutoConfigSpy = vi
+ .spyOn(await import("../autoconfig/details"), "getDetailsForAutoConfig")
+ .mockResolvedValue({
+ configured: false,
+ projectPath: process.cwd(),
+ workerName: "test-name",
+ framework: {
+ id: "cloudflare-pages",
+ name: "Cloudflare Pages",
+ autoConfigSupported: false,
+ configure: async () => ({ wranglerConfig: {} }),
+ isConfigured: () => false,
+ },
+ outputDir: "public",
+ });
+
+ // The command will fail later due to missing entry-point, but we can still verify
+ // that the deployment of the (Pages) project was attempted
+ await expect(runWrangler("deploy --x-autoconfig")).rejects.toThrow();
+
+ expect(getDetailsForAutoConfigSpy).toHaveBeenCalled();
+
+ expect(std.warn).toContain(
+ "It seems that you have run `wrangler deploy` on a Pages project"
+ );
+ expect(std.out).toContain(
+ "Using fallback value in non-interactive context: yes"
+ );
+ });
+
describe("output additional script information", () => {
it("for first party workers, it should print worker information at log level", async () => {
setIsTTY(false);
diff --git a/packages/wrangler/src/autoconfig/details.ts b/packages/wrangler/src/autoconfig/details.ts
index 39ac6d127be1..4db10269cf65 100644
--- a/packages/wrangler/src/autoconfig/details.ts
+++ b/packages/wrangler/src/autoconfig/details.ts
@@ -1,5 +1,5 @@
import assert from "node:assert";
-import { statSync } from "node:fs";
+import { existsSync, statSync } from "node:fs";
import { readdir, stat } from "node:fs/promises";
import { basename, join, relative, resolve } from "node:path";
import { brandColor } from "@cloudflare/cli/colors";
@@ -12,11 +12,13 @@ import {
import { Project } from "@netlify/build-info";
import { NodeFS } from "@netlify/build-info/node";
import { captureException } from "@sentry/node";
+import { getCacheFolder } from "../config-cache";
import { getErrorType } from "../core/handle-errors";
import { confirm, prompt, select } from "../dialogs";
import { logger } from "../logger";
import { sendMetricsEvent } from "../metrics";
import { getPackageManager } from "../package-manager";
+import { PAGES_CONFIG_CACHE_FILENAME } from "../pages/constants";
import { allKnownFrameworks, getFramework } from "./frameworks/get-framework";
import {
getAutoConfigId,
@@ -27,7 +29,6 @@ import type {
AutoConfigDetailsForNonConfiguredProject,
} from "./types";
import type { Config, PackageJSON } from "@cloudflare/workers-utils";
-import type { Settings } from "@netlify/build-info";
/**
* Asserts that the current project being targeted for autoconfig is not already configured.
@@ -65,9 +66,9 @@ async function hasIndexHtml(dir: string): Promise {
}
/**
- * If we haven't detected a framework being used, we need to "guess" what output dir the user is intending to use.
- * This is best-effort, and so will not be accurate all the time. The heuristic we use is the first child directory
- * with an `index.html` file present.
+ * If we haven't detected a framework being used, or the project is a Pages one, we need to "guess" what output dir the
+ * user is intending to use. This is best-effort, and so will not be accurate all the time. The heuristic we use is the
+ * first child directory with an `index.html` file present.
*/
async function findAssetsDir(from: string): Promise {
if (await hasIndexHtml(from)) {
@@ -91,6 +92,91 @@ function getWorkerName(projectOrWorkerName = "", projectPath: string): string {
return toValidWorkerName(rawName);
}
+type DetectedFramework = {
+ framework: {
+ name: string;
+ id: string;
+ };
+ buildCommand?: string | undefined;
+ dist?: string;
+};
+
+async function isPagesProject(
+ projectPath: string,
+ wranglerConfig: Config | undefined,
+ detectedFramework?: DetectedFramework | undefined
+): Promise {
+ if (wranglerConfig?.pages_build_output_dir) {
+ // The `pages_build_output_dir` is set only for Pages projects
+ return true;
+ }
+
+ const cacheFolder = getCacheFolder();
+ if (cacheFolder) {
+ const pagesConfigCache = join(cacheFolder, PAGES_CONFIG_CACHE_FILENAME);
+ if (existsSync(pagesConfigCache)) {
+ // If there is a cached pages.json we can safely assume that the project
+ // is a Pages one
+ return true;
+ }
+ }
+
+ if (detectedFramework === undefined) {
+ const functionsPath = join(projectPath, "functions");
+ if (existsSync(functionsPath)) {
+ const functionsStat = statSync(functionsPath);
+ if (functionsStat.isDirectory()) {
+ const pagesConfirmed = await confirm(
+ "We have identified a `functions` directory in this project, which might indicate you have an active Cloudflare Pages deployment. Is this correct?",
+ {
+ defaultValue: true,
+ // In CI we do want to fallback to `false` so that we can proceed with the autoconfig flow
+ fallbackValue: false,
+ }
+ );
+ return pagesConfirmed;
+ }
+ }
+ }
+
+ return false;
+}
+
+async function detectFramework(
+ projectPath: string,
+ wranglerConfig?: Config
+): Promise {
+ const fs = new NodeFS();
+
+ fs.logger = logger;
+ const project = new Project(fs, projectPath, projectPath)
+ .setEnvironment(process.env)
+ .setNodeVersion(process.version)
+ .setReportFn((err) => {
+ captureException(err);
+ });
+
+ const buildSettings = await project.getBuildSettings();
+
+ // If we've detected multiple frameworks, it's too complex for us to try and configure—let's just bail
+ if (buildSettings && buildSettings?.length > 1) {
+ throw new MultipleFrameworksError(buildSettings.map((b) => b.name));
+ }
+
+ const detectedFramework: DetectedFramework | undefined = buildSettings[0];
+
+ if (await isPagesProject(projectPath, wranglerConfig, detectedFramework)) {
+ return {
+ framework: {
+ name: "Cloudflare Pages",
+ id: "cloudflare-pages",
+ },
+ };
+ }
+
+ return detectedFramework;
+}
+
/**
* Derives a valid worker name from a project directory.
*
@@ -139,32 +225,20 @@ export async function getDetailsForAutoConfig({
{}
);
- // If a real Wrangler config has been found & used, don't run autoconfig
- if (wranglerConfig?.configPath) {
+ if (
+ // If a real Wrangler config has been found the project is already configured for Workers
+ wranglerConfig?.configPath &&
+ // Unless `pages_build_output_dir` is set, since that indicates that the project is a Pages one instead
+ !wranglerConfig.pages_build_output_dir
+ ) {
return {
configured: true,
projectPath,
workerName: getWorkerName(wranglerConfig.name, projectPath),
};
}
- const fs = new NodeFS();
-
- fs.logger = logger;
- const project = new Project(fs, projectPath, projectPath)
- .setEnvironment(process.env)
- .setNodeVersion(process.version)
- .setReportFn((err) => {
- captureException(err);
- });
-
- const buildSettings = await project.getBuildSettings();
-
- // If we've detected multiple frameworks, it's too complex for us to try and configure—let's just bail
- if (buildSettings.length > 1) {
- throw new MultipleFrameworksError(buildSettings.map((b) => b.name));
- }
- const detectedFramework = buildSettings.at(0);
+ const detectedFramework = await detectFramework(projectPath, wranglerConfig);
const framework = getFramework(detectedFramework?.framework?.id);
const packageJsonPath = resolve(projectPath, "package.json");
@@ -216,7 +290,7 @@ export async function getDetailsForAutoConfig({
if (!outputDir) {
const errorMessage =
- framework.id === "static"
+ framework.id === "static" || framework.id === "cloudflare-pages"
? "Could not detect a directory containing static files (e.g. html, css and js) for the project"
: "Failed to detect an output directory for the project";
@@ -275,7 +349,7 @@ export async function getDetailsForAutoConfig({
* @returns A runnable command for the build process if detected, undefined otherwise
*/
async function getProjectBuildCommand(
- detectedFramework: Settings
+ detectedFramework: DetectedFramework
): Promise {
if (!detectedFramework.buildCommand) {
return undefined;
diff --git a/packages/wrangler/src/autoconfig/frameworks/get-framework.ts b/packages/wrangler/src/autoconfig/frameworks/get-framework.ts
index 2895b66e8e3d..35bdda33f8c5 100644
--- a/packages/wrangler/src/autoconfig/frameworks/get-framework.ts
+++ b/packages/wrangler/src/autoconfig/frameworks/get-framework.ts
@@ -4,6 +4,7 @@ import { Astro } from "./astro";
import { Hono } from "./hono";
import { NextJs } from "./next";
import { Nuxt } from "./nuxt";
+import { CloudflarePages } from "./pages";
import { Qwik } from "./qwik";
import { ReactRouter } from "./react-router";
import { SolidStart } from "./solid-start";
@@ -43,6 +44,7 @@ export const allKnownFrameworks = [
{ id: "vite", name: "Vite", class: Vite },
{ id: "vike", name: "Vike", class: Vike },
{ id: "waku", name: "Waku", class: Waku },
+ { id: "cloudflare-pages", name: "Cloudflare Pages", class: CloudflarePages },
] as const satisfies FrameworkInfo[];
export function getFramework(frameworkId?: FrameworkInfo["id"]): Framework {
diff --git a/packages/wrangler/src/autoconfig/frameworks/pages.ts b/packages/wrangler/src/autoconfig/frameworks/pages.ts
new file mode 100644
index 000000000000..e22b04d43a59
--- /dev/null
+++ b/packages/wrangler/src/autoconfig/frameworks/pages.ts
@@ -0,0 +1,13 @@
+import { Framework } from ".";
+import type { ConfigurationResults } from ".";
+
+export class CloudflarePages extends Framework {
+ async configure(): Promise {
+ return {
+ wranglerConfig: {},
+ };
+ }
+
+ // Autoconfiguring a Pages project into a Workers one is not yet supported
+ autoConfigSupported = false;
+}
diff --git a/packages/wrangler/src/autoconfig/run.ts b/packages/wrangler/src/autoconfig/run.ts
index 253870cbb845..39fa2d4a388f 100644
--- a/packages/wrangler/src/autoconfig/run.ts
+++ b/packages/wrangler/src/autoconfig/run.ts
@@ -79,17 +79,19 @@ export async function runAutoConfig(
autoConfigDetails = updatedAutoConfigDetails;
assertNonConfigured(autoConfigDetails);
- assert(
- autoConfigDetails.outputDir,
- "The Output Directory is unexpectedly missing"
- );
-
if (!autoConfigDetails.framework.autoConfigSupported) {
throw new FatalError(
- `The detected framework ("${autoConfigDetails.framework.name}") cannot be automatically configured.`
+ autoConfigDetails.framework.id === "cloudflare-pages"
+ ? `The target project seems to be using Cloudflare Pages. Automatically migrating from a Pages project to a Workers one is not yet supported.`
+ : `The detected framework ("${autoConfigDetails.framework.name}") cannot be automatically configured.`
);
}
+ assert(
+ autoConfigDetails.outputDir,
+ "The Output Directory is unexpectedly missing"
+ );
+
const { date: compatibilityDate } = getLocalWorkerdCompatibilityDate({
projectPath: autoConfigDetails.projectPath,
});
diff --git a/packages/wrangler/src/config-cache.ts b/packages/wrangler/src/config-cache.ts
index 7e052ecf3469..5315d83aa325 100644
--- a/packages/wrangler/src/config-cache.ts
+++ b/packages/wrangler/src/config-cache.ts
@@ -7,7 +7,7 @@ import { logger } from "./logger";
let cacheMessageShown = false;
let __cacheFolder: string | null | undefined;
-function getCacheFolder() {
+export function getCacheFolder() {
if (__cacheFolder || __cacheFolder === null) {
return __cacheFolder;
}
diff --git a/packages/wrangler/src/deploy/index.ts b/packages/wrangler/src/deploy/index.ts
index e741e64adb64..68e942510f3b 100644
--- a/packages/wrangler/src/deploy/index.ts
+++ b/packages/wrangler/src/deploy/index.ts
@@ -268,14 +268,6 @@ export const deployCommand = createCommand({
}
},
async handler(args, { config }) {
- if (config.pages_build_output_dir) {
- throw new UserError(
- "It looks like you've run a Workers-specific command in a Pages project.\n" +
- "For Pages, please run `wrangler pages deploy` instead.",
- { telemetryMessage: true }
- );
- }
-
const shouldRunAutoConfig =
args.experimentalAutoconfig &&
// If there is a positional parameter or an assets directory specified via --assets then
@@ -284,6 +276,18 @@ export const deployCommand = createCommand({
!args.script &&
!args.assets;
+ if (
+ config.pages_build_output_dir &&
+ // Note: autoconfig handle Pages projects on its own, so we don't want to hard fail here if autoconfig run
+ !shouldRunAutoConfig
+ ) {
+ throw new UserError(
+ "It looks like you've run a Workers-specific command in a Pages project.\n" +
+ "For Pages, please run `wrangler pages deploy` instead.",
+ { telemetryMessage: true }
+ );
+ }
+
if (shouldRunAutoConfig) {
sendAutoConfigProcessStartedMetricsEvent({
command: "wrangler deploy",
@@ -295,8 +299,29 @@ export const deployCommand = createCommand({
wranglerConfig: config,
});
- // Only run auto config if the project is not already configured
- if (!details.configured) {
+ if (details.framework?.id === "cloudflare-pages") {
+ // If the project is a Pages project then warn the user but allow them to proceed if they wish so
+ logger.warn(
+ "It seems that you have run `wrangler deploy` on a Pages project, `wrangler pages deploy` should be used instead. Proceeding will likely produce unwanted results."
+ );
+ const proceedWithPagesProject = await confirm(
+ "Are you sure that you want to proceed?",
+ {
+ defaultValue: false,
+ fallbackValue: true,
+ }
+ );
+
+ if (!proceedWithPagesProject) {
+ sendAutoConfigProcessEndedMetricsEvent({
+ success: false,
+ command: "wrangler deploy",
+ dryRun: !!args.dryRun,
+ });
+ return;
+ }
+ } else if (!details.configured) {
+ // Only run auto config if the project is not already configured
const autoConfigSummary = await runAutoConfig(details);
writeOutput({