Development Guide
Development Guide
This guide covers development workflows and tooling for the Launcher project.
Quick Start
Prerequisites
- mise — tool version manager
- Go 1.26.2 (managed by mise)
- golangci-lint 2.10.1 (managed by mise)
Contributing Workflow
The main branch is protected — all changes must go through pull requests.
Branch Workflow
Create a feature branch from
main:Use branch prefixes:
feat/,fix/,docs/,chore/Develop and test locally:
Push and create a pull request:
Pass required CI checks:
lint,test,buildMerge via the merge queue (linear history required — rebase, no merge commits)
Branch Protection Rules
Enforced via the main-protection repository ruleset:
- Required status checks:
lint,test,build - Merge queue: merging goes through a GitHub merge queue (rebase method) that rebases and tests the merged result before landing — no manual rebasing, no auto-rebase force-pushes
- Pull requests required: all changes must go through a PR
- Conversation resolution: all review threads must be resolved
- Linear history: enforced (rebase only, no merge commits)
- Force pushes: disabled
- Branch deletion: disabled
- Bypass actors:
kure-release-bot(GitHub App) — allowed to push release commits directly
Development Workflow
1. Initial Setup
2. Development Cycle
3. Building
4. Testing
5. Code Quality
Pre-commit Workflow
Before committing changes, run:
This will:
- Format code with
go fmtandgoimports - Tidy modules
- Run linters
- Run all tests
CI/CD Pipeline
The project uses GitHub Actions workflows:
Main CI Pipeline (.github/workflows/ci.yml)
- Triggers: Push to main/develop, PRs, merge_group (merge queue)
- Jobs: validate (lint), test, security, coverage-check, build, cross-platform, analyze-changes
- Runner:
autops-kube(self-hosted)
Release Pipeline (.github/workflows/release.yml)
- Triggers: Version tags (
v*.*.*) - Jobs: test, validate (tag + changelog), goreleaser, post-release (proxy refresh)
- Produces: kurel binaries for linux × amd64/arm64 + checksums + SBOM + cosign signature
Creating a Release
Releases are triggered by pushing a vX.Y.Z tag:
- Update
CHANGELOG.md:make changelog(orgit cliff -o CHANGELOG.md) - Commit the changelog:
git commit -m "chore: update CHANGELOG for vX.Y.Z" - Push to main and wait for CI to pass
- Tag:
git tag vX.Y.Z && git push origin vX.Y.Z
The pushed tag triggers the release pipeline which runs GoReleaser to produce binaries and publish a GitHub release.
Dependabot Management
Use @dependabot commands in PR comments:
| Command | Effect |
|---|---|
@dependabot close | Close PR, prevent recreation |
@dependabot ignore this dependency | Ignore dependency permanently |
@dependabot rebase | Rebase the PR |
Makefile Targets Reference
Development
help- Display help messageinfo- Display project informationclean- Clean build artifacts and caches
Dependencies
deps- Download and tidy Go modulesdeps-upgrade- Upgrade all dependenciestools- Install development toolsoutdated- Check for outdated dependencies
Building
build/build-kurel- Build kurel executable
Testing
test- Run all teststest-race- Run tests with race detectiontest-short- Run short tests onlytest-coverage- Run tests with coverage reporttest-benchmark- Run benchmark teststest-integration- Run integration tests
Code Quality
lint- Run all lintersfmt- Format Go codevet- Run go vettidy- Tidy modulesvuln- Run govulncheck
CI/CD
check- Quick code quality checkprecommit- Run all pre-commit checksci- Run full CI pipeline
Release
release TYPE=<type>- Preview release (dry-run); types: alpha, beta, rc, stablerelease-snapshot- Test GoReleaser locally (no tag, no publish)changelog- Generate CHANGELOG.md from git historychangelog-preview- Preview unreleased entries
Active Linters
The .golangci.yml enables these linters, aligned with the Wharf standard (meta/standards/golangci-lint.md):
| Linter | Category | Purpose |
|---|---|---|
errcheck | Default | Unchecked errors |
govet | Default | Suspicious constructs |
ineffassign | Default | Ineffectual assignments |
staticcheck | Default | Comprehensive static analysis |
unused | Default | Unused code |
bodyclose | Required | HTTP response body closed |
durationcheck | Required | time.Duration mistakes |
errorlint | Required | Error wrapping issues |
exhaustive | Required | Exhaustive enum switches |
misspell | Required | Common misspellings |
nilerr | Required | Nil error returns |
unconvert | Required | Unnecessary conversions |
whitespace | Required | Unnecessary whitespace |
gosec | Optional | Security checks |
Formatters: gofmt, goimports (with github.com/go-kure/launcher as local prefix).