Skip to content

Commit 7734f56

Browse files
asimcodex
andauthored
Verify zero-to-hero deploy dry-run (#4330)
Co-authored-by: Codex <codex@openai.com>
1 parent affd61e commit 7734f56

3 files changed

Lines changed: 59 additions & 2 deletions

File tree

internal/harness/zero-to-hero-ci/docs_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,62 @@ func TestZeroToHeroReferenceDocs(t *testing.T) {
6262
}
6363
}
6464

65+
func TestZeroToHeroDeployDryRunCommandSmoke(t *testing.T) {
66+
root := filepath.Clean(filepath.Join("..", "..", ".."))
67+
absRoot, err := filepath.Abs(root)
68+
if err != nil {
69+
t.Fatalf("resolve repository root: %v", err)
70+
}
71+
72+
bin := filepath.Join(t.TempDir(), "micro")
73+
build := exec.Command("go", "build", "-o", bin, "./cmd/micro")
74+
build.Dir = absRoot
75+
if out, err := build.CombinedOutput(); err != nil {
76+
t.Fatalf("build micro CLI for deploy dry-run smoke: %v\n%s", err, out)
77+
}
78+
79+
workspace := t.TempDir()
80+
writeFile(t, filepath.Join(workspace, "micro.mu"), `service api
81+
path ./api
82+
83+
deploy prod
84+
ssh deploy@prod.example.com
85+
path /srv/micro
86+
`)
87+
if err := os.Mkdir(filepath.Join(workspace, "api"), 0o755); err != nil {
88+
t.Fatalf("create service dir: %v", err)
89+
}
90+
91+
cmd := exec.Command(bin, "deploy", "--dry-run", "prod")
92+
cmd.Dir = workspace
93+
cmd.Env = append(os.Environ(), "MICRO_CONFIG_FILE="+filepath.Join(workspace, "micro.mu"))
94+
out, err := cmd.CombinedOutput()
95+
if err != nil {
96+
t.Fatalf("documented deploy dry-run command failed: %v\n%s", err, out)
97+
}
98+
99+
got := string(out)
100+
for _, want := range []string{
101+
"micro deploy --dry-run",
102+
"Target",
103+
"deploy@prod.example.com",
104+
"Remote path",
105+
"/srv/micro",
106+
"Services",
107+
"api",
108+
"No SSH, rsync, systemd, or remote deployment was performed.",
109+
} {
110+
if !strings.Contains(got, want) {
111+
t.Fatalf("deploy dry-run output missing %q:\n%s", want, got)
112+
}
113+
}
114+
115+
guide := readFile(t, filepath.Join(absRoot, "internal", "website", "docs", "guides", "zero-to-hero.md"))
116+
if !strings.Contains(guide, "micro deploy --dry-run prod") {
117+
t.Fatal("0→hero guide must document the same deploy dry-run command covered by CI")
118+
}
119+
}
120+
65121
func TestGuidesNavigationLeadsWithDoing(t *testing.T) {
66122
root := filepath.Clean(filepath.Join("..", "..", ".."))
67123
nav := readFile(t, filepath.Join(root, "internal", "website", "_data", "navigation.yml"))

internal/harness/zero-to-hero-ci/run.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ cd "$ROOT"
99
go test ./cmd/micro/cli/new -run TestZeroToOne -count=1
1010
go test ./cmd/micro -run 'TestFirstAgentWalkthroughCLIBoundaries|TestZeroToHeroCLIBoundaries' -count=1
1111
go test ./cmd/micro/cli/deploy -run TestDeployDryRun -count=1
12-
go test ./internal/harness/zero-to-hero-ci -run 'TestNoSecretFirstAgentTranscript|TestNoSecretFirstAgentDebuggingSmoke|TestZeroToHeroReferenceDocs|TestYourFirstAgentTutorialSmoke' -count=1
12+
go test ./internal/harness/zero-to-hero-ci -run 'TestNoSecretFirstAgentTranscript|TestNoSecretFirstAgentDebuggingSmoke|TestZeroToHeroReferenceDocs|TestZeroToHeroDeployDryRunCommandSmoke|TestYourFirstAgentTutorialSmoke' -count=1
1313

1414
# Deterministic no-secret reference scenarios. These use the real Go Micro
1515
# runtime and mock only the LLM provider. The support example is the maintained

internal/website/docs/guides/zero-to-hero.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ cloud credentials?"
2323
| Run | `micro run` remains the local development entry point. | `go test ./cmd/micro -run TestZeroToHeroCLIBoundaries -count=1` |
2424
| Chat | `micro chat` remains the interactive agent entry point. | `go test ./cmd/micro -run TestZeroToHeroCLIBoundaries -count=1` |
2525
| Inspect | `micro inspect agent <name>`, `micro agent history <name>`, `micro inspect flow <flow>`, and `micro flow runs <flow>` remain discoverable for run history; the no-secret debugging smoke seeds durable agent history and runs the documented inspect/history commands without provider keys. | `go test ./internal/harness/zero-to-hero-ci -run TestNoSecretFirstAgentDebuggingSmoke -count=1` |
26-
| Deploy | `micro deploy --dry-run` resolves deploy targets without touching remote infrastructure. | `go test ./cmd/micro/cli/deploy -run TestDeployDryRun -count=1` |
26+
| Deploy | `micro deploy --dry-run prod` resolves the documented deploy target without touching remote infrastructure. | `go test ./internal/harness/zero-to-hero-ci -run TestZeroToHeroDeployDryRunCommandSmoke -count=1` |
2727
| Smallest first agent | `examples/first-agent` runs one service-backed agent with a deterministic mock model and no provider key. | `go test ./examples/first-agent -run TestRunFirstAgent -count=1` |
2828
| Runtime reference app | `examples/support` runs typed services, an agent using those services as tools, an event-driven flow handoff, and an approval gate with only the model mocked. | `go test ./examples/support -run 'TestRunSupportMockSmoke|TestZeroToHeroReadmeDocumentsLifecycle' -count=1` |
2929
| Runtime harnesses | Real services, agents, durable flows, store-backed history, delegation, and A2A run with only the model mocked. | `./internal/harness/zero-to-hero-ci/run.sh` and `make provider-conformance-mock` |
@@ -84,6 +84,7 @@ go test ./cmd/micro -run TestFirstAgentWalkthroughCLIBoundaries -count=1
8484
# CLI inner-loop commands: run, chat, inspect, flow runs, deploy --dry-run.
8585
go test ./cmd/micro -run TestZeroToHeroCLIBoundaries -count=1
8686
go test ./cmd/micro/cli/deploy -run TestDeployDryRun -count=1
87+
go test ./internal/harness/zero-to-hero-ci -run TestZeroToHeroDeployDryRunCommandSmoke -count=1
8788

8889
# Smallest no-secret service-backed first agent.
8990
go test ./examples/first-agent -run TestRunFirstAgent -count=1

0 commit comments

Comments
 (0)