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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/blue-dragons-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wrangler": patch
---

Add a warning in the autoconfig logic letting users know that support for projects inside workspaces is limited
6 changes: 6 additions & 0 deletions .changeset/purple-queens-vanish.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@cloudflare/workers-utils": patch
"wrangler": patch
---

Switch to `empathic` for file-system upwards traversal to reduce dependency bloat.
5 changes: 5 additions & 0 deletions .changeset/soft-apes-ask.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wrangler": patch
---

Implemented logic within `wrangler containers registries configure` to check if a specified secret name is already in-use and offer to reuse that secret. Also added `--skip-confirmation` flag to the command to skip all interactive prompts.
2 changes: 1 addition & 1 deletion packages/workers-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
"@vitest/ui": "catalog:default",
"cloudflare": "^5.2.0",
"concurrently": "^8.2.2",
"empathic": "^2.0.0",
"eslint": "catalog:default",
"find-up": "^6.3.0",
"jsonc-parser": "catalog:default",
"smol-toml": "catalog:default",
"ts-dedent": "^2.2.0",
Expand Down
10 changes: 5 additions & 5 deletions packages/workers-utils/src/config/config-helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { existsSync } from "node:fs";
import path from "node:path";
import { findUpSync } from "find-up";
import * as find from "empathic/find";
import dedent from "ts-dedent";
import { PATH_TO_DEPLOY_CONFIG } from "../constants";
import { UserError } from "../errors";
Expand Down Expand Up @@ -61,9 +61,9 @@ export function findWranglerConfig(
{ useRedirectIfAvailable = false } = {}
): ConfigPaths {
const userConfigPath =
findUpSync(`wrangler.json`, { cwd: referencePath }) ??
findUpSync(`wrangler.jsonc`, { cwd: referencePath }) ??
findUpSync(`wrangler.toml`, { cwd: referencePath });
find.file(`wrangler.json`, { cwd: referencePath }) ??
find.file(`wrangler.jsonc`, { cwd: referencePath }) ??
find.file(`wrangler.toml`, { cwd: referencePath });

if (!useRedirectIfAvailable) {
return {
Expand Down Expand Up @@ -99,7 +99,7 @@ function findRedirectedWranglerConfig(
deployConfigPath: string | undefined;
redirected: boolean;
} {
const deployConfigPath = findUpSync(PATH_TO_DEPLOY_CONFIG, { cwd });
const deployConfigPath = find.file(PATH_TO_DEPLOY_CONFIG, { cwd });
if (deployConfigPath === undefined) {
return { configPath: userConfigPath, deployConfigPath, redirected: false };
}
Expand Down
2 changes: 1 addition & 1 deletion packages/wrangler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,10 @@
"devtools-protocol": "^0.0.1182435",
"dotenv": "^16.3.1",
"dotenv-expand": "^12.0.2",
"empathic": "^2.0.0",
"eslint": "catalog:default",
"esprima": "4.0.1",
"execa": "^6.1.0",
"find-up": "^6.3.0",
"get-port": "^7.0.0",
"glob-to-regexp": "^0.4.1",
"https-proxy-agent": "7.0.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ describe("autoconfig details - confirmAutoConfigDetails()", () => {
"dlx": [
"npx",
],
"lockFiles": [
"package-lock.json",
],
"npx": "npx",
"type": "npm",
},
Expand Down Expand Up @@ -115,6 +118,9 @@ describe("autoconfig details - confirmAutoConfigDetails()", () => {
"dlx": [
"npx",
],
"lockFiles": [
"package-lock.json",
],
"npx": "npx",
"type": "npm",
},
Expand Down Expand Up @@ -174,6 +180,9 @@ describe("autoconfig details - confirmAutoConfigDetails()", () => {
"dlx": [
"npx",
],
"lockFiles": [
"package-lock.json",
],
"npx": "npx",
"type": "npm",
},
Expand Down Expand Up @@ -255,6 +264,9 @@ describe("autoconfig details - confirmAutoConfigDetails()", () => {
"dlx": [
"npx",
],
"lockFiles": [
"package-lock.json",
],
"npx": "npx",
"type": "npm",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type { Mock, MockInstance } from "vitest";
describe("autoconfig details - getDetailsForAutoConfig()", () => {
runInTempDir();
const { setIsTTY } = useMockIsTTY();
mockConsoleMethods();
const std = mockConsoleMethods();
let isNonInteractiveOrCISpy: MockInstance;

beforeEach(() => {
Expand Down Expand Up @@ -122,6 +122,27 @@ describe("autoconfig details - getDetailsForAutoConfig()", () => {
);
});

it("should warn when no lock file is detected (project may be inside a workspace)", async ({
expect,
}) => {
// Create a project without a lock file - simulating a project inside a workspace
// where the lock file is at the workspace root
await seed({
"package.json": JSON.stringify({
name: "my-app",
dependencies: {},
}),
"index.html": "<h1>Hello World</h1>",
});

await details.getDetailsForAutoConfig();

expect(std.warn).toContain(
"No lock file has been detected in the current working directory."
);
expect(std.warn).toContain("project is part of a workspace");
});

it("should use npm build instead of framework build if present", async ({
expect,
}) => {
Expand Down
69 changes: 60 additions & 9 deletions packages/wrangler/src/__tests__/containers/registries.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe("containers registries configure", () => {
const domain = "123456789012.dkr.ecr.us-west-2.amazonaws.com";
await expect(
runWrangler(
`containers registries configure ${domain} --public-credential=test-id --disableSecretsStore`
`containers registries configure ${domain} --public-credential=test-id --disable-secrets-store`
)
).rejects.toThrowErrorMatchingInlineSnapshot(
`[Error: Secrets Store can only be disabled in FedRAMP compliance regions.]`
Expand All @@ -61,23 +61,23 @@ describe("containers registries configure", () => {
`containers registries configure ${domain} --aws-access-key-id=test-access-key-id --secret-store-id=storeid`
)
).rejects.toThrowErrorMatchingInlineSnapshot(
`[Error: Secrets Store is not supported in FedRAMP compliance regions. You must set --disableSecretsStore.]`
`[Error: Secrets Store is not supported in FedRAMP compliance regions. You must set --disable-secrets-store.]`
);

await expect(
runWrangler(
`containers registries configure ${domain} --aws-access-key-id=test-access-key-id --secret-store-id=storeid --disableSecretsStore`
`containers registries configure ${domain} --aws-access-key-id=test-access-key-id --secret-store-id=storeid --disable-secrets-store`
)
).rejects.toThrowErrorMatchingInlineSnapshot(
`[Error: Arguments secret-store-id and disableSecretsStore are mutually exclusive]`
`[Error: Arguments secret-store-id and disable-secrets-store are mutually exclusive]`
);

await expect(
runWrangler(
`containers registries configure ${domain} --aws-access-key-id=test-access-key-id --secret-name=secret-name --disableSecretsStore`
`containers registries configure ${domain} --aws-access-key-id=test-access-key-id --secret-name=secret-name --disable-secrets-store`
)
).rejects.toThrowErrorMatchingInlineSnapshot(
`[Error: Arguments secret-name and disableSecretsStore are mutually exclusive]`
`[Error: Arguments secret-name and disable-secrets-store are mutually exclusive]`
);
});

Expand Down Expand Up @@ -123,7 +123,7 @@ describe("containers registries configure", () => {
});

await runWrangler(
`containers registries configure ${awsEcrDomain} --aws-access-key-id=test-access-key-id --disableSecretsStore`
`containers registries configure ${awsEcrDomain} --aws-access-key-id=test-access-key-id --disable-secrets-store`
);

expect(cliStd.stdout).toMatchInlineSnapshot(`
Expand Down Expand Up @@ -161,7 +161,7 @@ describe("containers registries configure", () => {
});

await runWrangler(
`containers registries configure ${awsEcrDomain} --public-credential=test-access-key-id --disableSecretsStore`
`containers registries configure ${awsEcrDomain} --public-credential=test-access-key-id --disable-secrets-store`
);
});
});
Expand Down Expand Up @@ -192,6 +192,7 @@ describe("containers registries configure", () => {
modified: "2024-01-01T00:00:00Z",
},
]);
mockListSecrets(storeId, []);
mockCreateSecret(storeId);
mockPutRegistry({
domain: "123456789012.dkr.ecr.us-west-2.amazonaws.com",
Expand Down Expand Up @@ -235,6 +236,7 @@ describe("containers registries configure", () => {

mockListSecretStores([]);
mockCreateSecretStore(newStoreId);
mockListSecrets(newStoreId, []);
mockCreateSecret(newStoreId);
mockPutRegistry({
domain: awsEcrDomain,
Expand Down Expand Up @@ -275,6 +277,7 @@ describe("containers registries configure", () => {
result: "AWS_Secret_Access_Key",
});

mockListSecrets(providedStoreId, []);
mockCreateSecret(providedStoreId);
mockPutRegistry({
domain: awsEcrDomain,
Expand Down Expand Up @@ -307,7 +310,7 @@ describe("containers registries configure", () => {
│ Container-scoped secret AWS_Secret_Access_Key created in Secrets Store.
│ Container-scoped secret "AWS_Secret_Access_Key" created in Secrets Store.
╰ Registry configuration completed

Expand Down Expand Up @@ -336,6 +339,7 @@ describe("containers registries configure", () => {
modified: "2024-01-01T00:00:00Z",
},
]);
mockListSecrets(storeId, []);
mockCreateSecret(storeId);
mockPutRegistry({
domain: awsEcrDomain,
Expand All @@ -353,6 +357,53 @@ describe("containers registries configure", () => {
`containers registries configure ${awsEcrDomain} --public-credential=test-access-key-id --secret-name=AWS_Secret_Access_Key`
);
});

it("should reuse existing secret with --skip-confirmation", async () => {
const storeId = "test-store-id-reuse";
const secretName = "existing_secret";

mockStdIn.send("test-secret-value");
mockListSecretStores([
{
id: storeId,
account_id: "some-account-id",
name: "Default",
created: "2024-01-01T00:00:00Z",
modified: "2024-01-01T00:00:00Z",
},
]);
mockListSecrets(storeId, [
{
id: "existing-secret-id",
store_id: storeId,
name: secretName,
comment: "",
scopes: ["containers"],
created: "2024-01-01T00:00:00Z",
modified: "2024-01-01T00:00:00Z",
status: "active",
},
]);
mockPutRegistry({
domain: awsEcrDomain,
is_public: false,
auth: {
public_credential: "test-access-key-id",
private_credential: {
store_id: storeId,
secret_name: secretName,
},
},
kind: "ECR",
});

await runWrangler(
`containers registries configure ${awsEcrDomain} --public-credential=test-access-key-id --secret-name=${secretName} --skip-confirmation`
);

// Should not contain "created" message since we reused existing secret
expect(cliStd.stdout).not.toContain("created in Secrets Store");
});
});
});
});
Expand Down
1 change: 1 addition & 0 deletions packages/wrangler/src/__tests__/init.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ describe("init", () => {
type: "yarn",
npx: "yarn",
dlx: ["yarn", "dlx"],
lockFiles: ["yarn.lock"],
};
(getPackageManager as Mock).mockResolvedValue(mockPackageManager);

Expand Down
15 changes: 15 additions & 0 deletions packages/wrangler/src/autoconfig/details.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { Project } from "@netlify/build-info";
import { NodeFS } from "@netlify/build-info/node";
import { captureException } from "@sentry/node";
import chalk from "chalk";
import dedent from "ts-dedent";
import { getCacheFolder } from "../config-cache";
import { getErrorType } from "../core/handle-errors";
Expand Down Expand Up @@ -231,6 +232,20 @@ async function detectFramework(
// This is populated after getBuildSettings() runs, which triggers the full detection chain.
const packageManager = convertDetectedPackageManager(project.packageManager);

const lockFileExists = packageManager.lockFiles.some((lockFile) =>
existsSync(join(projectPath, lockFile))
);

if (!lockFileExists) {
logger.warn(
"No lock file has been detected in the current working directory." +
" This might indicate that the project is part of a workspace. Auto-configuration of " +
`projects inside workspaces is limited. See ${chalk.hex("#3B818D")(
"https://developers.cloudflare.com/workers/framework-guides/automatic-configuration/#workspaces"
)}`
);
}

if (await isPagesProject(projectPath, wranglerConfig, detectedFramework)) {
return {
detectedFramework: {
Expand Down
6 changes: 3 additions & 3 deletions packages/wrangler/src/autoconfig/frameworks/utils/packages.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { parsePackageJSON, readFileSync } from "@cloudflare/workers-utils";
import { findUpSync } from "find-up";
import * as find from "empathic/find";

/**
* Checks wether a package is installed in a target project or not
Expand Down Expand Up @@ -35,9 +35,9 @@ export function getInstalledPackageVersion(
if (!packagePath) {
return undefined;
}
const packageJsonPath = findUpSync("package.json", {
const packageJsonPath = find.file("package.json", {
cwd: packagePath,
stopAt: opts.stopAtProjectPath === true ? projectPath : undefined,
last: opts.stopAtProjectPath === true ? projectPath : undefined,
});
if (!packageJsonPath) {
return undefined;
Expand Down
6 changes: 2 additions & 4 deletions packages/wrangler/src/config-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from "node:fs";
import * as path from "node:path";
import { getWranglerCacheDirFromEnv } from "@cloudflare/workers-utils";
import { findUpSync } from "find-up";
import * as find from "empathic/find";
import { isNonInteractiveOrCI } from "./is-interactive";
import { logger } from "./logger";

Expand All @@ -29,9 +29,7 @@ export function getCacheFolder(): string {
}

// Find node_modules using existing find-up logic
const closestNodeModulesDirectory = findUpSync("node_modules", {
type: "directory",
});
const closestNodeModulesDirectory = find.dir("node_modules");

const nodeModulesCache = closestNodeModulesDirectory
? path.join(closestNodeModulesDirectory, ".cache", "wrangler")
Expand Down
Loading
Loading