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/cli-dynamic-compat-date.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bigcommerce/catalyst": patch
---

`catalyst build` now derives the Cloudflare Workers `compatibility_date` dynamically (current date minus one month) instead of using a pinned date, keeping the build-time runtime semantics aligned with what the deployment service applies at deploy time.
16 changes: 15 additions & 1 deletion packages/catalyst/src/cli/lib/wrangler-config.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, test } from 'vitest';

import { getWranglerConfig } from './wrangler-config';
import { getCompatibilityDate, getWranglerConfig } from './wrangler-config';

test('returns a config with name identical to worker self reference service', () => {
const config = getWranglerConfig('uuid');
Expand All @@ -10,3 +10,17 @@ test('returns a config with name identical to worker self reference service', ()
config.services.find((service) => service.binding === 'WORKER_SELF_REFERENCE')?.service,
).toBe(`project-uuid`);
});

test('compatibility date is one month before the given date', () => {
expect(getCompatibilityDate(new Date('2026-06-11T15:00:00Z'))).toBe('2026-05-11');
});

test('compatibility date handles month-end normalization', () => {
// May 31 minus one month lands in early May (no April 31), still a valid date.
expect(getCompatibilityDate(new Date('2026-05-31T12:00:00Z'))).toBe('2026-05-01');
expect(getCompatibilityDate(new Date('2026-01-15T00:00:00Z'))).toBe('2025-12-15');
});

test('config uses a YYYY-MM-DD compatibility date', () => {
expect(getWranglerConfig('uuid').compatibility_date).toMatch(/^\d{4}-\d{2}-\d{2}$/u);
});
20 changes: 19 additions & 1 deletion packages/catalyst/src/cli/lib/wrangler-config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
// The compatibility date, compatibility flags, Durable Object classes, and
// migration tag below are mirrored in Ignition, which builds its own Worker
// metadata at deploy time (pkg/cloudflare/upload/metadata.go and
// pkg/cloudflare/upload/migrations/migrations.go). Keep both sides in sync
// when changing any of them.
export function getCompatibilityDate(now = new Date()): string {
const date = new Date(now);

// One month behind the current date: recent enough to track Cloudflare
// runtime behavior (per Cloudflare guidance), buffered enough to avoid
// brand-new compatibility-date-gated changes. Ignition applies the same
// offset at deploy time, so the bundle is never built against newer
// semantics than it runs under.
date.setUTCMonth(date.getUTCMonth() - 1);

return date.toISOString().slice(0, 10);
}

export function getWranglerConfig(projectUuid: string) {
return {
$schema: 'node_modules/wrangler/config-schema.json',
main: '../.open-next/worker.js',
name: `project-${projectUuid}`,
compatibility_date: '2025-09-15',
compatibility_date: getCompatibilityDate(),
compatibility_flags: ['nodejs_compat', 'global_fetch_strictly_public'],
observability: {
enabled: true,
Expand Down
Loading