Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
9 changes: 9 additions & 0 deletions .changeset/funny-toes-exist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@opennextjs/cloudflare": patch
---

Use `OPEN_NEXT_BUILD_ID` instead of `NEXT_BUILD_ID` in the cache keys.

As of Next 16.2 `NEXT_BUILD_ID` is a fixed value when deploymentId is set explicitly.

See <https://github.com/opennextjs/opennextjs-aws/pull/1144>
2 changes: 1 addition & 1 deletion packages/cloudflare/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"dependencies": {
"@ast-grep/napi": "^0.40.5",
"@dotenvx/dotenvx": "catalog:",
"@opennextjs/aws": "3.10.2",
"@opennextjs/aws": "https://pkg.pr.new/@opennextjs/aws@1149",
Comment thread
vicb marked this conversation as resolved.
Outdated
"ci-info": "^4.2.0",
"cloudflare": "^4.4.1",
"comment-json": "^4.5.1",
Expand Down
8 changes: 4 additions & 4 deletions packages/cloudflare/src/api/durable-objects/queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export class DOQueueHandler extends DurableObject<CloudflareEnv> {
"INSERT OR REPLACE INTO sync (id, lastSuccess, buildId) VALUES (?, unixepoch(), ?)",
// We cannot use the deduplication id because it's not unique per route - every time a route is revalidated, the deduplication id is different.
`${host}${url}`,
process.env.__NEXT_BUILD_ID
process.env.__OPEN_NEXT_BUILD_ID
);
}
// If everything went well, we can remove the route from the failed state
Expand Down Expand Up @@ -238,7 +238,7 @@ export class DOQueueHandler extends DurableObject<CloudflareEnv> {
"INSERT OR REPLACE INTO failed_state (id, data, buildId) VALUES (?, ?, ?)",
msg.MessageDeduplicationId,
JSON.stringify(updatedFailedState),
process.env.__NEXT_BUILD_ID
process.env.__OPEN_NEXT_BUILD_ID
);
}
// We probably want to do something if routeInFailedState is becoming too big, at least log it
Expand Down Expand Up @@ -273,8 +273,8 @@ export class DOQueueHandler extends DurableObject<CloudflareEnv> {

// Before doing anything else, we clear the DB for any potential old data
// TODO: extract this to a function so that it could be called by the user at another time than init
this.sql.exec("DELETE FROM failed_state WHERE buildId != ?", process.env.__NEXT_BUILD_ID);
this.sql.exec("DELETE FROM sync WHERE buildId != ?", process.env.__NEXT_BUILD_ID);
this.sql.exec("DELETE FROM failed_state WHERE buildId != ?", process.env.__OPEN_NEXT_BUILD_ID);
this.sql.exec("DELETE FROM sync WHERE buildId != ?", process.env.__OPEN_NEXT_BUILD_ID);

const failedStateCursor = this.sql.exec<{ id: string; data: string }>("SELECT * FROM failed_state");
for (const row of failedStateCursor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class KVIncrementalCache implements IncrementalCache {
protected getKVKey(key: string, cacheType?: CacheEntryType): string {
return computeCacheKey(key, {
prefix: getCloudflareContext().env[PREFIX_ENV_NAME],
buildId: process.env.NEXT_BUILD_ID,
buildId: process.env.OPEN_NEXT_BUILD_ID,
cacheType,
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class R2IncrementalCache implements IncrementalCache {
protected getR2Key(key: string, cacheType?: CacheEntryType): string {
return computeCacheKey(key, {
prefix: getCloudflareContext().env[PREFIX_ENV_NAME],
buildId: process.env.NEXT_BUILD_ID,
buildId: process.env.OPEN_NEXT_BUILD_ID,
cacheType,
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ class RegionalCache implements IncrementalCache {
}

protected getCacheUrlKey(key: string, cacheType?: CacheEntryType) {
const buildId = process.env.NEXT_BUILD_ID ?? FALLBACK_BUILD_ID;
const buildId = process.env.OPEN_NEXT_BUILD_ID ?? FALLBACK_BUILD_ID;
return "http://cache.local" + `/${buildId}/${key}`.replace(/\/+/g, "/") + `.${cacheType ?? "cache"}`;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class StaticAssetsIncrementalCache implements IncrementalCache {
if (cacheType === "composable") {
throw new Error("Composable cache is not supported in static assets incremental cache");
}
const buildId = process.env.NEXT_BUILD_ID ?? FALLBACK_BUILD_ID;
const buildId = process.env.OPEN_NEXT_BUILD_ID ?? FALLBACK_BUILD_ID;
const name = (
cacheType === "fetch"
? `${CACHE_DIR}/__fetch/${buildId}/${key}`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,10 @@ describe("D1NextModeTagCache", () => {
expect(error).toHaveBeenCalledWith(mockError);
});

it("should use custom build ID when NEXT_BUILD_ID is set", async () => {
it("should prefer OPEN_NEXT_BUILD_ID when it is set", async () => {
const customBuildId = "custom-build-id";
vi.stubEnv("NEXT_BUILD_ID", customBuildId);
vi.stubEnv("NEXT_BUILD_ID", "legacy-build-id");
vi.stubEnv("OPEN_NEXT_BUILD_ID", customBuildId);

mockRaw.mockResolvedValue([[`${customBuildId}/tag1`, 123, 123, null]]);

Expand Down Expand Up @@ -534,9 +535,9 @@ describe("D1NextModeTagCache", () => {
expect(cacheKey).toBe(`${FALLBACK_BUILD_ID}/${key}`);
});

it("should use custom build ID when NEXT_BUILD_ID is set", () => {
it("should use custom build ID when OPEN_NEXT_BUILD_ID is set", () => {
const customBuildId = "custom-build-id";
vi.stubEnv("NEXT_BUILD_ID", customBuildId);
vi.stubEnv("OPEN_NEXT_BUILD_ID", customBuildId);

const key = "test-tag";
const cacheKey = (tagCache as unknown as { getCacheKey: (key: string) => string }).getCacheKey(key);
Expand All @@ -545,7 +546,7 @@ describe("D1NextModeTagCache", () => {
});

it("should handle double slashes by replacing them with single slash", () => {
vi.stubEnv("NEXT_BUILD_ID", "build//id");
vi.stubEnv("OPEN_NEXT_BUILD_ID", "build//id");

const key = "test-tag";
const cacheKey = (tagCache as unknown as { getCacheKey: (key: string) => string }).getCacheKey(key);
Expand All @@ -555,16 +556,16 @@ describe("D1NextModeTagCache", () => {
});

describe("getBuildId", () => {
it("should return NEXT_BUILD_ID when set", () => {
it("should return OPEN_NEXT_BUILD_ID when set", () => {
const customBuildId = "custom-build-id";
vi.stubEnv("NEXT_BUILD_ID", customBuildId);
vi.stubEnv("OPEN_NEXT_BUILD_ID", customBuildId);

const buildId = (tagCache as unknown as { getBuildId: () => string }).getBuildId();

expect(buildId).toBe(customBuildId);
});

it("should return fallback build ID when NEXT_BUILD_ID is not set", () => {
it("should return fallback build ID when no build ID env vars are set", () => {
const buildId = (tagCache as unknown as { getBuildId: () => string }).getBuildId();

expect(buildId).toBe(FALLBACK_BUILD_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ export class D1NextModeTagCache implements NextModeTagCache {
}

protected getBuildId() {
return process.env.NEXT_BUILD_ID ?? FALLBACK_BUILD_ID;
return process.env.OPEN_NEXT_BUILD_ID ?? FALLBACK_BUILD_ID;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,10 @@ describe("KVNextModeTagCache", () => {
expect(error).toHaveBeenCalledWith(mockError);
});

it("should use custom build ID when NEXT_BUILD_ID is set", async () => {
it("should prefer OPEN_NEXT_BUILD_ID when it is set", async () => {
const customBuildId = "custom-build-id";
vi.stubEnv("NEXT_BUILD_ID", customBuildId);
vi.stubEnv("NEXT_BUILD_ID", "legacy-build-id");
vi.stubEnv("OPEN_NEXT_BUILD_ID", customBuildId);

mockGet.mockResolvedValue(new Map([["tag1", null]]));

Expand Down Expand Up @@ -393,9 +394,9 @@ describe("KVNextModeTagCache", () => {
expect(cacheKey).toBe(`${FALLBACK_BUILD_ID}/${key}`);
});

it("should use custom build ID when NEXT_BUILD_ID is set", () => {
it("should use custom build ID when OPEN_NEXT_BUILD_ID is set", () => {
const customBuildId = "custom-build-id";
vi.stubEnv("NEXT_BUILD_ID", customBuildId);
vi.stubEnv("OPEN_NEXT_BUILD_ID", customBuildId);

const key = "test-tag";
const cacheKey = (tagCache as unknown as { getCacheKey: (key: string) => string }).getCacheKey(key);
Expand All @@ -404,7 +405,7 @@ describe("KVNextModeTagCache", () => {
});

it("should handle double slashes by replacing them with single slash", () => {
vi.stubEnv("NEXT_BUILD_ID", "build//id");
vi.stubEnv("OPEN_NEXT_BUILD_ID", "build//id");

const key = "test-tag";
const cacheKey = (tagCache as unknown as { getCacheKey: (key: string) => string }).getCacheKey(key);
Expand All @@ -414,18 +415,16 @@ describe("KVNextModeTagCache", () => {
});

describe("getBuildId", () => {
it("should return NEXT_BUILD_ID when set", () => {
it("should return OPEN_NEXT_BUILD_ID when set", () => {
const customBuildId = "custom-build-id";
vi.stubEnv("NEXT_BUILD_ID", customBuildId);
vi.stubEnv("OPEN_NEXT_BUILD_ID", customBuildId);

const buildId = (tagCache as unknown as { getBuildId: () => string }).getBuildId();

expect(buildId).toBe(customBuildId);
});

it("should return fallback build ID when NEXT_BUILD_ID is not set", () => {
// Environment variables are cleared by vi.unstubAllEnvs() in beforeEach

it("should return fallback build ID when no build ID env vars are set", () => {
const buildId = (tagCache as unknown as { getBuildId: () => string }).getBuildId();

expect(buildId).toBe(FALLBACK_BUILD_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ export class KVNextModeTagCache implements NextModeTagCache {
}

protected getBuildId() {
return process.env.NEXT_BUILD_ID ?? FALLBACK_BUILD_ID;
return process.env.OPEN_NEXT_BUILD_ID ?? FALLBACK_BUILD_ID;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createRequire } from "node:module";
import path from "node:path";

import { loadBuildId, loadPrerenderManifest } from "@opennextjs/aws/adapters/config/util.js";
import { loadBuildId, loadConfig, loadPrerenderManifest } from "@opennextjs/aws/adapters/config/util.js";
import { type BuildOptions, esbuildSync } from "@opennextjs/aws/build/helper.js";

export function compileDurableObjects(buildOpts: BuildOptions) {
Expand All @@ -17,6 +17,7 @@ export function compileDurableObjects(buildOpts: BuildOptions) {
const prerenderManifest = loadPrerenderManifest(buildOutputDotNextDir);
const previewModeId = prerenderManifest?.preview?.previewModeId;
const BUILD_ID = loadBuildId(buildOutputDotNextDir);
const nextConfig = loadConfig(buildOutputDotNextDir);

return esbuildSync(
{
Expand All @@ -28,7 +29,7 @@ export function compileDurableObjects(buildOpts: BuildOptions) {
external: ["cloudflare:workers"],
define: {
"process.env.__NEXT_PREVIEW_MODE_ID": `"${previewModeId}"`,
"process.env.__NEXT_BUILD_ID": `"${BUILD_ID}"`,
"process.env.__OPEN_NEXT_BUILD_ID": JSON.stringify(nextConfig.deploymentId ?? BUILD_ID),
},
},
buildOpts
Expand Down
14 changes: 7 additions & 7 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading