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.7 (managed by mise)
- golangci-lint 2.13.2 (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/Changing the shape or meaning of a
launcher.gokure.dev/v1alpha1document (app.yaml/kurel.yaml/cluster.yaml, or aCapabilityDefinition)? Use theformatcommit scope (feat(format):,fix(format):,docs(format):) — it groups under the changelog’s Document Format heading. Seedocs/oam/design-gvk.md§ Document-Format Lifecycle.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
Validating example manifests against flux-schema
This runs in CI as the non-required validate-manifests job (see
docs/github-workflows.md) — not yet in the required-checks list below while it
completes its first non-blocking cycle (go-kure/launcher#292).
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
- Check kure dependency sync
- Check tool-version pins (golangci-lint, govulncheck) stay consistent across Makefile, CI and docs
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.
Renovate Management
Dependency updates come from Renovate (renovate.json, extending the shared
go-kure/.github preset). The Dependency Dashboard issue is the control
surface:
- Gated updates (every major, all Go-toolchain updates) sit under Pending Approval — tick the checkbox to let Renovate open the PR. Nothing gated is ever proposed on its own.
- Deferring an update: leave its dashboard checkbox unticked; there is nothing to close. To reopen a closed/ignored update, tick its checkbox on the dashboard.
- Rebasing a PR: tick the “rebase/retry” checkbox in the PR body, or the per-PR entry on the dashboard. Renovate also rebases automatically when the PR falls behind the base branch.
- Closing a PR: closing it normally tells Renovate not to recreate that version; the dashboard lists it under Closed/Ignored.
Direct dependencies shared with the imported kure are never proposed here at
all — launcher must not lead the kure release it imports (see AGENTS.md
§ shared dependencies; CI enforces it via site/scripts/check-kure-dep-sync.sh).
The disable list lives in renovate.json and must be kept in step with that
guard’s shared-direct set.
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 executablevalidate-manifests- Build example manifests and validate against flux-schema
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 (the full go-kure linter set):
| 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).