Contributing
See CONTRIBUTING.md for the full contributing guide, and Architecture & Adding a Service for how the codebase is structured and how to add a new product CLI.
Quick start
git clone https://github.com/vngcloud/greennode-cli.git
cd greennode-cli/go
go build -o grn .
./grn --version
Adding a new command
- Create
cmd/<service>/<command_name>.go - Define a
cobra.CommandwithUse,Short,RunE - Register it on the service's parent command in
cmd/<service>/<service>.go - Build the client with
cli.NewClient(cmd, "<service>"); print withcli.Output(cmd, data) - Validate any ID used in a URL with
validator.ValidateID(...) - Add
--dry-runfor create/update/delete;--force+ confirmation for delete - (Optional) Register flag value completion — see Architecture
- Document it: create
docs/commands/<service>/<command-name>.md, add it to the command index table and to themkdocs.ymlnav - Add a changelog fragment:
./scripts/new-change -t feature -c <service> -d "..."
Adding a new service
A new product self-registers and is mounted without editing root.go. See
Architecture & Adding a Service for the
full steps (parent command + cli.RegisterService, blank-import in
cmd/register.go, endpoint in REGIONS, CODEOWNERS entry).
Running tests
On macOS 26 (Darwin 25) with Go 1.22,
go testmay abort withdyld: missing LC_UUID. Use the external linker:CGO_ENABLED=1 go test -ldflags='-linkmode=external' ./...