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
7 changes: 7 additions & 0 deletions .changeset/skip-api-project-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"cf": patch
---

Skip reading the compliance region from the config file when it is set in the environment

Resolve `CLOUDFLARE_COMPLIANCE_REGION` before project settings, matching the existing account ID priority. Commands with both `CLOUDFLARE_ACCOUNT_ID` and `CLOUDFLARE_COMPLIANCE_REGION` no longer evaluate a `cloudflare.config.ts` file solely to establish API context.
44 changes: 44 additions & 0 deletions packages/cli/src/__tests__/commands/api-config-loading.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { writeFile } from "node:fs/promises";
import { runInTempDir } from "@cloudflare/workers-utils/test-helpers";
import { http, HttpResponse } from "msw/http";
import { afterEach, describe, expect, it, vi } from "vite-plus/test";
import { server, setupMsw, TEST_BASE_URL } from "../helpers/msw.js";
import { runCf } from "../helpers/run-cf.js";

describe("API command project config loading", () => {
runInTempDir();
setupMsw();

afterEach(() => vi.restoreAllMocks());

it("does not load project config when account ID and compliance region are in the environment", async () => {
await writeFile(
"cloudflare.config.ts",
`import "a-package-that-does-not-exist"; export default {};`
);
vi.spyOn(console, "log").mockImplementation(() => undefined);
let requested = false;
server.use(
http.get(
`${TEST_BASE_URL}/accounts/account-1/workers/scripts-search`,
() => {
requested = true;
return HttpResponse.json({ success: true, result: [] });
}
)
);

const result = await runCf(
["workers", "scripts", "search", "--name", "x"],
{
CLOUDFLARE_API_BASE_URL: TEST_BASE_URL,
CLOUDFLARE_API_TOKEN: "test-token",
CLOUDFLARE_ACCOUNT_ID: "account-1",
CLOUDFLARE_COMPLIANCE_REGION: "public",
}
);

expect(result.exitCode).toBe(0);
expect(requested).toBe(true);
});
});
22 changes: 5 additions & 17 deletions packages/cli/src/__tests__/lib/context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,27 +156,15 @@ describe("context", () => {
await expect(getComplianceRegion()).resolves.toBe("fedramp_high");
});

it("prioritises the legacy env representation", async () => {
it("reads the environment before loading project settings", async () => {
writeFileSync(
join(process.cwd(), "cloudflare.config.ts"),
`throw new Error("project config should not be loaded");`
);
vi.stubEnv("CLOUDFLARE_COMPLIANCE_REGION", "fedramp_high");
await expect(getComplianceRegion()).resolves.toBe("fedramp_high");
});

it("warns when the environment overrides project settings", async () => {
const warn = vi
.spyOn(console, "warn")
.mockImplementation(() => undefined);
vi.stubEnv("CLOUDFLARE_COMPLIANCE_REGION", "public");
writeProjectSettings({ complianceRegion: "fedramp-high" });

await expect(getComplianceRegion()).resolves.toBe("public");
await expect(getComplianceRegion()).resolves.toBe("public");

expect(warn).toHaveBeenCalledOnce();
expect(warn).toHaveBeenCalledWith(
'The compliance region was resolved to "public" from the `CLOUDFLARE_COMPLIANCE_REGION` environment variable, which takes precedence over the configured value "fedramp-high" in `cloudflare.config.ts`.'
);
});

it("throws on an invalid value", async () => {
vi.stubEnv("CLOUDFLARE_COMPLIANCE_REGION", "invalid");
await expect(getComplianceRegion()).rejects.toThrow(
Expand Down
37 changes: 10 additions & 27 deletions packages/cli/src/lib/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,6 @@ const VALID_COMPLIANCE_REGIONS = ["public", "fedramp_high"] as const;

export type ComplianceRegion = (typeof VALID_COMPLIANCE_REGIONS)[number];

let complianceRegionConflictsReported = false;

/**
* Resolve the compliance region in the representation consumed by
* workers-auth/workers-utils. cloudflare.config.ts uses `fedramp-high`, which
Expand All @@ -213,38 +211,23 @@ let complianceRegionConflictsReported = false;
async function resolveComplianceRegion(
options: { isPreview?: boolean } = {}
): Promise<ComplianceRegion | undefined> {
const envRegion = normalizeComplianceRegion(
process.env.CLOUDFLARE_COMPLIANCE_REGION,
"CLOUDFLARE_COMPLIANCE_REGION"
);
if (envRegion) {
return envRegion;
}

const preloadedProjectSettings = getLoadedProjectSettings(undefined, options);
const projectSettings =
preloadedProjectSettings === undefined
? await loadProjectSettings(undefined, options)
: preloadedProjectSettings;
const configuredValue = projectSettings?.settings?.complianceRegion;
const configureRegion = normalizeComplianceRegion(
configuredValue,
return normalizeComplianceRegion(
projectSettings?.settings?.complianceRegion,
"cloudflare.config.ts"
);
const envValue = process.env.CLOUDFLARE_COMPLIANCE_REGION;
const envRegion = normalizeComplianceRegion(
envValue,
"CLOUDFLARE_COMPLIANCE_REGION"
);

if (!envRegion) {
return configureRegion;
}

if (
configureRegion &&
configureRegion !== envRegion &&
!complianceRegionConflictsReported
) {
complianceRegionConflictsReported = true;
console.warn(
`The compliance region was resolved to "${envValue}" from the \`CLOUDFLARE_COMPLIANCE_REGION\` environment variable, which takes precedence over the configured value "${configuredValue}" in \`cloudflare.config.ts\`.`
);
}

return envRegion;
}

/** Get the compliance region, defaulting to public. */
Expand Down
Loading