Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake
12 changes: 3 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,8 @@ jobs:
go-version: '1.26'
check-latest: true

- name: Install Task
run: sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin

- name: Run tests
run: task ci:test
run: go test -race -count=1 ./... -tags=!examples

lint:
name: Lint
Expand All @@ -38,11 +35,8 @@ jobs:
go-version: '1.26'
check-latest: true

- name: Install Task
run: sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin

- name: Install golangci-lint
run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.11.3

- name: Run lint
run: task ci:lint
run: golangci-lint run ./...
16 changes: 7 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,8 @@ jobs:
go-version: '1.26'
check-latest: true

- name: Install Task
run: sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin

- name: Run tests
run: task ci:test
run: go test -race -count=1 ./... -tags=!examples

release:
name: Release
Expand All @@ -48,9 +45,6 @@ jobs:
go-version: '1.26'
check-latest: true

- name: Install Task
run: sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin

- name: Setup Node.js
uses: actions/setup-node@v6
with:
Expand All @@ -65,10 +59,14 @@ jobs:
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: task release
run: bunx semantic-release

- name: Warm Go module proxy
if: success()
run: |
sleep 5
task release:proxy-warmup
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -n "$LATEST_TAG" ]; then
echo "Warming Go proxy for github.com/jasoet/pkg/v2@${LATEST_TAG}"
GOPROXY=https://proxy.golang.org GO111MODULE=on go list -m "github.com/jasoet/pkg/v2@${LATEST_TAG}" || true
fi
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -220,4 +220,7 @@ temporal.db
.claude/*
!.claude/settings.json
!.claude/hooks/
.claude/settings.local.json
.claude/settings.local.json

# Nix / direnv
.direnv/
6 changes: 5 additions & 1 deletion INSTRUCTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ attribute commits to AI. This applies to ALL commits, including those made by to
- **Superpowers**: Ensure superpowers skills are installed. Use TDD for implementation, systematic-debugging for bugs.
- **Commits**: Use Conventional Commits. Format: `<type>(<scope>): <description>`. Types: `feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `perf`, `ci`.
- **Branching**: New branch for each feature/fix (`feat/...`, `fix/...`). PR with squash merge. Use `gh` for PR status and CI checks.
- **Nix**: All dev tools provided via `flake.nix`. Use `task <name>` which wraps commands with `nix develop -c`. Prerequisites: Nix (with flakes), go-task (global).
- **Containers**: Dual Docker/Podman support. This is a shared library — consumers use either runtime.
- **Patterns**: Functional options for configuration. OTelConfig always injected via `With*()` options, never serialized (`yaml:"-" mapstructure:"-"`). Use `otel.Layers.Start*()` for instrumentation.
- **Self-maintaining docs**: Update `INSTRUCTION.md`, `README.md`, and `AI_PATTERN.md` when making significant changes.
Expand All @@ -44,6 +45,8 @@ attribute commits to AI. This applies to ALL commits, including those made by to
| `<module>/*_integration_test.go` | Integration tests (`//go:build integration`) |
| `docs/plans/` | Design docs and implementation plans |
| `.claude/` | Claude Code hooks and settings |
| `flake.nix` | Nix flake — dev tool declarations |
| `.envrc` | direnv auto-activation (optional) |
| `Taskfile.yml` | All project commands |
| `INSTRUCTION.md` | AI dev context (this file) |
| `AI_PATTERN.md` | AI library consumer patterns index |
Expand All @@ -63,7 +66,8 @@ attribute commits to AI. This applies to ALL commits, including those made by to
| `task vendor` | go mod tidy + vendor |
| `task check` | test + lint |
| `task clean` | Remove build artifacts |
| `task tools` | Install dev tools |
| `task nix:check` | Verify Nix environment and tool availability |
| `task nix:update` | Update flake inputs (bump tool versions) |
| `task docker:check` | Verify Docker/Podman availability |
| `task k8s:check` | Verify kubectl and cluster |
| `task argo:check` | Verify Argo Workflows |
Expand Down
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,24 @@ open output/coverage-all.html

## Development

### Development Setup

**Prerequisites:**

- **Nix** (with flakes enabled): install via [Determinate Nix Installer](https://install.determinate.systems/nix)
- **go-task** (global): `nix profile install nixpkgs#go-task`
- **gh** (optional): for PR management

**Quick start:**

```bash
task nix:check # verify environment
task test # run tests
task lint # run linter
```

All `task` commands execute through `nix develop -c` automatically, so you do not need to manually enter a Nix shell.

### Development Commands

```bash
Expand Down Expand Up @@ -537,7 +555,8 @@ Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md)

2. **Setup Development Environment**
```bash
task docker:check
task nix:check # verify Nix tools
task docker:check # verify Docker/Podman
task test
```

Expand Down
69 changes: 45 additions & 24 deletions Taskfile.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
version: '3'

vars:
N: "nix develop -c"
PODMAN_SOCKET:
sh: |
if command -v podman &> /dev/null; then
Expand Down Expand Up @@ -39,16 +40,16 @@ tasks:
desc: Run go mod vendor
silent: true
cmds:
- go mod tidy
- go mod vendor
- '{{.N}} go mod tidy'
- '{{.N}} go mod vendor'

test:
desc: Run unit tests with coverage
silent: true
cmds:
- mkdir -p output
- go test -race -count=1 -coverprofile=output/coverage.out -covermode=atomic ./... -tags=!examples
- go tool cover -html=output/coverage.out -o output/coverage.html
- '{{.N}} go test -race -count=1 -coverprofile=output/coverage.out -covermode=atomic ./... -tags=!examples'
- '{{.N}} go tool cover -html=output/coverage.out -o output/coverage.html'
- 'echo "✓ Coverage: output/coverage.html"'

test:integration:
Expand All @@ -60,8 +61,8 @@ tasks:
TESTCONTAINERS_RYUK_DISABLED: '{{if .CONTAINER_HOST}}true{{end}}'
cmds:
- mkdir -p output
- go list ./... | grep -v examples | xargs go test -race -count=1 -coverprofile=output/coverage-integration.out -covermode=atomic -tags=integration -timeout=15m
- go tool cover -html=output/coverage-integration.out -o output/coverage-integration.html
- '{{.N}} bash -c "go list ./... | grep -v examples | xargs go test -race -count=1 -coverprofile=output/coverage-integration.out -covermode=atomic -tags=integration -timeout=15m"'
- '{{.N}} go tool cover -html=output/coverage-integration.out -o output/coverage-integration.html'
- 'echo "✓ Integration coverage: output/coverage-integration.html"'

test:argo:
Expand All @@ -70,10 +71,10 @@ tasks:
cmds:
- task: argo:check
- mkdir -p output
- go test -race -count=1 -coverprofile=output/coverage-argo.out -covermode=atomic -tags=argo -timeout=15m ./argo/...
- go tool cover -html=output/coverage-argo.out -o output/coverage-argo.html
- '{{.N}} go test -race -count=1 -coverprofile=output/coverage-argo.out -covermode=atomic -tags=argo -timeout=15m ./argo/...'
- '{{.N}} go tool cover -html=output/coverage-argo.out -o output/coverage-argo.html'
- 'echo "✓ Argo coverage: output/coverage-argo.html"'
- go tool cover -func=output/coverage-argo.out | grep total
- '{{.N}} bash -c "go tool cover -func=output/coverage-argo.out | grep total"'

test:complete:
desc: Run ALL tests (unit + integration + argo) with single comprehensive coverage report
Expand All @@ -86,11 +87,11 @@ tasks:
- task: argo:check
- mkdir -p output
- echo "🧪 Running all tests (unit + integration + argo)..."
- go list ./... | grep -v examples | xargs go test -race -count=1 -coverprofile=output/coverage-complete.out -covermode=atomic -tags=integration,argo -timeout=20m -v
- go tool cover -html=output/coverage-complete.out -o output/coverage-complete.html
- '{{.N}} bash -c "go list ./... | grep -v examples | xargs go test -race -count=1 -coverprofile=output/coverage-complete.out -covermode=atomic -tags=integration,argo -timeout=20m -v"'
- '{{.N}} go tool cover -html=output/coverage-complete.out -o output/coverage-complete.html'
- 'echo ""'
- 'echo "✅ Complete test coverage report:"'
- go tool cover -func=output/coverage-complete.out | grep total
- '{{.N}} bash -c "go tool cover -func=output/coverage-complete.out | grep total"'
- 'echo "📄 HTML Report: output/coverage-complete.html"'
- 'echo "📄 Coverage Data: output/coverage-complete.out"'

Expand Down Expand Up @@ -136,7 +137,7 @@ tasks:
desc: Run golangci-lint
silent: true
cmds:
- golangci-lint run ./...
- '{{.N}} golangci-lint run ./...'

check:
desc: Run all checks (test + lint)
Expand Down Expand Up @@ -194,31 +195,51 @@ tasks:
fi

# Utilities
tools:
desc: Install development tools
nix:check:
desc: Verify Nix environment and tool availability
silent: true
cmds:
- go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
- go install github.com/securego/gosec/v2/cmd/gosec@latest
- go install mvdan.cc/gofumpt@latest
- echo "✓ Tools installed"
- |
if ! command -v nix &> /dev/null; then
echo "❌ Nix not installed"
echo " Install: curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install"
exit 1
fi
echo "✅ Nix $(nix --version)"
echo "Checking devShell tools..."
{{.N}} go version
{{.N}} golangci-lint --version
{{.N}} gofumpt --version
{{.N}} gosec --version
{{.N}} podman --version
{{.N}} docker --version
{{.N}} bun --version
{{.N}} jq --version
echo "✅ All tools available"

nix:update:
desc: Update flake inputs (bump tool versions)
silent: true
cmds:
- nix flake update
- echo "✅ Flake inputs updated. Run 'task nix:check' to verify."

fmt:
desc: Format all Go files with gofumpt
cmds:
- gofumpt -l -w .
- '{{.N}} gofumpt -l -w .'

ci:test:
desc: Run unit tests for CI (no coverage HTML)
silent: true
cmds:
- go test -race -count=1 ./... -tags=!examples
- '{{.N}} go test -race -count=1 ./... -tags=!examples'

ci:lint:
desc: Run golangci-lint for CI
silent: true
cmds:
- golangci-lint run ./...
- '{{.N}} golangci-lint run ./...'

ci:check:
desc: Run all CI checks (test + lint)
Expand All @@ -231,7 +252,7 @@ tasks:
desc: Run semantic-release (CI only)
silent: true
cmds:
- bunx semantic-release
- '{{.N}} bunx semantic-release'

release:proxy-warmup:
desc: Warm Go module proxy with latest tag
Expand All @@ -241,7 +262,7 @@ tasks:
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -n "$LATEST_TAG" ]; then
echo "Warming Go proxy for github.com/jasoet/pkg/v2@${LATEST_TAG}"
GOPROXY=https://proxy.golang.org GO111MODULE=on go list -m "github.com/jasoet/pkg/v2@${LATEST_TAG}" || true
{{.N}} bash -c "GOPROXY=https://proxy.golang.org GO111MODULE=on go list -m \"github.com/jasoet/pkg/v2@${LATEST_TAG}\"" || true
fi

clean:
Expand Down
61 changes: 61 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
description = "Go pkg/v2 development environment";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};

outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in {
devShells.default = pkgs.mkShell {
packages = [
# Go toolchain
pkgs.go
pkgs.golangci-lint
pkgs.gofumpt
pkgs.gosec

# Container CLIs (daemon is system-level)
pkgs.podman
pkgs.docker-client
pkgs.podman-compose

# Other tools
pkgs.bun
pkgs.jq
];

shellHook = ''
echo "pkg/v2 dev environment ready — Go $(go version | awk '{print $3}')"
'';
};
});
}