Skip to content

Commit 98e619d

Browse files
authored
Merge pull request #437 from cloudflare/deploy-button-config
fix: gate artifacts binding on ENABLE_ARTIFACTS during deploy
2 parents a651a52 + 8191265 commit 98e619d

4 files changed

Lines changed: 84 additions & 3 deletions

File tree

.github/workflows/deploy-release-live.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ jobs:
5353
CI: true
5454
WRANGLER_NON_INTERACTIVE: true
5555

56+
# Production runs on an account with Cloudflare Artifacts access. Keep the
57+
# ARTIFACTS binding: the deploy script drops it unless this is "true".
58+
ENABLE_ARTIFACTS: "true"
59+
5660
# Prefer repo variables for non-sensitive config.
5761
CUSTOM_DOMAIN: ${{ vars.CUSTOM_DOMAIN }}
5862
CUSTOM_PREVIEW_DOMAIN: ${{ vars.CUSTOM_PREVIEW_DOMAIN }}

.github/workflows/deploy-staging.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ jobs:
5656
# Target the staging wrangler config instead of the prod one.
5757
WRANGLER_CONFIG_PATH: wrangler.staging.jsonc
5858

59+
# Staging runs on an account with Cloudflare Artifacts access. Keep the
60+
# ARTIFACTS binding: the deploy script drops it unless this is "true".
61+
ENABLE_ARTIFACTS: "true"
62+
5963
# Staging-specific overrides. These take priority over wrangler.staging.jsonc vars.
6064
CUSTOM_DOMAIN: staging.build.cloudflare.dev
6165
CUSTOM_PREVIEW_DOMAIN: staging.build.cloudflare.dev

scripts/deploy.ts

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ interface WranglerConfig {
6565
custom_domain: boolean;
6666
zone_id?: string;
6767
}>;
68+
artifacts?: Array<{
69+
binding: string;
70+
namespace: string;
71+
}>;
6872
vars?: {
6973
TEMPLATES_REPOSITORY?: string;
7074
CLOUDFLARE_AI_GATEWAY?: string;
@@ -101,6 +105,7 @@ class CloudflareDeploymentManager {
101105
private cloudflare: Cloudflare;
102106
private aiGatewayCloudflare?: Cloudflare; // Separate SDK instance for AI Gateway operations
103107
private conflictingVarsForCleanup: Record<string, string> | null = null; // For signal cleanup
108+
private artifactsBindingBackup: WranglerConfig['artifacts'] | null = null; // Restored after deploy when temporarily removed
104109

105110
constructor() {
106111
this.validateEnvironment();
@@ -125,9 +130,10 @@ class CloudflareDeploymentManager {
125130

126131
try {
127132
// Restore conflicting vars using existing restoration method
128-
if (this.conflictingVarsForCleanup) {
133+
if (this.conflictingVarsForCleanup || this.artifactsBindingBackup) {
129134
console.log('🔄 Restoring original wrangler.jsonc configuration...');
130135
await this.restoreOriginalVars(this.conflictingVarsForCleanup);
136+
this.restoreArtifactsBinding();
131137
} else {
132138
console.log('ℹ️ No configuration changes to restore');
133139
}
@@ -1962,6 +1968,71 @@ class CloudflareDeploymentManager {
19621968
}
19631969
}
19641970

1971+
/**
1972+
* Whether Cloudflare Artifacts should be enabled for this deployment.
1973+
* Controlled by ENABLE_ARTIFACTS (env var takes priority over wrangler vars).
1974+
* Cloudflare Artifacts is a closed beta; accounts without access cannot
1975+
* deploy a Worker that declares the ARTIFACTS binding.
1976+
*/
1977+
private artifactsEnabled(): boolean {
1978+
const value = (process.env.ENABLE_ARTIFACTS ?? this.config.vars?.ENABLE_ARTIFACTS ?? '')
1979+
.toString()
1980+
.trim()
1981+
.toLowerCase();
1982+
return value === 'true';
1983+
}
1984+
1985+
/**
1986+
* Removes the `artifacts` binding from the wrangler config before deploy
1987+
* when Artifacts is not enabled. Without access to the closed beta, declaring
1988+
* the binding fails `wrangler deploy` (code 10015). The binding is unused when
1989+
* ENABLE_ARTIFACTS is not "true", so it is safe to drop. Backed up for restore.
1990+
*/
1991+
private removeArtifactsBindingIfDisabled(): void {
1992+
if (this.artifactsEnabled()) {
1993+
console.log('✅ ENABLE_ARTIFACTS="true" - keeping ARTIFACTS binding');
1994+
return;
1995+
}
1996+
1997+
try {
1998+
const { content, config } = this.readWranglerConfig();
1999+
if (!config.artifacts) {
2000+
return;
2001+
}
2002+
2003+
this.artifactsBindingBackup = config.artifacts;
2004+
const edits = modify(content, ['artifacts'], undefined, CloudflareDeploymentManager.JSONC_FORMAT_OPTIONS);
2005+
this.writeWranglerConfig(applyEdits(content, edits));
2006+
this.logSuccess('Removed ARTIFACTS binding for deploy (ENABLE_ARTIFACTS is not "true")');
2007+
} catch (error) {
2008+
this.logWarning(`Could not remove ARTIFACTS binding: ${error instanceof Error ? error.message : String(error)}`, [
2009+
'Continuing with deployment...'
2010+
]);
2011+
}
2012+
}
2013+
2014+
/**
2015+
* Restores the `artifacts` binding removed by removeArtifactsBindingIfDisabled.
2016+
*/
2017+
private restoreArtifactsBinding(): void {
2018+
if (!this.artifactsBindingBackup) {
2019+
return;
2020+
}
2021+
2022+
try {
2023+
const { content } = this.readWranglerConfig();
2024+
const edits = modify(content, ['artifacts'], this.artifactsBindingBackup, CloudflareDeploymentManager.JSONC_FORMAT_OPTIONS);
2025+
this.writeWranglerConfig(applyEdits(content, edits));
2026+
this.logSuccess('Restored ARTIFACTS binding to wrangler config');
2027+
} catch (error) {
2028+
this.logWarning(`Could not restore ARTIFACTS binding: ${error instanceof Error ? error.message : String(error)}`, [
2029+
'You may need to manually restore the artifacts binding in the wrangler config'
2030+
]);
2031+
} finally {
2032+
this.artifactsBindingBackup = null;
2033+
}
2034+
}
2035+
19652036
/**
19662037
* Runs database migrations
19672038
*/
@@ -2010,6 +2081,9 @@ class CloudflareDeploymentManager {
20102081
console.log(' 🔧 Updating container instance types');
20112082
this.updateContainerInstanceTypes();
20122083

2084+
console.log(' 🔧 Configuring Artifacts binding');
2085+
this.removeArtifactsBindingIfDisabled();
2086+
20132087
console.log('✅ Configuration files updated successfully!\n');
20142088

20152089
// Step 1.5: Check dispatch namespace availability early
@@ -2087,6 +2161,7 @@ class CloudflareDeploymentManager {
20872161
// Step 7: Always restore original vars (even if deployment failed)
20882162
console.log('\n📋 Step 7: Restoring original configuration...');
20892163
await this.restoreOriginalVars(conflictingVars);
2164+
this.restoreArtifactsBinding();
20902165

20912166
// Clear the backup since we've restored
20922167
this.conflictingVarsForCleanup = null;

wrangler.jsonc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,6 @@
224224
"version": "1.0.0"
225225
},
226226
"CUSTOM_DOMAIN": "",
227-
// Cloudflare Artifacts is in closed beta; enable only for accounts with access.
228-
"ENABLE_ARTIFACTS": "false",
229227
"MAX_SANDBOX_INSTANCES": "10",
230228
"SANDBOX_INSTANCE_TYPE": "standard-3",
231229
"DEV_BROWSER_SIDECAR_URL": "http://127.0.0.1:9223",

0 commit comments

Comments
 (0)