Thank you for your interest in contributing to the Thalassa Cloud CLI! This document provides guidelines and instructions for contributing to the project.
- Getting Started
- Development Setup
- Project Structure
- Development Workflow
- Code Style and Conventions
- Testing
- Commit Messages
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/cli.git cd cli - Add the upstream remote:
git remote add upstream https://github.com/thalassa-cloud/cli.git
- Go 1.24 or later - Install Go
- Make - Usually pre-installed on Unix systems
- Git - For version control
# Build the binary
make build
# The binary will be available at ./bin/tcloud
./bin/tcloud --help# Run unit tests
make test
# Run E2E tests (requires configuration)
# NOTE: Creates real resources, which may cost money
make test-e2eSee the Testing section for more details.
cli/
├── cmd/ # CLI commands organized by feature
│ ├── context/ # Context management commands
│ ├── iaas/ # IaaS-related commands
│ ├── kubernetes/ # Kubernetes commands
│ └── ...
├── internal/ # Internal packages (not exported)
│ ├── config/ # Configuration management
│ ├── table/ # Table formatting utilities
│ └── ...
├── e2e/ # End-to-end tests
├── docs/ # Documentation
└── main.go # Application entry point
Commands are organized in the cmd/ directory following this structure:
- Each top-level command has its own package (e.g.,
cmd/kubernetes/) - Subcommands are in the same package or subdirectories
- Command files follow naming conventions:
{command}.go- Main command definition{subcommand}.go- Subcommand implementation
-
Create a feature branch:
git checkout -b feature/your-feature-name
-
Make your changes following the code style guidelines
-
Write tests for your changes (see Testing)
-
Run tests to ensure everything passes:
make test -
Commit your changes using semantic commit messages (see Commit Messages)
-
Push to your fork:
git push origin feature/your-feature-name
-
Create a Pull Request on GitHub
- Follow standard Go formatting:
go fmt ./... - Follow Effective Go guidelines
- Use
golangci-lintor similar tools for linting (if configured)
Unit tests are located alongside the code they test (e.g., labels_test.go in the labels package).
- Use table-driven tests for multiple test cases
- Use the
testifypackage for assertions - Keep tests simple and focused on one behavior
Example:
func TestParseLabelSelector(t *testing.T) {
tests := []struct {
name string
selector string
expected map[string]string
}{
{
name: "single label",
selector: "key1=value1",
expected: map[string]string{"key1": "value1"},
},
// ... more test cases
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := ParseLabelSelector(tt.selector)
assert.Equal(t, tt.expected, result)
})
}
}Running Unit Tests:
# Run all unit tests
make test
# Run tests for a specific package
go test ./internal/labels/...
# Run tests with verbose output
go test -v ./internal/labels/...End-to-end tests are located in the e2e/ directory and test the actual CLI binary against a real API.
Setup:
- Build the binary:
make build - Configure environment variables (see
e2e/README.mdfor details):export TCLOUD_E2E_API_ENDPOINT="https://api.thalassa.cloud" export TCLOUD_E2E_PERSONAL_ACCESS_TOKEN="your-token"
Running E2E Tests:
# Run all E2E tests
make test-e2e
# Run specific E2E test
go test ./e2e/... -v -run TestVersion
# Run with custom binary path
TCLOUD_E2E_BINARY_PATH=/path/to/tcloud go test ./e2e/... -vFor more details, see e2e/README.md.
We follow semantic commit message conventions. Commit messages should be clear, descriptive, and follow this format:
<type>(<scope>): <subject>
<body>
<footer>
feat: New featurefix: Bug fixdocs: Documentation changestest: Adding or updating testsrefactor: Code refactoring (no behavior change)style: Code style changes (formatting, etc.)chore: Maintenance tasksperf: Performance improvements
feat(vpcs): add support for label selectors in list command
This allows users to filter VPCs by labels when listing them,
improving usability for managing large numbers of resources.
Closes #123
fix(auth): handle expired tokens gracefully
Previously, expired tokens would cause a panic. Now they are
handled with a clear error message prompting the user to re-authenticate.
test(e2e): add E2E tests for me organisations command
Adds comprehensive E2E tests covering all flags and output formats
for the me organisations command.
- Use imperative mood ("add" not "added" or "adds")
- Keep the subject line under 50 characters
- Capitalize the first letter of the subject
- Don't end the subject with a period
- Use the body to explain what and why (not how)
- Reference issues and PRs in the footer