Skip to content

Latest commit

 

History

History
127 lines (98 loc) · 5.68 KB

development.md

File metadata and controls

127 lines (98 loc) · 5.68 KB

Developing Devctl

This guide is for contributors to the Devctl repository. Project authors using the CLI should start with the user guide.

Local checks

Install the repository-pinned tools once, or again after .mise.toml changes:

mise install

Run the complete local CI contract through Mise:

mise run check

check runs the core checks plus golangci-lint and e2e workflows. The check:core task contains formatting, dependency-graph hygiene, Go tests, build, generated documentation, and the Orders API example. The separate mise run test:race task runs the race-enabled suite; CI runs it on pushes to main and on the nightly schedule.

Pull request CI runs the core, lint, and e2e checks in separate Linux jobs. The separate Main CI workflow cross-builds the Devctl binary for macOS amd64 and arm64 with CGO disabled on pushes to main. The Docker image check runs in PR CI only when Dockerfile or .dockerignore changes. Race tests run separately on pushes to main and on the nightly schedule. Native macOS jobs are intentionally not part of regular CI because the repository has no platform-specific implementation. The release workflow still builds and publishes native macOS release archives for both architectures.

Regenerate the CLI reference after changing visible command metadata:

mise run docs:generate

The command reference is generated from CLI metadata. docs:check checks that reference; prose changes also need repository-local link and heading-anchor checks. Product rules and architecture are indexed in Documentation.

Release and image packaging

Artifact Platforms
CLI release archive Linux amd64, macOS amd64 and arm64
Devctl container image Linux amd64 and arm64

The release helper derives stable and RC versions through git-cliff and existing tags. Stable calculation ignores RC tags; RC versions carry a sequential -rc.N suffix. Release creation requires new commits and an unused remote tag, creates an annotated tag, and builds with GOWORK=off and CGO disabled. Archives include the binary, README, and license. The GitHub Release is created as a draft for manual publication.

The image workflow accepts a published SemVer or RC release tag and checks its commit/version metadata before building the image. Stable images receive both the version tag and latest; RC images receive only their version tag. The workflow publishes provenance attestations. The image packages Devctl, Go, Git, Node, and quicktype; it is tooling for mounted Projects, not an application deployment image generated by scaffold.

The source of these rules is the version helper, release workflow, and image workflow. Packaging the current checkout also requires resolving the local dependency constraint below.

Working with sibling modules

For local work across sibling devctl and go-libs checkouts, create a Go workspace outside either repository, for example in their parent directory:

go work init ./devctl ./go-libs/...

Use that workspace only for interactive development. Do not commit go.work. Before submitting, rerun the checks above with GOWORK=off so an external workspace does not hide dependency-graph problems.

The current migration implementation temporarily requires github.com/devctllabs/go-libs/dbmigrate v0.0.0 with a go.mod replacement to ../go-libs/dbmigrate. Keep that module in a sibling go-libs checkout; the replacement also applies with GOWORK=off. A standalone release, module installation, or Docker build needs a published dependency version in place of this local replacement.

Verifying migrations

Run the focused CLI, service, and repository tests during migration changes:

GOWORK=off go test ./cmd/devctl/internal/migrate ./internal/service/migration ./internal/repository/migration
GOWORK=off go test ./cmd/devctl -run 'TestMigrateCIWorkflow|TestInitScaffoldCreatesMigrationToolingWithoutOwningSQL'

Repository tests execute SQL against temporary SQLite databases, including no-change application, dirty state, partial rollback, file containment, and creation collisions. Environment tests cover URL precedence and safe failures. The main-package workflow runs the built CLI against a temporary SQLite Project; the scaffold test also exercises a generated Mise migration wrapper.

Live PostgreSQL and ClickHouse verification is separate from these automated tests. mise run example:orders:check runs the example's Go tests without a live database; it does not apply the PostgreSQL SQL in examples/orders-api.

To verify that example's actual migration, build the current Devctl binary and put it on PATH, provide ORDERS_API_DB_PRIMARY_POSTGRES_MIGRATIONS_URL for an isolated PostgreSQL database, and run mise run migrate:primary:postgres:up from examples/orders-api. Check the resulting orders columns and constraints, status, repeated up, down, and reapplication. The getting started guide describes an API round trip against the migrated schema. ClickHouse smoke verification likewise needs an isolated live server and the selected target's migration URL; include non-transactional failure and dirty-state behavior when changing its adapter.

Ownership boundaries

Devctl uses github.com/devctllabs/go-libs/filesystem for rooted file operations, go-libs/log for structured logging, and go-libs/di for command scenario graphs. Atomic file publication, Git, process execution, and external tool boundaries remain owned by Devctl. Completed Target or scaffold changes are not rolled back after a later failure.