Repository navigation
feat: add volcano deploy to deploy a whole project in one run - #298
Conversation
e139ce9 to
752c42d
Compare
f4d9959 to
9105884
Compare
subnetmarco
left a comment
There was a problem hiding this comment.
The overall shape works well. Every input is checked before anything changes, the resume hints are precise, and the E2E coverage in both modes is thorough. The touched packages' unit tests pass locally for me. I'd fix one issue before merging; the rest are smaller.
Fix before merging: the cloud deploy uses the local env file by default. volcano init and base/volcano/README.md both print volcano cloud deploy with no --env-file. That deploys volcano/volcano.env, which holds the local server's values, to the cloud project. This PR also adds NEXT_PUBLIC_VOLCANO_API_URL=http://localhost:8000 to that file, so the cloud frontend gets compiled against localhost. Details are inline on init.go.
Smaller issues (details inline):
- A
supersededdeployment counts as success. The config step can supersede deployments this run just started, and the run then exits 0 without waiting for the deployments that actually serve. - Only the first manifest decides which functions are durable. With
-c auth.yaml -c volcano-config.yaml, durable functions get created as standard functions. A function's kind can't change after creation. -dwithout--with-migrationsis silently ignored.- Frontend uploads rely on the root
.gitignoreto keepvolcano/*.envout. That works for new starters. A project scaffolded before this release has no such line, so once it adds a.volcano/source-layout.jsonwith"workspace": "", itsvolcano/volcano.env(including the service key) goes into the frontend's source archive. Since the packager already excludes.env*.localunconditionally, I'd excludevolcano/*.envthe same way rather than depend on the user's.gitignore. docs/deploy.mdshould say which env file a cloud deploy should use. That part depends on how the first issue gets resolved.
752c42d to
eb05e1d
Compare
9105884 to
fcc2806
Compare
|
Addressed all of these; details are in the inline replies. The two without a thread:
|
swkeever
left a comment
There was a problem hiding this comment.
Requesting changes for one issue: when -c leaves out volcano/volcano-config.yaml, durable functions declared there are created as standard functions, and a function's kind can't change afterward (inline on plan.go:95).
The rest looks solid: step order is right, refusals happen before anything changes, both modes have E2E, and the strings hosting#1797 asserts and the commands skills#58 teaches all match what this ships. Other findings are inline; none block on their own.
One without a line to anchor: an --env-file outside volcano/ (e.g. a root cloud.env) still lands in frontend uploads that archive the project root. The packager could also exclude the file this run deploys.
eb05e1d to
f72d573
Compare
fcc2806 to
c91777c
Compare
swkeever
left a comment
There was a problem hiding this comment.
Both blocking issues are fixed. -c volcano/auth.yaml is now refused when volcano/volcano-config.yaml declares durable functions the first manifest doesn't (checkDefaultManifest). The Git refusal prints variables deploy -f <env file> with the file this run already checked for local values. The other earlier items check out too: two manifests declaring the same variable section are refused, --no-env-file ends the rename loop, the wait follows a redeploy queued behind an active deployment, and the deployed env file stays out of frontend uploads.
Build, lint, and the touched packages' unit tests pass locally.
One gap remains in the resume hint (inline on plan.go:547). It needs a first manifest other than the default and a failed functions step, so I'm not blocking on it. It ends in the same unchangeable kind, though.
f72d573 to
6f515f4
Compare
f03b988 to
70d7f74
Compare
`volcano deploy` (local) and `volcano cloud deploy` deploy variables, migrations (with --with-migrations), functions, durable functions, the frontends listed in .volcano/source-layout.json, and the config manifests, in that order, then wait for every deployment to finish. A deployment the config step supersedes hands the wait to the newer one. Inputs are checked before anything changes. A failed step names what already ran and the commands that finish the rest. A cloud deploy refuses an env file holding the local server's keys or a localhost VOLCANO_API_URL. `volcano init` now prints the one command, with --env-file volcano/cloud.env for the cloud, and the Next.js starters ship a source layout and the frontend variable selection their builds need. Frontend uploads always leave out volcano/*.env. Co-authored-by: Cursor <cursoragent@cursor.com>
Volcano's Postgres proxy refuses a query holding more than one statement, and migrations send each file as one query, so 'volcano migrations deploy' failed on the starter's 001_create_notes.sql. Co-authored-by: Cursor <cursoragent@cursor.com>
…ed redeploys, add --no-env-file Co-authored-by: Cursor <cursoragent@cursor.com>
…read Co-authored-by: Cursor <cursoragent@cursor.com>
70d7f74 to
1046c67
Compare
Summary
Third of three stacked PRs; based on PR2. Adds one command that deploys a whole project.
Before, a new Next.js project printed ten commands to run by hand:
After:
volcano deploy(local) andvolcano cloud deployrun, in order: variables, migrations (only with--with-migrations), functions, durable functions, the frontends listed in.volcano/source-layout.json, and the config manifests. Then they wait for every deployment, print each result and the frontend URLs, and exit non-zero if one failed.--no-waitskips the wait.--env-file,--no-env-file(for a project whose manifest owns its variables), repeatable-c/--config,-d/--database,--no-frontendsvariablessection together, since applying that section deletes the env file's variables. The refusal points at--no-env-filevariables,shared_variables, orfrontend_shared_variablessection, for the same reason--env-filetogether with--no-env-fileVOLCANO_API_URL/NEXT_PUBLIC_VOLCANO_API_URL. The starters'volcano/volcano.envholds exactly those, and a cloud frontend would compile the localhost URL in.-dwithout--with-migrations, which would otherwise skip migrations silentlykind: durableor a frontend'svariable_scope/variables. The code steps read those from the first manifest only, and a function created as the wrong kind can't change.-cmanifests that leave outvolcano/volcano-config.yamlwhile it declares durable functions the first manifest doesn't, which would create them as standard functionsvariables deploy -f <env file>andconfig deployfor the parts a deploy can still handle.variable_scope/variablesselection from the primary manifest, becauseNEXT_PUBLIC_*values are compiled into the buildvolcano initprints the one command; for the cloud,volcano cloud deploy --env-file volcano/cloud.env, with a line saying that file holds the cloud project's variables. The base starter's README says the same. The Next.js starters ship.volcano/source-layout.json, a scoped frontend variable selection, andvolcano/*.envin the root.gitignore.NEXT_PUBLIC_VOLCANO_API_URL,NEXT_PUBLIC_VOLCANO_ANON_KEY, andNEXT_PUBLIC_VOLCANO_DATABASE. Frontend builds drop everyVOLCANO_*name, so selectingVOLCANO_ANON_KEYbuilt a browser bundle with no key; the cloud E2E caught it. Local builds don't drop the prefix, which is why local mode passed.volcano migrations deploywas already failing on it; the new local-mode E2E caught it.docs/databases.mdand the starter's migrations README now state the rule.docs/deploy.mdis new; the README quickstart,docs/README.md, and the functions, durable, variables, frontends, and configuration pages point at it.volcano/source-layout.jsonis checked with the same path rules as the Git deploy parser, so a layout the CLI accepts is one Git acceptsBehavior changes outside the new command:
app_rootwithout its ownpackage.jsonwhen a parentpackage.jsonbuilds it withnext build <dir>, the layoutvolcano init nextjscreates. Previously--app-root webon that layout was refused..gitignorefiles listvolcano/*.env; the basevolcano/.gitignoreignores*.env, socloud.envstays out of Git toovolcano/*.envandvolcano.env, like.env*.local, andvolcano deployalso leaves out the env file it deployed, wherever it is. A project scaffolded before the.gitignoreline, deploying a frontend from the project root, would otherwise upload its service key.volcano/volcano.env(and.example) carriesNEXT_PUBLIC_VOLCANO_API_URL,NEXT_PUBLIC_VOLCANO_ANON_KEY, andNEXT_PUBLIC_VOLCANO_DATABASEwith the local values, so every new project has the names a Next.js frontend readsOpen questions:
--dry-runis not in v1.volcano cloud config deploy --dry-runstill previews config.allorscopedselection. For an entry withvariable_scope: shared, or a missing field, the run warns: the build uses the frontend's current selection, the config step applies the new one, and the next deploy rebuilds with it.Coordinated changes, all on branch
feat/volcano-deploy:docs/public)Verification
make lintgo test ./...--no-env-file, and the packager leaving out the Volcano env files and the deployed env file.make localmode-e2eagainstkong/volcano:local-nightly(the smoke takes about 5.5 minutes, inside the 35-minute limit). It covers:NEXT_PUBLIC_*variable, and a manifest with an auth section. The test invokes the function, reaches the HTTP function through the frontend route, completes a durable execution, and reads the auth setting back withconfig pull.--no-frontendsdeploying no frontend,--no-waitreturning while the build runs, and a broken build exiting non-zero with the frontend's name and its logs command--no-env-filedeploying the manifest's variablesinit nextjs --example notesfollowed bydeploy --with-migrations, which serves the app with the anon key compiled in and the service key absentTestAPIE2ECloudDeploy(new) passed against staging through the hosting repo'scloud-e2e-local, run in a Linux container as in CI. It runs the notes starter's cloud steps and checks that the anon key is compiled into the page and the service key is not a project variable. As a signed-up user it inserts and reads back a note, which works only if the migrations ran. It then re-runs with a durable function, a routed HTTP function, and an auth setting, and checks the route, a durable execution, and the setting throughconfig pull. The test's new first check, that a barevolcano cloud deployrefuses the starter'svolcano/volcano.env, was added after that run. It fails before any request, and the hosting CLI E2E lane runs the same refusal.