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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,11 @@ Both CI and manual deployments include `config/production.env` through
`worker.vars`. Production deployment starts only after staging passes.
`void deploy` never uploads the local `.env`.

The pinned `void@0.27.0` dependency has a patch in `patches/` because its managed
deployment code otherwise discards `worker.vars`. The patch includes these values
in the deployment manifest. Keep it until Void includes this fix. The deployment
smoke check probes each configured package pattern against the running Worker.

**Migration for existing projects:** remove the public keys previously uploaded
to remote secret storage in both production and staging. A remote secret with
the same name takes precedence over `worker.vars`, so leaving those entries
Expand Down
22 changes: 22 additions & 0 deletions patches/void@0.27.0.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
diff --git a/dist/deploy-Bqe1PYBw.mjs b/dist/deploy-Bqe1PYBw.mjs
index f47d40b72817476b5d55c0f6edc5a349f927c4b5..e3100149fbc8ab2e3ccd461a4d640c2f54d98891 100644
--- a/dist/deploy-Bqe1PYBw.mjs
+++ b/dist/deploy-Bqe1PYBw.mjs
@@ -9011,7 +9011,7 @@ async function runFrameworkDeploy(root, config, client, detected, fwPreset, void
const revalidate = collectRevalidate(voidConfig, null);
const prerender = voidConfig.routing?.isr === false ? void 0 : voidConfig.routing?.prerender;
const { schedules, queues } = toManifestSchedulesAndQueues(rawJobs, rawQueues);
- const envVars = {};
+ const envVars = voidConfig.worker?.vars ?? {};
await assertEnvSchemaValid(root, client, config.projectId);
const s = createSpinner();
const onProgress = (msg) => s.message(msg);
@@ -9629,7 +9629,7 @@ async function runFullDeploy(root, config, client, voidConfig, fwPreset, skipBui
needsSandbox: bindings.needsSandbox
});
const workerMain = resolveDeployWorkerMain(voidConfig, join(distDir, workerDirName));
- const envVars = {};
+ const envVars = voidConfig.worker?.vars ?? {};
await assertEnvSchemaValid(root, client, config.projectId);
const s = createSpinner();
const onProgress = (msg) => s.message(msg);
9 changes: 6 additions & 3 deletions pnpm-lock.yaml

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

5 changes: 4 additions & 1 deletion pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ catalog:
vite: npm:@voidzero-dev/vite-plus-core@1.1.0
vite-plus: 1.1.0
vitest: 5.0.3
void: ^0.27.0
# Keep the managed-deploy vars patch until an upstream release includes it.
void: 0.27.0
overrides:
vite@*: 'catalog:'
vitest@*: 'catalog:'
Expand All @@ -38,3 +39,5 @@ peerDependencyRules:
allowedVersions:
vite: '*'
vitest: '*'
patchedDependencies:
void@0.27.0: patches/void@0.27.0.patch
6 changes: 5 additions & 1 deletion scripts/lib/config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,15 @@ function parseEnvFile(file) {
return out
}

/** Read PUBLIC_BASE_URL from the public production settings. */
/** Read public production settings used by the deployment checks. */
export function readConfig() {
const production = parseEnvFile(path.join(root, 'config', 'production.env'))
return {
baseUrl: production.PUBLIC_BASE_URL || '',
workspacePackages: (production.WORKSPACE_PACKAGES || '')
.split(',')
.map((name) => name.trim())
.filter(Boolean),
}
}

Expand Down
23 changes: 22 additions & 1 deletion scripts/smoke-test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import { createTarGzip } from 'nanotar'
import { createHash } from 'node:crypto'
import { refToVersion } from './lib/config.mjs'
import { readConfig, refToVersion } from './lib/config.mjs'

const args = process.argv.slice(2)
const WRITE = args.includes('--write')
Expand Down Expand Up @@ -233,6 +233,27 @@ const checks = [
},
]

// An invalid version reaches the allowlist check without reading or writing R2.
// Probe every configured pattern so stale remote settings cannot hide new names.
const { workspacePackages } = readConfig()
assert(workspacePackages.length > 0, 'WORKSPACE_PACKAGES must contain at least one package pattern')
for (const pattern of workspacePackages) {
const name = pattern.endsWith('*') ? `${pattern.slice(0, -1)}smoke-config-check` : pattern
checks.push({
name: `workspace allowlist accepts ${name}`,
async run() {
const res = await fetch(`${base}/tarballs/${encodeURIComponent(name)}/invalid-version.tgz`)
const body = await res.text()
console.log(` ${res.status} ${truncate(body)}`)
assert(res.status === 400, `status ${res.status}: ${truncate(body)}`)
assert(
JSON.parse(body)?.error === 'Invalid preview version: invalid-version',
'unexpected error',
)
},
})
}

if (WRITE) {
// Not retried (`retry: false`): a retry after a partial run would false-fail
// the "invisible before register" gate, and the sha is unique per run anyway.
Expand Down
Loading