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 AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Fullsend is a platform for fully autonomous agentic development for Git-hosted o
- When invoking the fullsend CLI from this checkout, **prefer** `go run ./cmd/fullsend …` from the repo root. Do **not** use a `fullsend` binary from mise, `$PATH`, `go install`, or another checkout — those often lag this tree. A stale CLI once rewrote hosted-mint `ALLOWED_ROLES` during enrollment (dropping `e2e`/`fix`) and broke e2e. Details: [Go Code](docs/contributing/go-code.md#running-the-fullsend-cli).
- You **must** read and follow [COMMITS.md](COMMITS.md) when writing or reviewing commit messages and PR titles. Getting the prefix right is not optional — GoReleaser uses PR titles to build release notes. Breaking changes **must** carry the `!` suffix in both commit messages and PR titles; a missing `!` is an important-severity review finding.
- This repository requires a [Developer Certificate of Origin (DCO)](https://developercertificate.org/). Human-proposed commits **must** be signed off: use `git commit -s` (or add `Signed-off-by: Your Name <email>` as a trailer). Human-driven agent sessions (e.g., using Claude Code locally) should also sign off — the human directing the session is the one certifying the DCO. **Autonomous agent commits are exempt** and must never supply the DCO with `-s` or with `Signed-off-by`. These agents commit using the GitHub App's bot identity, which the [Probot DCO app](https://github.com/apps/dco) auto-skips.
- **Go coverage gate:** When changing Go production code (files under `cmd/` or `internal/` that are not `_test.go`), you **must** verify approximate patch coverage meets the 80% threshold from [`.codecov.yml`](.codecov.yml) before considering verification done. `make go-test` passing alone is not sufficient — it does not enforce Codecov thresholds. See [Verifying patch coverage locally](docs/contributing/go-code.md#verifying-patch-coverage-locally) for the exact commands. If coverage is below threshold, add tests for uncovered new/changed lines and re-check within the same run.
- Never commit secrets (tokens, API keys, PEM keys, gcloud credentials) or sensitive data (GCP project names, service account identifiers, Model Armor template names, internal hostnames). Use environment variables with no defaults for sensitive values.
- When adding a new doc under `docs/`, check `docs/.vitepress/config.ts` sidebar config. Sections using `getMarkdownFiles()` are auto-discovered. All other sections need a manual `{ text, link }` entry. Also add the new folder's prefix to `search.options.scopes` in the same file so the folder's pages are reachable when search scope pills are active.
- When removing or renaming a CLI command, public API, or user-facing feature, grep all documentation files under `docs/` for references to the old name and update or remove them. Pay special attention to `docs/cli/`, `docs/guides/`, and any getting-started or operations guides that walk through the removed workflow.
Expand Down
66 changes: 65 additions & 1 deletion docs/contributing/go-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,74 @@ The `internal/mintcore/` module is shared between the mint and devmint. Its file
When making changes to Go code under `cmd/` or `internal/`:

1. **Unit tests:** Run `make go-test` (or `go test ./...`) and fix any failures before committing.
2. **Coverage:** CI enforces thresholds via [Codecov](https://about.codecov.io/) (see [`.codecov.yml`](../../.codecov.yml)). **Patch coverage** on changed lines must meet **80%** (with a 5% tolerance). **Project coverage** must not drop more than **1%** below the base branch. `make go-test` runs tests with `-cover` locally but does not enforce these thresholds — a PR can still fail the Codecov status check if new or changed code lacks tests. Add or extend `_test.go` files for logic you introduce or modify.
2. **Coverage:** CI enforces thresholds via [Codecov](https://about.codecov.io/) (see [`.codecov.yml`](../../.codecov.yml)). **Patch coverage** on changed lines must meet **80%** (with a 5% tolerance). **Project coverage** must not drop more than **1%** below the base branch. `make go-test` alone does **not** enforce these thresholds — you must verify coverage locally before committing. See [Verifying patch coverage locally](#verifying-patch-coverage-locally) below for the exact commands.
3. **Vet:** Run `make go-vet` to catch common issues.
4. **E2E tests:** Run `make e2e-test` if your changes touch `internal/appsetup/`, `internal/forge/`, `internal/cli/`, or `internal/layers/`. These tests exercise the full admin install/uninstall flow against live GitHub pool orgs using mint/OIDC authentication.

## Verifying patch coverage locally

`make go-test` runs tests with `-cover` but does not check whether your
changed lines meet the **80% patch coverage** threshold from
[`.codecov.yml`](../../.codecov.yml). You must approximate this check
yourself before committing. Skipping this step is the most common cause
of `codecov/patch` failures on first push.

### Step-by-step

1. **Identify changed Go files** (excluding tests and generated code):

```bash
git diff --name-only main -- '*.go' | grep -v '_test.go'
```

2. **Determine affected packages** from those files:

```bash
git diff --name-only main -- '*.go' | grep -v '_test.go' \
| xargs -I{} dirname {} | sort -u \
| sed 's|^|./|'
```

3. **Run tests with a cover profile** for the affected packages:

```bash
go test -coverprofile=coverage.out ./path/to/changed/pkg/...
```

If changes span multiple packages, list them all or use `./...`
(slower but comprehensive).

4. **Inspect per-function coverage** for your changed files:

```bash
go tool cover -func=coverage.out | grep 'changed_file.go'
```

Each line shows `file:line: function coverage%`. Look at functions
you added or modified — these approximate Codecov's line-level patch
metric.

5. **Assess against the threshold.** If the functions you changed or
added show coverage well below 80%, add or extend `_test.go` files
to cover the missing lines. Then re-run from step 3.

### What counts as covered

Codecov measures line-level coverage on the diff. Locally, `go tool
cover -func` reports function-level coverage, which is a coarser
approximation. Target **≥ 80%** on the functions you touched. If a
function has complex branching, use `go tool cover -html=coverage.out`
to visually inspect which lines are covered.

### When to skip

- **Test-only changes** (no production `.go` files modified) — Codecov
patch coverage applies to production code, not test files.
- **Generated code, docs, or config-only changes** — no Go coverage
applies.
- **Files listed in `.codecov.yml` `ignore:`** — these are excluded from
coverage enforcement. Check the ignore list if your file is there.

## Concurrency testing (race detection)

`make go-test` runs all tests with `-race`. Every test must pass under the race detector.
Expand Down
115 changes: 115 additions & 0 deletions skills/check-patch-coverage/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
---
name: check-patch-coverage
description: >-
Verify approximate Go patch coverage meets the repo's 80% Codecov threshold.
Use after writing or updating Go production code — before committing — to
catch coverage gaps that would fail the codecov/patch status check.
---

# Check Patch Coverage

Verify that new or changed Go production code meets the **80% patch
coverage** threshold configured in [`.codecov.yml`](../../.codecov.yml)
before committing. This prevents `codecov/patch` failures on first push.

## When to use

- After implementing or modifying Go production code under `cmd/` or
`internal/` (files that are **not** `_test.go`).
- After adding tests for new code — to confirm coverage is sufficient.
- When the fix agent is addressing a coverage-related failure.

## When to skip

- Test-only changes (no production `.go` files modified).
- Documentation, config, or generated-code-only changes.
- Files listed in `.codecov.yml` `ignore:` — these are excluded from
coverage enforcement.

## Procedure

### 1. Identify changed production files

Determine which non-test Go files you changed relative to the target
branch. **Stage new files first** (`git add`) — `git diff --name-only`
only sees tracked or staged files, so an unstaged new file would be
invisible and the check would silently skip it.

```bash
CHANGED_GO=$(git diff --name-only main -- '*.go' | grep -v '_test.go')
Comment thread
ifireball marked this conversation as resolved.
echo "$CHANGED_GO"
```

If the list is empty, patch coverage does not apply — stop here.

### 2. Determine affected packages

```bash
PKGS=$(echo "$CHANGED_GO" | xargs -I{} dirname {} | sort -u | sed 's|^|./|')
echo "$PKGS"
```

### 3. Run tests with a cover profile

```bash
go test -coverprofile=coverage.out -count=1 $PKGS
```

If tests fail, fix them first — coverage is meaningless on broken code.

### 4. Check per-function coverage on changed files

For each changed file, inspect coverage:

```bash
for f in $CHANGED_GO; do
echo "=== $f ==="
go tool cover -func=coverage.out | grep "$f" || echo "(no coverage data)"
done
```

Each output line shows `file:line: function coverage%`.

### 5. Assess against the 80% threshold

Look at the functions you added or modified:

- **All functions ≥ 80%:** Coverage is sufficient. Proceed to commit.
- **Some functions below 80%:** Add or extend `_test.go` files to cover
the missing lines. Focus on:
- New functions you added (these must be tested)
- Modified functions where you added new branches or error paths
- Functions at 0% that contain logic (not just simple getters/setters)

After adding tests, re-run from step 3 and re-check.

### 6. Visual inspection (optional, for complex cases)

If function-level coverage is borderline or the function has complex
branching:

```bash
go tool cover -html=coverage.out
```

This opens an HTML view showing exactly which lines are covered (green)
and which are not (red). Use this to target your test additions.

## Understanding the approximation

This procedure approximates Codecov's **line-level patch coverage**
using Go's **function-level coverage** (`go tool cover -func`). The
local check is coarser — Codecov counts individual lines in the diff,
while `go tool cover -func` reports per-function percentages. Aim for
**≥ 80%** on touched functions to stay above the threshold with margin.

The configured tolerance is **5%** (from `.codecov.yml`), so Codecov
will pass at 75% in practice. But targeting 80% locally accounts for
the approximation gap between function-level and line-level metrics.

## Thresholds reference

From [`.codecov.yml`](../../.codecov.yml):

- **Patch coverage target:** 80% (5% tolerance)
- **Project coverage:** must not drop more than 1% below base branch
Loading