A Go CLI tool for executing deployment scripts in a controlled, sequential manner. It's heavily inspired by Amazon's Internal Apollo Cmd tool.
DeployCtl executes scripts from ~/workbench/{env}/DeployCfg/cmd/{cmd}/ in sorted alphabetical order. Scripts are expected to have numeric prefixes (e.g., 100000-setup.sh, 200000-deploy.sh) for ordering.
workbench/
├── myproject # Entry point
│ ├── some_code.py # checkout out code
│ └── DeployCfg/
│ └── cmd/
│ └── Deploy/
│ │ ├── 100000-setup # a script that setups up initial environment
│ │ ├── 200000-deploy # a script that deploys the application
│ │ └── 300000-cleanup # a script that cleans up after deployment
│ └── Rollback/
│ ├── 100000-stop-curr-version # a script that stops the current version
│ ├── 200000-rollback # a script that rolls back the application
│ └── 300000-cleanup # a script that cleans up after deployment
In this scenario we would have 2 options:
- Deploy:
deployctl --env myproject --cmd Deploy - Rollback:
deployctl --env myproject --cmd Rollback
Right now we build from source by checking this repo and building the binary.
cd DeployCtl
go build -o deployctl ./cmd/deployctldeployctl --env <environment> --cmd <command>deployctl --env myproject --cmd DeployThis executes all scripts in ~/workbench/myproject/DeployCfg/cmd/Deploy/ in alphabetical order.
- Sequential Execution: Scripts run in alphabetical order (numeric prefixes ensure ordering)
- Fail-Fast: Execution stops immediately if any script exits with non-zero code
- Dual Logging: Output goes to both console (with colors) and log file
- Log Files: Saved to
~/.deployctl/logs/{env}-{cmd}-{timestamp}.log
DeployCtl/
├── cmd/deployctl/main.go # Entry point
├── internal/
│ ├── cli/root.go # Cobra command setup
│ ├── discovery/discovery.go # Script discovery & sorting
│ ├── executor/executor.go # Script execution
│ └── logger/
│ ├── logger.go # Logger interface
│ ├── file_logger.go # File logging implementation
│ ├── stdout_logger.go # Console output with colors
│ └── multi_logger.go # Composite logger
├── go.mod
└── README.md
Scripts must:
- Be executable (
chmod +x) - Have a proper shebang line (e.g.,
#!/bin/bash) - Return exit code 0 on success, non-zero on failure
The modular logger design allows adding remote logging without changing core code:
type Logger interface {
Log(entry LogEntry) error
StartRun(env, cmd string) error
EndRun(success bool) error
Writer() io.Writer
Close() error
}Implement this interface for remote logging (e.g., CloudWatch, Datadog) and add to the MultiLogger.