feat(fly): add Fly.io cloud substrate (--on fly)#5
Merged
Conversation
The next hosting target in the substrate suite, after render and vercel.
v0 is image-only: a service declares a prebuilt `[services.X.fly].image`
and the substrate deploys it as a Fly machine.
- crates/stackless-fly impl Substrate: Stripe Projects provisions
`flyio/app` and returns a Stripe-managed, app-scoped DEPLOY_TOKEN (pinned
by `mise run discover flyio/app`); the Fly Machines REST API allocates the
app's public IPs, creates the machine, and polls it to `started`;
health-gates on `{app}.fly.dev`. observe/destroy key off the Stripe
resource registration (the token is ephemeral), so the Fly API is touched
only at deploy time. No managed datastore in v0.
- fly_api.rs is hand-written reqwest/serde, not progenitor: the served Fly
Machines spec is Swagger 2.0 and we use ~6 endpoints. Spec vendored under
specs/ for reference.
- Registered across the one-row seams: workspace member, binary dep,
substrates.rs (row + builder + global codes-uniqueness test), `--on` help,
SubstrateRequired remediation, integrations KNOWN.
- Tests: hermetic catalog-gap + config + Stripe-scripted observe/destroy +
mock-API machine deploy (19). Live-validated end-to-end via
`mise run smoke-fly` (provision -> deploy -> HTTPS health -> verified
teardown).
- Docs: README, ARCHITECTURE 4c, docs/SCHEMA.md, and a new "One-time setup:
initialize + link the provider" section in ADDING-A-PROVIDER.md covering
the `stripe projects init` + `link` ritual (run from the fixture dir).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A re-run after `create_machine` succeeded but `wait_for_started` failed would create a duplicate (billing) machine — `create_machine` is not idempotent. `start_service` now checks for an existing machine by name (`find_machine`) and reuses it before creating. Surfaced by an adversarial self-review of the resume path; re-validated by the live smoke. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The second hosting target in the suite, after Fly. v0 is static-upload: a service's source files (under [services.X.netlify].root or the repo root) are deployed via Netlify's file-digest API. - crates/stackless-netlify impl Substrate: Stripe Projects provisions `netlify/project` (free) and returns a Stripe-managed token + site id (pinned by `mise run discover netlify/project`; the token surfaces on a refreshed env read). The substrate clones the pinned ref and runs the file-digest deploy (SHA1 per file, PUT only the `required` files, poll to `ready`), health-gating on the deploy's ssl_url. observe/destroy key off the Stripe resource registration (the token is ephemeral). - netlify_api.rs is hand-written reqwest/serde (Swagger-2.0 source, ~5 endpoints). - Registered across the one-row seams: workspace member, binary dep, substrates.rs (row + builder + global codes-uniqueness test), --on help, SubstrateRequired remediation, integrations KNOWN. - Tests: hermetic catalog-gap + config + Stripe-scripted observe/destroy + mock-API file-digest deploy (15). Live-validated end-to-end via `mise run smoke-netlify` (provision -> upload deploy -> HTTPS health -> verified teardown). - Docs: README, ARCHITECTURE 4d, docs/SCHEMA.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(netlify): add Netlify cloud substrate (--on netlify)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds Fly.io as a
--on flycloud substrate — the next hosting target in the suite afterrenderandvercel. v0 is image-only: a service declares a prebuilt[services.X.fly].imageand the substrate deploys it as a Fly machine.How it works
flyio/appand returns a Stripe-managed, app-scopedDEPLOY_TOKEN(pinned viamise run discover flyio/app). The Fly Machines REST API (hand-writtenfly_api.rs— the served spec is Swagger 2.0 and we use ~6 endpoints, vendored underspecs/for reference) allocates the app's public IPs, creates the machine, and polls it tostarted; then a health gate onhttps://{app}.fly.dev.observe/destroykey off the Stripe resource registration (resource_registered/remove_resource) — the Fly API is touched only at deploy time.flyio/mpgis a separate catalog integration;[datastores.*]is rejected).substrates.rs(row + builder + global codes-uniqueness test),--onhelp,SubstrateRequiredremediation, integrationsKNOWN.Validation
mise run smoke-fly): provision → deploy-token → IPs → machinestarted→ HTTPS health at*.fly.dev→ verified teardownNotes / follow-ups
create_machine422s until a card is on the Stripe-managed Fly org (stripe projects open flyio→ Fly dashboard). No Stripe Projects CLI command propagates it today — a Stripe↔Fly integration gap worth reporting upstream.startfailure (Stripe add succeeds, deploy fails) leaves theflyio/appresource un-reaped until a later successful up→down (same shape as render). A Codex review of this exact case is in flight; any fix folds in here.docs/SCHEMA.md, and a new "One-time setup: initialize + link the provider" section inADDING-A-PROVIDER.md(thestripe projects init+linkritual, run from the fixture dir).🤖 Generated with Claude Code