From 54d3f380491ceb4d0dcef241801c7bfb47813fa7 Mon Sep 17 00:00:00 2001 From: Codex Date: Fri, 24 Apr 2026 22:49:32 +0100 Subject: [PATCH] feat(go-devops): scaffold tests/cli/devops Taskfile + test driver per AX-10 tests/cli/devops/Taskfile.yaml + main.go. Verified: task -d + go test ./tests/cli/devops pass. Closes tasks.lthn.sh/view.php?id=756 Co-authored-by: Codex --- tests/cli/devops/Taskfile.yaml | 82 +++++++++++++++++++++++++++++++ tests/cli/devops/main.go | 89 ++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 tests/cli/devops/Taskfile.yaml create mode 100644 tests/cli/devops/main.go diff --git a/tests/cli/devops/Taskfile.yaml b/tests/cli/devops/Taskfile.yaml new file mode 100644 index 0000000..525eb40 --- /dev/null +++ b/tests/cli/devops/Taskfile.yaml @@ -0,0 +1,82 @@ +version: "3" + +tasks: + default: + cmds: + - task: test + + test: + cmds: + - task: test:deploy:plan + - task: test:deploy:ansible + - task: test:health + + test:deploy:plan: + desc: Validate the deploy command surface. + dir: ../../.. + cmds: + - | + export GOWORK=off + export GOCACHE="${GOCACHE:-/tmp/go-devops-gocache}" + export GOMODCACHE="${GOMODCACHE:-/tmp/go-devops-gomodcache}" + mkdir -p "$GOCACHE" "$GOMODCACHE" + + bin="$(mktemp -t go-devops-cli.XXXXXX)" + out="$(mktemp -t go-devops-deploy.XXXXXX)" + trap 'rm -f "$bin" "$out"' EXIT + + go build -o "$bin" ./tests/cli/devops + "$bin" deploy --help >"$out" + grep -Eq "servers|projects|apps|Coolify" "$out" + echo "deploy plan smoke passed: deploy command surface available" + + test:deploy:ansible: + desc: Validate bundled playbook YAML for the deploy smoke path. + dir: ../../.. + cmds: + - | + export GOWORK=off + export GOCACHE="${GOCACHE:-/tmp/go-devops-gocache}" + export GOMODCACHE="${GOMODCACHE:-/tmp/go-devops-gomodcache}" + mkdir -p "$GOCACHE" "$GOMODCACHE" + + bin="$(mktemp -t go-devops-cli.XXXXXX)" + out="$(mktemp -t go-devops-playbooks.XXXXXX)" + trap 'rm -f "$bin" "$out"' EXIT + + go build -o "$bin" ./tests/cli/devops + "$bin" playbook-smoke playbooks >"$out" + grep -q "playbook smoke passed" "$out" + echo "deploy ansible smoke passed: playbook YAML decoded" + + test:health: + desc: Validate core dev health output against a temporary registry. + dir: ../../.. + cmds: + - | + export GOWORK=off + export GOCACHE="${GOCACHE:-/tmp/go-devops-gocache}" + export GOMODCACHE="${GOMODCACHE:-/tmp/go-devops-gomodcache}" + mkdir -p "$GOCACHE" "$GOMODCACHE" + + bin="$(mktemp -t go-devops-cli.XXXXXX)" + tmp="$(mktemp -d)" + out="$(mktemp -t go-devops-health.XXXXXX)" + trap 'rm -f "$bin" "$out"; rm -rf "$tmp"' EXIT + + mkdir -p "$tmp/packages/alpha" + git -C "$tmp/packages/alpha" init -q + cat >"$tmp/repos.yaml" <"$out" + grep -q "1 repos" "$out" + grep -q "up to date" "$out" + echo "health smoke passed: dev health validated temporary registry" diff --git a/tests/cli/devops/main.go b/tests/cli/devops/main.go new file mode 100644 index 0000000..8b7ac8a --- /dev/null +++ b/tests/cli/devops/main.go @@ -0,0 +1,89 @@ +// AX-10 CLI driver for go-devops. +// +// task -d tests/cli/devops +// go run ./tests/cli/devops dev --help +package main + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "dappco.re/go/core/cli/pkg/cli" + deploycmd "dappco.re/go/devops/cmd/deploy" + devcmd "dappco.re/go/devops/cmd/dev" + docscmd "dappco.re/go/devops/cmd/docs" + gitcmd "dappco.re/go/devops/cmd/gitcmd" + setupcmd "dappco.re/go/devops/cmd/setup" + + "gopkg.in/yaml.v3" +) + +func main() { + root := cli.NewGroup("devops", "DevOps CLI artifact test driver", "") + devcmd.AddDevCommands(root) + deploycmd.AddDeployCommands(root) + docscmd.AddDocsCommands(root) + gitcmd.AddGitCommands(root) + setupcmd.AddSetupCommands(root) + root.AddCommand(playbookSmokeCommand()) + root.SetArgs(os.Args[1:]) + + if err := root.Execute(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func playbookSmokeCommand() *cli.Command { + return &cli.Command{ + Use: "playbook-smoke [dir]", + Short: "Validate bundled playbook YAML can be decoded", + Args: cli.RangeArgs(0, 1), + RunE: runPlaybookSmoke, + } +} + +func runPlaybookSmoke(cmd *cli.Command, args []string) error { + dir := "playbooks" + if len(args) > 0 { + dir = args[0] + } + + count := 0 + err := filepath.WalkDir(dir, func(path string, entry os.DirEntry, err error) error { + if err != nil { + return err + } + if entry.IsDir() || !isYAML(path) { + return nil + } + + raw, err := os.ReadFile(path) + if err != nil { + return err + } + + var document any + if err := yaml.Unmarshal(raw, &document); err != nil { + return fmt.Errorf("%s: %w", path, err) + } + count++ + return nil + }) + if err != nil { + return err + } + if count == 0 { + return fmt.Errorf("no playbook YAML files found in %s", dir) + } + + fmt.Fprintf(cmd.OutOrStdout(), "playbook smoke passed: %d YAML files decoded\n", count) + return nil +} + +func isYAML(path string) bool { + ext := strings.ToLower(filepath.Ext(path)) + return ext == ".yaml" || ext == ".yml" +}