Building from Source
Relevant source files
The following files were used as context for generating this wiki page:Building the tusk-drift-cli from source is the primary method for development, local testing, and contributing to the project. The process is managed through a combination of standard Go tooling and make targets for convenience. This allows developers to compile the binary for their local platform, run tests, and prepare for releases.
The project uses GoReleaser for its automated release process, which is triggered by pushing a new version tag. This process handles cross-compilation for various platforms, artifact creation, and publishing to GitHub Releases. For local development, specific go build commands with -ldflags are used to embed version information into the binary, mimicking the CI build environment.
Sources: CONTRIBUTING.md, README.md, scripts/release.sh
Prerequisites
To build the project from source, the following requirements must be met:
- Go: Version 1.25 or higher.
- (Optional) Nix: A
nix developcommand is available to enter a development shell with all dependencies pre-configured.
Sources: CONTRIBUTING.md:10-12
Development Workflow
The development workflow is streamlined using a Makefile that provides several common targets. These targets simplify building, testing, and formatting the code.
Sources: CONTRIBUTING.md:18-28
Common Make Targets
The following table summarizes the most frequently used make targets for development.
| Target | Description |
|---|---|
make build | Builds the binary for the current platform, outputting it as ./tusk. |
make run | Builds and runs the application. |
make test | Runs tests for the module root. |
make test-ci | Runs tests for all packages, as used in CI. This is a pre-flight check for releases. |
make deps | Downloads and tidies Go modules. |
make fmt | Formats the Go code using go fmt .. |
make lint | Runs the golangci-lint linter. This is a pre-flight check for releases. |
make build-ci | Builds the binary with embedded version information, mimicking the CI process. |
Sources: CONTRIBUTING.md:18-28, scripts/release.sh:65-68, scripts/release.sh:71-74
Standard Dev Cycle
The typical development cycle involves editing code, followed by formatting, linting, testing, and finally building the application.
The diagram below illustrates the standard development workflow using the provided make targets.
Sources: CONTRIBUTING.md:18-28
Building for Distribution
When building the CLI for distribution or testing release candidates, it's important to embed version information into the binary. This is handled automatically by the CI/CD pipeline but can be replicated locally.
Version Information
The following version details are embedded into the binary using Go's -ldflags:
| Variable | Path | Description |
|---|---|---|
Version | internal/version.Version | The Git tag of the release (e.g., v1.2.3). |
BuildTime | internal/version.BuildTime | The UTC timestamp of the build. |
GitCommit | internal/version.GitCommit | The full Git commit hash. |
Sources: CONTRIBUTING.md:103-105
Local Distribution Build
To build a binary with version information locally, you can use the following command structure. This mimics the process used in CI builds.
# With version info (mimics CI builds)
VERSION=v1.2.3
BUILD_TIME=$(date -u '+%Y-%m-%d %H:%M:%S UTC')
GIT_COMMIT=$(git rev-parse HEAD)
go build \
-ldflags "-X github.com/Use-Tusk/tusk-drift-cli/internal/version.Version=${VERSION} \
-X github.com/Use-Tusk/tusk-drift-cli/internal/version.BuildTime=${BUILD_TIME} \
-X github.com/Use-Tusk/tusk-drift-cli/internal/version.GitCommit=${GIT_COMMIT}" \
-o tusk
Sources: CONTRIBUTING.md:107-116
Cross-Compilation
To build for a different platform, set the GOOS and GOARCH environment variables.
# Example: Cross-compile for Linux AMD64
GOOS=linux GOARCH=amd64 go build -o tusk-linux
Sources: CONTRIBUTING.md:99-100
Release Process
Releases are automated using GoReleaser and triggered via a GitHub Actions workflow. The process of creating and pushing a new version tag is managed by the scripts/release.sh script.
Sources: CONTRIBUTING.md:83-84, scripts/release.sh
Creating a Release
The release.sh script automates version bumping and tagging. It accepts either patch or minor as an argument to determine the version increment.
Usage:
# Patch release (e.g., v1.0.0 → v1.0.1)
./scripts/release.sh patch
# Minor release (e.g., v1.0.0 → v1.1.0)
./scripts/release.sh minor
Sources: scripts/release.sh:4-5, scripts/release.sh:80-86
The script performs several pre-flight checks before proceeding:
- Ensures it's running on the
mainbranch. - Checks for uncommitted changes.
- Fetches the latest tags and commits from the remote.
- Verifies the local branch is up-to-date.
- Confirms there are new commits since the last tag.
- Runs
make test-ciandmake lintto ensure code quality.
After the checks pass, it calculates the new version, prompts for user confirmation, and then creates and pushes an annotated Git tag.
Sources: scripts/release.sh:22-75
The following diagram shows the flow of the release script.
Sources: scripts/release.sh
Automated Build and Publication
Once a new tag is pushed, a GitHub Actions workflow takes over to:
- Build binaries for all supported platforms.
- Create archives containing the
README.mdandLICENSEfiles. - Generate checksums for the artifacts.
- Create a GitHub release with a changelog.
- Upload all artifacts to the release.
- Update the latest version manifest on GitHub Pages.
Sources: CONTRIBUTING.md:88-95
Supported Platforms
The release workflow builds binaries for the following platforms and architectures:
| OS | Architectures |
|---|---|
| Linux | amd64, arm64 |
| macOS (darwin) | amd64, arm64 |
| Windows | amd64, arm64 |
Sources: CONTRIBUTING.md:99-102
Local GoReleaser Testing
To test the GoReleaser configuration locally without creating a full release, you can run it in snapshot mode.
goreleaser release --snapshot --clean
Sources: CONTRIBUTING.md:119-121