Skip to content

Import SDK CI/CD tooling: labeling, CodeQL, surface checks, AI changelog#166

Merged
jeremy merged 9 commits intomainfrom
checks
Feb 28, 2026
Merged

Import SDK CI/CD tooling: labeling, CodeQL, surface checks, AI changelog#166
jeremy merged 9 commits intomainfrom
checks

Conversation

@jeremy
Copy link
Member

@jeremy jeremy commented Feb 28, 2026

Summary

  • Path-based auto-labeler with 9 labels (commands, tui, sdk, tests, ci, skills, plugin, auth, output) and labeler workflow using actions/labeler v5 with sync-labels
  • AI PR classifier for automatic bug/enhancement/documentation labeling and breaking change detection scoped to command surface files
  • Semver-aware dependabot auto-merge — patches auto-merge, minor github-actions only, Go module minors require review
  • CodeQL analysis added to security workflow (included in release gate via workflow_call)
  • Deterministic CLI surface check — snapshot script walks --help --agent recursively, diff script detects removals via comm -23. CI uses isolated git worktrees for baseline comparison
  • AI release changelog via actions/ai-inference with conditional goreleaser header (empty = no-op)
  • 6 new golangci-lint linters (contextcheck, durationcheck, errname, exhaustive, predeclared, revive) with all findings fixed
  • Pre-commit hooks for merge conflict markers, private key detection, case conflicts
  • Breaking changes category in GitHub release notes config

Design decisions

  • Path labels use bare names — no area/ prefix. docs and deps omitted to avoid near-synonym confusion with documentation (AI classifier) and dependencies (dependabot)
  • Surface check uses git worktree (not in-place checkout) to avoid corrupting workspace state during CI. PR's copy of the snapshot script runs against the baseline binary, so the introducing PR works even though main doesn't have the script yet
  • No pip install in workflows — prompt splicing is pure Python string ops, YAML validation is best-effort via try/except ImportError
  • Revive indent-error-flow findings handled with nolint directives where early return contradicts existing code style

Test plan

  • make check passes (fmt-check, vet, lint, test, test-e2e, check-naming, check-surface)
  • golangci-lint run ./... — 0 issues with all 6 new linters
  • goreleaser check — validates template with empty RELEASE_CHANGELOG
  • make check-surface — 1302 surface entries generated
  • go build ./... — clean compilation
  • Verify path labeler assigns labels on this PR
  • Verify AI classifier assigns type label on this PR
  • Verify cli-surface job passes in test workflow

Add [*.bats] section (2-space indent) to .editorconfig. Add
check-merge-conflict, detect-private-key, and check-case-conflict
to pre-commit-config.yaml.
Add .github/labeler.yml with area/* prefix labels (commands, tui,
sdk, tests, docs, deps, ci, skills, plugin, auth, output) and
labeler workflow using actions/labeler v5 with sync-labels.

Add breaking category and github-actions exclusion to release.yml
changelog configuration.
Two-job workflow: classify (bug/enhancement/documentation via
gpt-4o-mini) and breaking (CLI command surface analysis with
structured JSON response). Filters breaking detection to
internal/commands/*.go and internal/cli/root.go diffs only.

Prompt splicing uses pure Python string ops with optional PyYAML
validation (try/except ImportError, no pip install in privileged
pull_request_target context).
Replace blanket auto-merge with dependabot/fetch-metadata v2.
Patches auto-approve and auto-merge unconditionally. Minor bumps
auto-merge only for github-actions (Go module minors require
manual review).
New codeql job in security.yml using manual build mode with
private SDK access. Runs security-and-quality queries, uploads
SARIF with continue-on-error (requires GHAS). Automatically
included in release gate via workflow_call.
Surface snapshot script walks --help --agent recursively, emitting
fully-qualified CMD/FLAG/SUB lines rooted at "basecamp". Diff
script uses comm -23 to detect removals (breaking changes).

CI integration uses isolated git worktrees for baseline comparison
(no in-place checkout or stash fallbacks). PR's copy of the script
runs against the baseline binary, so the introducing PR works.

Add check-surface to make check. Add cli-surface job to test.yml.
Add surface compatibility check to release.yml test job.

Add AI changelog generation to release workflow using
actions/ai-inference v1 with summarize-changelog prompt.
RELEASE_CHANGELOG conditionally prepended to goreleaser release
header (empty = no-op).

Add jq to CONTRIBUTING.md prerequisites and make tools.
Enable contextcheck, durationcheck, errname, exhaustive,
predeclared, and revive. Add revive rules for common Go
conventions and exhaustive default-signifies-exhaustive setting.

Fixes: rename predeclared shadow (copy -> cfg in resilience),
add exhaustive default cases (appctx, metrics), add nolint
directives for intentional patterns (contextcheck on
context.Background in OAuth shutdown, exhaustive on partial
tea.KeyType switches, revive context-as-argument where name
is the primary differentiator).
Copilot AI review requested due to automatic review settings February 28, 2026 10:01
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Imports SDK-style CI/CD and repo hygiene tooling to improve automation (labeling, security scanning, release notes) and add a deterministic “CLI surface” compatibility gate based on --help --agent snapshots.

Changes:

  • Add deterministic CLI surface snapshot + diff scripts, wire them into make check and CI/release gates.
  • Expand CI automation: path-based area labels, AI PR classification + breaking-change detection, and semver-aware Dependabot auto-merge.
  • Add CodeQL to the security workflow and AI-generated release changelog injection into GoReleaser release headers.

Reviewed changes

Copilot reviewed 30 out of 30 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
scripts/check-cli-surface.sh New script to walk commands via --help --agent JSON and emit a sorted surface snapshot.
scripts/check-cli-surface-diff.sh New script to compare snapshots and fail on removals (breaking surface).
internal/tui/workspace/workspace.go Add //nolint:exhaustive to partial Bubble Tea key switch.
internal/tui/workspace/views/home.go Add //nolint:exhaustive to partial view-target switch.
internal/tui/workspace/data/realm.go Add revive suppression for context-as-argument rule.
internal/tui/workspace/data/metrics.go Add default case to event switch (clarify non-counted events).
internal/tui/workspace/boostpicker.go Add //nolint:exhaustive to partial Bubble Tea key switch.
internal/resilience/hooks.go Add contextcheck suppressions around context-independent lock/state operations.
internal/resilience/config.go Rename local variable from copy to cfg (avoid predeclared identifier shadowing).
internal/commands/doctor.go Document/suppress contextcheck for best-effort version fetch with its own timeout ctx.
internal/auth/auth.go Add contextcheck suppression for server.Shutdown(context.Background()) in callback server.
internal/appctx/context.go Make stats-in-error/stderr decisions explicit via default cases to satisfy exhaustiveness linting.
Makefile Add check-surface (and include it in check), plus helper targets and jq note.
CONTRIBUTING.md Document jq requirement for CLI surface checks.
.pre-commit-config.yaml Add additional pre-commit hooks (merge conflict markers, private key detection, case conflicts).
.goreleaser.yaml Allow optional AI changelog injection into the release header via RELEASE_CHANGELOG.
.golangci.yml Enable additional linters (contextcheck/durationcheck/errname/exhaustive/predeclared/revive) and configure revive/exhaustive settings + exclusions.
.github/workflows/test.yml Add CI job to snapshot PR vs baseline (origin/main) CLI surface using isolated worktrees.
.github/workflows/security.yml Add CodeQL analysis job and upload SARIF (best-effort).
.github/workflows/release.yml Add surface check to release gate; add AI changelog generation and export into RELEASE_CHANGELOG.
.github/workflows/labeler.yml New PR labeler workflow (pull_request_target) using actions/labeler.
.github/workflows/dependabot-auto-merge.yml Make Dependabot auto-merge semver-aware (patch always; minor only for GitHub Actions).
.github/workflows/ai-labeler.yml New AI PR classifier and breaking-change detector workflow (pull_request_target).
.github/release.yml Add “Breaking Changes” category and exclude github-actions labeled PRs from changelog.
.github/prompts/summarize-changelog.prompt.yml Prompt for generating a concise markdown release changelog.
.github/prompts/detect-breaking.prompt.yml JSON-schema prompt for detecting breaking CLI surface changes.
.github/prompts/classify-pr.prompt.yml Prompt for classifying PR type into bug/enhancement/documentation.
.github/labeler.yml Path-based area/* label definitions for the labeler workflow.
.github/codeql/codeql-config.yml CodeQL query configuration (security-and-quality; filter diagnostics/metrics).
.editorconfig Add indentation rules for *.bats files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Use bare label names (commands, tui, sdk, etc.) instead of
area/commands, area/tui, area/sdk. Simpler and sufficient —
no collision with AI classifier labels (bug, enhancement,
documentation).
Copilot AI review requested due to automatic review settings February 28, 2026 10:18
- Add jq preflight check to check-cli-surface.sh
- Force LC_ALL=C for sort and comm to ensure stable collation
- Guard empty/missing response-file in ai-labeler breaking step
  and release changelog step
- Use bounded 5s timeout context for OAuth callback server
  shutdown instead of context.Background()
@jeremy jeremy merged commit 25bfe75 into main Feb 28, 2026
20 checks passed
@jeremy jeremy deleted the checks branch February 28, 2026 10:23
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 30 out of 30 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

jeremy added a commit that referenced this pull request Mar 1, 2026
- Rename labeler keys to area/* namespace (area/commands, area/tui, etc.)
  and add area/docs, area/deps categories
- Capture stderr from --help --agent instead of suppressing with 2>/dev/null
- Write changelog diff to file instead of shell variable to avoid size limits
- Add worktree cleanup trap for baseline surface check on failure
- Add jq preflight check to make check-surface
@jeremy jeremy mentioned this pull request Mar 1, 2026
3 tasks
jeremy added a commit that referenced this pull request Mar 1, 2026
* Address PR #166 review feedback

- Rename labeler keys to area/* namespace (area/commands, area/tui, etc.)
  and add area/docs, area/deps categories
- Capture stderr from --help --agent instead of suppressing with 2>/dev/null
- Write changelog diff to file instead of shell variable to avoid size limits
- Add worktree cleanup trap for baseline surface check on failure
- Add jq preflight check to make check-surface

* Drop area/ prefix from labeler labels

Keep the plain names — no namespace needed for this repo.
jeremy added a commit that referenced this pull request Mar 1, 2026
* Address PR #166 review feedback

- Rename labeler keys to area/* namespace (area/commands, area/tui, etc.)
  and add area/docs, area/deps categories
- Capture stderr from --help --agent instead of suppressing with 2>/dev/null
- Write changelog diff to file instead of shell variable to avoid size limits
- Add worktree cleanup trap for baseline surface check on failure
- Add jq preflight check to make check-surface

* Drop area/ prefix from labeler labels

Keep the plain names — no namespace needed for this repo.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants