From 32f61ddced82ba555fac6091ff13cb7cd2b58456 Mon Sep 17 00:00:00 2001 From: Samuel K Date: Thu, 15 Oct 2026 14:57:51 -0600 Subject: [PATCH] fix(provider): install latest MicroSandbox release by default --- cmd/provider/add.go | 2 +- cmd/provider/add_test.go | 22 ++++++++++-- .../main/__tests__/ipc-provider-jobs.test.ts | 35 +++++++++++-------- .../components/provider/ProviderWizard.svelte | 2 +- .../provider/ProviderWizard.test.ts | 5 ++- e2e/tests/up/MICROSANDBOX.md | 8 +++-- e2e/tests/up/provider_microsandbox.go | 2 +- .../external-runtime-rollout.mdx | 6 ++-- .../managing-providers/manage-providers.mdx | 7 ++-- 9 files changed, 56 insertions(+), 33 deletions(-) diff --git a/cmd/provider/add.go b/cmd/provider/add.go index 5b41bff40d..a868a03b37 100644 --- a/cmd/provider/add.go +++ b/cmd/provider/add.go @@ -20,7 +20,7 @@ import ( "github.com/spf13/cobra" ) -const currentMicrosandboxSource = "github.com/devsy-org/devsy-provider-microsandbox@v0.1.8" +const currentMicrosandboxSource = "github.com/devsy-org/devsy-provider-microsandbox" // AddCmd holds the cmd flags. type AddCmd struct { diff --git a/cmd/provider/add_test.go b/cmd/provider/add_test.go index d26671c659..9a0c9f0204 100644 --- a/cmd/provider/add_test.go +++ b/cmd/provider/add_test.go @@ -49,7 +49,7 @@ func (s *addDeprecationSuite) SetupTest() { previousTransport := client.Transport client.Transport = providerAddRoundTripper(func(req *http.Request) (*http.Response, error) { const manifestURL = "https://github.com/devsy-org/devsy-provider-microsandbox/" + - "releases/download/v0.1.8/provider.yaml" + "releases/latest/download/provider.yaml" if req.URL.String() != manifestURL { s.T().Fatalf("unexpected source request: %s", req.URL) } @@ -58,7 +58,7 @@ func (s *addDeprecationSuite) SetupTest() { s.T().Cleanup(func() { client.Transport = previousTransport }) } -func (s *addDeprecationSuite) TestMicrosandboxAliasUsesPinnedExternalProvider() { +func (s *addDeprecationSuite) TestMicrosandboxAliasUsesLatestExternalProvider() { cmd := &AddCmd{GlobalFlags: &flags.GlobalFlags{}} for _, tc := range []struct { name string @@ -74,7 +74,7 @@ func (s *addDeprecationSuite) TestMicrosandboxAliasUsesPinnedExternalProvider() ) s.Require().NoError(err) s.Require().Equal(tc.want, resolved.name) - s.Require().Equal(currentMicrosandboxSource, resolved.source.Raw) + s.Require().Equal("github.com/devsy-org/devsy-provider-microsandbox", resolved.source.Raw) s.Require().Equal("devsy-org/devsy-provider-microsandbox", resolved.source.Github) parsed, err := providerpkg.ParseProvider(bytes.NewReader(resolved.raw)) s.Require().NoError(err) @@ -82,6 +82,22 @@ func (s *addDeprecationSuite) TestMicrosandboxAliasUsesPinnedExternalProvider() } } +func (s *addDeprecationSuite) TestExplicitMicrosandboxPinIsPreserved() { + const pinnedSource = "github.com/devsy-org/devsy-provider-microsandbox@v0.1.8" + client := devsyhttp.GetHTTPClient() + client.Transport = providerAddRoundTripper(func(req *http.Request) (*http.Response, error) { + s.Require().Equal("https://github.com/devsy-org/devsy-provider-microsandbox/"+ + "releases/download/v0.1.8/provider.yaml", req.URL.String()) + return providerAddResponse(req, externalMicrosandboxManifest), nil + }) + cmd := &AddCmd{GlobalFlags: &flags.GlobalFlags{}} + resolved, err := cmd.resolveAddSource(context.Background(), []string{pinnedSource}, "") + s.Require().NoError(err) + s.Require().Equal(providerpkg.MicrosandboxDriver, resolved.name) + s.Require().Equal(pinnedSource, resolved.source.Raw) + s.Require().Equal("devsy-org/devsy-provider-microsandbox", resolved.source.Github) +} + func (s *addDeprecationSuite) TestCloneAndOtherSourcesRemainUnchanged() { cmd := &AddCmd{GlobalFlags: &flags.GlobalFlags{}, FromExisting: "docker"} resolved, err := cmd.resolveAddSource( diff --git a/desktop/src/main/__tests__/ipc-provider-jobs.test.ts b/desktop/src/main/__tests__/ipc-provider-jobs.test.ts index aee88e154d..eae98cf5cc 100644 --- a/desktop/src/main/__tests__/ipc-provider-jobs.test.ts +++ b/desktop/src/main/__tests__/ipc-provider-jobs.test.ts @@ -235,21 +235,26 @@ describe("provider job lifecycle over IPC", () => { expect(providerJobs.get("docker")?.activity).toBe("installing") }) - it("adds and initializes the external Microsandbox preset without selecting a default", async () => { - const { cli, providerJobs } = setup() - const source = "github.com/devsy-org/devsy-provider-microsandbox@v0.1.8" - - await invoke("provider_add", { name: "microsandbox", source }) - await invoke("provider_init", { name: "microsandbox" }) - - expect(cli.runStreaming.mock.calls.map(([args]) => args)).toEqual([ - ["provider", "add", source, "--use=false", "--name", "microsandbox"], - ["provider", "init", "microsandbox"], - ]) - expect(cli.run).not.toHaveBeenCalled() - expect(cli.runRaw).not.toHaveBeenCalled() - expect(providerJobs.get("microsandbox")).toBeUndefined() - }) + it.each([ + "github.com/devsy-org/devsy-provider-microsandbox", + "github.com/devsy-org/devsy-provider-microsandbox@v0.1.8", + ])( + "adds and initializes external source %s without selecting a default", + async (source) => { + const { cli, providerJobs } = setup() + + await invoke("provider_add", { name: "microsandbox", source }) + await invoke("provider_init", { name: "microsandbox" }) + + expect(cli.runStreaming.mock.calls.map(([args]) => args)).toEqual([ + ["provider", "add", source, "--use=false", "--name", "microsandbox"], + ["provider", "init", "microsandbox"], + ]) + expect(cli.run).not.toHaveBeenCalled() + expect(cli.runRaw).not.toHaveBeenCalled() + expect(providerJobs.get("microsandbox")).toBeUndefined() + }, + ) it("releases an abandoned job so the card stops spinning", async () => { const { providerJobs } = setup(() => ({ lines: [], code: 0 })) diff --git a/desktop/src/renderer/src/lib/components/provider/ProviderWizard.svelte b/desktop/src/renderer/src/lib/components/provider/ProviderWizard.svelte index 67d6ca9971..89a191c2a5 100644 --- a/desktop/src/renderer/src/lib/components/provider/ProviderWizard.svelte +++ b/desktop/src/renderer/src/lib/components/provider/ProviderWizard.svelte @@ -39,7 +39,7 @@ const PRESETS: ProviderPreset[] = [ { name: "apple", description: "Apple containers (macOS 26+, Apple silicon)" }, { name: "microsandbox", - source: "github.com/devsy-org/devsy-provider-microsandbox@v0.1.8", + source: "github.com/devsy-org/devsy-provider-microsandbox", description: "Hardware-isolated microVMs", }, { name: "lima", description: "Linux VMs via Lima (macOS)" }, diff --git a/desktop/src/renderer/src/lib/components/provider/ProviderWizard.test.ts b/desktop/src/renderer/src/lib/components/provider/ProviderWizard.test.ts index ddc3d91764..ae75b98cea 100644 --- a/desktop/src/renderer/src/lib/components/provider/ProviderWizard.test.ts +++ b/desktop/src/renderer/src/lib/components/provider/ProviderWizard.test.ts @@ -44,8 +44,7 @@ vi.mock("$lib/stores/toasts.js", () => ({ import ProviderWizard from "./ProviderWizard.svelte" -const microsandboxSource = - "github.com/devsy-org/devsy-provider-microsandbox@v0.1.8" +const microsandboxSource = "github.com/devsy-org/devsy-provider-microsandbox" function makeProvider(name: string): Provider { return { @@ -74,7 +73,7 @@ describe("ProviderWizard", () => { onCommandProgress.mockImplementation(async () => () => undefined) }) - it("adds a fresh Microsandbox preset with the pinned source and keeps it selected", async () => { + it("adds a fresh Microsandbox preset with the latest source and keeps it selected", async () => { const page = renderWizard() const preset = screen.getByRole("button", { name: /microsandbox Hardware-isolated microVMs/, diff --git a/e2e/tests/up/MICROSANDBOX.md b/e2e/tests/up/MICROSANDBOX.md index a15ad20059..9544febc8c 100644 --- a/e2e/tests/up/MICROSANDBOX.md +++ b/e2e/tests/up/MICROSANDBOX.md @@ -12,9 +12,11 @@ The shared provider selector supplies the pinned source, runtime identity and provider label while callers retain their descriptive provider names. Built-in cases explicitly select `builtin:microsandbox`, which persists the -original internal source identity. The fresh-install CLI alias `microsandbox` -selects the pinned external provider; it must not silently replace the built-in -half of these parity or existing-workspace migration tests. +original internal source identity. External cases use the explicit published +version in `microsandboxExternalProvider`, including the lifecycle and performance +case. The fresh-install CLI alias `microsandbox` selects the latest external +release; it must not introduce a moving version into these fixtures or silently +replace the built-in half of the parity and migration tests. Workspace cleanup registration is explicit. Ginkgo cleanup runs in reverse order; register volume cleanup before workspace cleanup so the VM is torn down diff --git a/e2e/tests/up/provider_microsandbox.go b/e2e/tests/up/provider_microsandbox.go index 8823963506..96566d223b 100644 --- a/e2e/tests/up/provider_microsandbox.go +++ b/e2e/tests/up/provider_microsandbox.go @@ -182,7 +182,7 @@ var _ = ginkgo.Describe( ginkgo.Label("microsandbox-builtin"), ginkgo.SpecTimeout(framework.TimeoutLong())), ginkgo.Entry( "external v0.1.8", - provider.MicrosandboxDriver, + microsandboxExternalProvider, "microsandbox-external-parity", provider.ExternalDriver, ginkgo.Label("microsandbox-external"), ginkgo.SpecTimeout(framework.TimeoutLong()), diff --git a/sites/docs-devsy-sh/content/docs/developing-providers/external-runtime-rollout.mdx b/sites/docs-devsy-sh/content/docs/developing-providers/external-runtime-rollout.mdx index 777ac9d063..559b4ca50e 100644 --- a/sites/docs-devsy-sh/content/docs/developing-providers/external-runtime-rollout.mdx +++ b/sites/docs-devsy-sh/content/docs/developing-providers/external-runtime-rollout.mdx @@ -4,7 +4,7 @@ sidebar_label: Runtime Rollout Decision description: Fresh Desktop provider selection, existing-provider migration, and external MicroSandbox runtime evidence. --- -**Status: fresh Desktop and CLI installs select the published provider; the built-in driver is deprecated.** The Microsandbox preset and `devsy provider add microsandbox` install the pinned external source for a new provider while retaining the name `microsandbox`. Existing internal providers continue to use the embedded MicroSandbox driver until an explicit source migration. The runtime evidence remains limited to the covered Linux/KVM scenarios. +**Status: fresh Desktop and CLI installs select the published provider; the built-in driver is deprecated.** The Microsandbox preset and `devsy provider add microsandbox` install the latest published external release for a new provider while retaining the name `microsandbox`. Existing internal providers continue to use the embedded MicroSandbox driver until an explicit source migration. The runtime evidence remains limited to the covered Linux/KVM scenarios. ## Current host and runtime contract @@ -24,7 +24,7 @@ The separate Windows provider-update job exercises Go archive and provider-updat ## Fresh Desktop installation -The Desktop Microsandbox preset and fresh CLI alias install the pinned source [`github.com/devsy-org/devsy-provider-microsandbox@v0.1.8`](https://github.com/devsy-org/devsy-provider-microsandbox/releases/tag/v0.1.8), while retaining the provider name `microsandbox`. Reloading this provider without a replacement source retains the pinned tag. For an already pinned GitHub provider, a Desktop update to a displayed version explicitly selects that version; refreshing without a known target retains the configured pin. The existing Desktop setup path uses `provider add ... --use=false`; this preserves its current default-provider behavior. CLI `--name` and `--use` retain their normal behavior. The explicit compatibility source `builtin:microsandbox` remains available, as does the embedded manifest for parity tests and compatibility with existing internal provider records. +The Desktop Microsandbox preset and fresh CLI alias select the latest published release from [`github.com/devsy-org/devsy-provider-microsandbox`](https://github.com/devsy-org/devsy-provider-microsandbox), while retaining the provider name `microsandbox`. Users can explicitly select a tag such as `@v0.1.8`; source-omitted reloads retain an explicit tag. Unpinned GitHub sources resolve the latest release on a later reload, while an existing installation is unchanged until an explicit reload or update. For an already pinned GitHub provider, a Desktop update to a displayed version explicitly selects that version; refreshing without a known target retains the configured pin. The existing Desktop setup path uses `provider add ... --use=false`; this preserves its current default-provider behavior. CLI `--name` and `--use` retain their normal behavior. The explicit compatibility source `builtin:microsandbox` remains available, as does the embedded manifest for parity tests and compatibility with existing internal provider records. This choice applies only to a new provider. The wizard refuses an existing provider name before installation; it does not replace or migrate that record. Other presets and custom names retain their behavior. Entering `builtin:microsandbox` as a custom source deliberately chooses the deprecated built-in provider. Source-omitted reloads of stored internal records retain their legacy meaning; the fresh-install alias does not reinterpret those records. Migrating a stored internal provider to the external runtime requires passing the full external source explicitly to `provider set-source`. Loading an internal provider refreshes its embedded Exec blocks, not its stored driver or binaries. If initialization fails after a source change is committed, the new source remains selected and the provider records `InitError`; the command does not promise rollback. The running and stopped migration cases provide evidence for the tested successful transition, not for rollback after arbitrary failures. @@ -38,7 +38,7 @@ announced transition and validation. ## Evidence and compatibility limits -The performance artifact from run 38628263920 records one Linux/amd64 hosted run with SDK v1.6.0 and provider v0.1.8. It observed fresh and reused `up` wall times of 13.504s and 6.335s. Four direct/supervised/supervised/direct probe runs collected one first sample and 100 warm `Info` and `Find` samples each; all 808 launches were reaped. The artifact marks `cold_cache_measured=false`. These are observations, not thresholds, cold-start results, or evidence that supervision improves performance. No process pool is proposed. +Integration and performance fixtures retain explicit release pins for reproducibility; their evidence applies to the tested version, not every future release. The performance artifact from run 38628263920 records one Linux/amd64 hosted run with SDK v1.6.0 and provider v0.1.8. It observed fresh and reused `up` wall times of 13.504s and 6.335s. Four direct/supervised/supervised/direct probe runs collected one first sample and 100 warm `Info` and `Find` samples each; all 808 launches were reaped. The artifact marks `cold_cache_measured=false`. These are observations, not thresholds, cold-start results, or evidence that supervision improves performance. No process pool is proposed. Other provider-supported host profiles remain untested here. Upstream requires Apple Silicon on macOS, KVM on Linux, and WHP on Windows; this campaign does not claim runtime parity on those other hosts. The registry tests do not cover every proxy, Docker daemon/context/socket, credential-store, or temp-directory configuration. Neither the built-in driver nor the external provider guarantees removal of every effect after a failed or interrupted create; use a fresh `Find` and explicit cleanup where recovery is needed. The exact native VM artifacts surviving a particular interruption remain unproven. diff --git a/sites/docs-devsy-sh/content/docs/managing-providers/manage-providers.mdx b/sites/docs-devsy-sh/content/docs/managing-providers/manage-providers.mdx index 130d332ea5..146a76c4aa 100644 --- a/sites/docs-devsy-sh/content/docs/managing-providers/manage-providers.mdx +++ b/sites/docs-devsy-sh/content/docs/managing-providers/manage-providers.mdx @@ -43,9 +43,10 @@ Click a provider in the list to edit its settings, switch version, update, re-in devsy provider add docker ``` -`devsy provider add microsandbox` installs the pinned external MicroSandbox -provider from `github.com/devsy-org/devsy-provider-microsandbox@v0.1.8`. The Desktop -MicroSandbox preset selects the same published source. +`devsy provider add microsandbox` installs the latest published external MicroSandbox +provider from `github.com/devsy-org/devsy-provider-microsandbox`. The Desktop +MicroSandbox preset selects the same source. To install a specific release, append +a tag, for example `github.com/devsy-org/devsy-provider-microsandbox@v0.1.8`. Existing built-in MicroSandbox installations are listed as **Deprecated built-in** in Desktop and marked deprecated by `devsy provider list`. Their names, defaults,