diff --git a/.claude/skills/release/SKILL.md b/.claude/skills/release/SKILL.md new file mode 100644 index 00000000..a2ba3898 --- /dev/null +++ b/.claude/skills/release/SKILL.md @@ -0,0 +1,208 @@ +--- +name: release +description: Guide releasing a new grafanactl version. Use when user wants to create a release, tag a version, or asks about the release process. +allowed-tools: [Bash, Read] +--- + +# Release Skill + +## Overview + +Automates the grafanactl release process using `scripts/release.sh` and `svu` for semantic versioning. + +## When to Use + +- User asks to "release a new version" or "create a release" +- User says "tag v0.x.y" or "bump version" +- User mentions "publish a release" +- Questions about the release process + +## Release Workflow + +### Step 1: Show Current State + +Check the current version and what versions are available: + +```bash +# Run in parallel +svu current +svu next +svu patch +svu minor +svu major +``` + +Show commits since the last tag: +```bash +git log $(svu current)..HEAD --oneline +``` + +### Step 2: Ask User for Bump Type + +Present the options to the user: +- **`next`** - Auto-detect based on conventional commits (recommended) +- **`patch`** - Bug fixes only (0.1.8 → 0.1.9) +- **`minor`** - New features (0.1.8 → 0.2.0) +- **`major`** - Breaking changes (0.1.8 → 1.0.0) + +### Step 3: Run Release Script + +The `scripts/release.sh` script handles everything: + +```bash +scripts/release.sh +``` + +The script will: +1. Calculate the next version using `svu` +2. Show commits since last tag +3. Run `make all` (lint, tests, build, docs) +4. Ask for confirmation +5. Create and push the git tag +6. Print GitHub Actions workflow URL + +**Note**: The script is interactive and requires user confirmation before pushing the tag. + +### Step 4: Monitor Release + +After the tag is pushed, monitor the GitHub Actions workflow: + +```bash +# Check latest release workflow run +gh run list --workflow=release.yaml --limit=1 + +# Watch the run in progress (optional) +gh run watch +``` + +The workflow performs: +- GoReleaser builds (linux/darwin/windows, multiple architectures) +- Documentation build +- GitHub Pages deployment +- Changelog generation (auto-excludes `docs:`, `test:`, `chore:` commits) + +### Step 5: Verify Release + +Once the workflow completes: + +```bash +# View the release +gh release view + +# Get release URL +echo "https://github.com/$(gh repo view --json nameWithOwner -q .nameWithOwner)/releases/tag/" +``` + +## Pre-Release Checklist + +Before running the release script, ensure: +- ✅ All changes committed and pushed to main +- ✅ CI passing on main branch +- ✅ No uncommitted changes: `git status` +- ✅ Up to date with remote: `git pull` +- ✅ All PRs for this release are merged + +The release script will also run `make all` which includes: +- Linting (`make lint`) +- Tests (`make tests`) +- Build (`make build`) +- Documentation generation (`make docs`) +- Documentation drift check (`make reference-drift`) + +## Examples + +### Example 1: Auto-Detect Version Bump + +```bash +# Show what version will be tagged +svu next + +# Run release with auto-detection +scripts/release.sh next +``` + +### Example 2: Force Patch Release + +```bash +# Force a patch bump +scripts/release.sh patch +``` + +### Example 3: Check Without Releasing + +```bash +# Show current and next versions +svu current +svu next + +# Review commits +git log $(svu current)..HEAD --oneline +``` + +## Version Calculation (svu) + +The `svu` tool uses conventional commits to determine version bumps: + +| Commit Prefix | Version Bump | Example | +|---------------|--------------|---------| +| `fix:` | Patch | 0.1.8 → 0.1.9 | +| `feat:` | Minor | 0.1.8 → 0.2.0 | +| `fix!:` or `feat!:` | Major | 0.1.8 → 1.0.0 | +| `BREAKING CHANGE:` footer | Major | 0.1.8 → 1.0.0 | +| `chore:` | None | No bump | + +## Troubleshooting + +### Issue: "svu: command not found" + +**Solution**: Install svu from https://github.com/caarlos0/svu or via: +```bash +go install github.com/caarlos0/svu@latest +``` + +### Issue: Release Script Fails on `make all` + +**Solution**: Fix the reported issues first: +- Linter errors: Run `make lint` and fix +- Test failures: Run `make tests` and fix +- Docs drift: Run `make docs` to regenerate + +### Issue: Tag Already Exists + +**Solution**: +1. Check existing tags: `git tag` +2. Delete local tag if needed: `git tag -d ` +3. Force-delete remote tag (CAUTION): `git push origin :refs/tags/` + +### Issue: GitHub Actions Workflow Fails + +**Solution**: +1. View workflow logs: `gh run view ` +2. Check for common issues: + - GoReleaser configuration errors + - Build failures + - Documentation build errors +3. Fix and re-run if possible, or create a patch release + +## Related Files + +- `scripts/release.sh` - Release automation script +- `.goreleaser.yaml` - GoReleaser configuration +- `.github/workflows/release.yaml` - Release workflow +- `AGENTS.md` - Release process documentation + +## Best Practices + +### Do +- ✅ Use `next` for automatic version detection +- ✅ Review commits before releasing +- ✅ Wait for CI to pass before releasing +- ✅ Monitor the release workflow after pushing tag +- ✅ Verify the GitHub release page after completion + +### Don't +- ❌ Release with uncommitted changes +- ❌ Skip the pre-release checks (`make all`) +- ❌ Force-push release tags +- ❌ Delete released tags (breaks users) +- ❌ Release from non-main branches diff --git a/AGENTS.md b/AGENTS.md index dce3e6aa..abe0e3e2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -816,6 +816,148 @@ Based on TODO comments in code: - Grafana <12 (not supported) - Extremely large deployments (>10,000 resources without streaming) +## Release Process + +grafanactl uses a **tag-driven release process** powered by **GoReleaser** and **GitHub Actions**. + +### Quick Start + +**To release a new version**: + +```bash +# Option 1: Use the release script (recommended) +scripts/release.sh [patch|minor|major|next] + +# Option 2: Use the /release skill in Claude Code +/release +``` + +### How Releases Work + +Pushing a git tag matching `v*` to the repository triggers an automated pipeline: + +1. **GitHub Actions** (`.github/workflows/release.yaml`) detects the tag +2. **GoReleaser** (`.goreleaser.yaml`) builds cross-platform binaries: + - Linux (amd64, arm64) + - macOS/Darwin (amd64, arm64) + - Windows (amd64, arm64) +3. **Artifacts** are uploaded to GitHub Releases: + - Pre-built binaries as tar.gz (zip for Windows) + - Checksum file (`grafanactl_checksums.txt`) +4. **Changelog** is auto-generated from commit history: + - Excludes commits prefixed with `docs:`, `test:`, `chore:`, and merge commits +5. **Documentation** is built and published to GitHub Pages + +### Release Script (`scripts/release.sh`) + +The release script automates the entire process: + +```bash +#!/usr/bin/env bash +# Usage: scripts/release.sh [patch|minor|major|next] + +# Features: +# - Uses svu for semantic version calculation +# - Runs `make all` for pre-release validation +# - Shows commits since last tag for review +# - Confirms before tagging and pushing +# - Provides GitHub Actions workflow URL +``` + +**Version Bump Types**: +- `next` - Auto-detect from conventional commits (recommended) +- `patch` - Bug fixes only (0.1.8 → 0.1.9) +- `minor` - New features (0.1.8 → 0.2.0) +- `major` - Breaking changes (0.1.8 → 1.0.0) + +**Conventional Commits** (used by `svu` for auto-detection): +| Prefix | Bump | Example | +|--------|------|---------| +| `fix:` | patch | 0.1.8 → 0.1.9 | +| `feat:` | minor | 0.1.8 → 0.2.0 | +| `feat!:` or `BREAKING CHANGE:` | major | 0.1.8 → 1.0.0 | +| `chore:` | none | No version change | + +### Pre-Release Checklist + +Before releasing: +- ✅ All changes committed and pushed to main +- ✅ CI passing on main branch (`make all`) +- ✅ No uncommitted changes (`git status`) +- ✅ Up to date with remote (`git pull`) +- ✅ All PRs merged + +The release script runs `make all` which includes: +- Linting (`make lint`) +- Tests (`make tests`) +- Build (`make build`) +- Documentation generation (`make docs`) +- Documentation drift check (`make reference-drift`) + +### Monitoring Releases + +After pushing the tag: + +```bash +# Check workflow status +gh run list --workflow=release.yaml --limit=1 + +# View workflow logs +gh run watch + +# View the release when complete +gh release view +``` + +### Manual Release (if needed) + +If the script cannot be used: + +```bash +# 1. Calculate next version +NEXT=$(svu next) # or: svu patch / svu minor / svu major + +# 2. Validate +make all + +# 3. Tag and push +git tag "$NEXT" +git push origin "$NEXT" + +# 4. Monitor +gh run list --workflow=release.yaml --limit=1 +``` + +### Key Files + +| File | Purpose | +|------|---------| +| `scripts/release.sh` | Release automation script | +| `.goreleaser.yaml` | GoReleaser build configuration | +| `.github/workflows/release.yaml` | Release workflow definition | +| `cmd/grafanactl/main.go` | Version variables (`main.version`, `main.commit`, `main.date`) | + +### Version Information + +Version details are injected at build time via ldflags: + +```go +// cmd/grafanactl/main.go +var ( + version string // Git tag (e.g., "0.1.8") + commit string // Git commit SHA + date string // Build timestamp +) +``` + +For local builds without a tag, version defaults to `"SNAPSHOT"`. + +### Project Skills + +grafanactl includes a project-specific skill for release automation: + +- **`/release`** - Guides through the release process using `scripts/release.sh` and `svu` + ## Go Code Organization Standards When writing Go code, always organize code symbols in a given file in this order: diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 00000000..31fde5c4 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# Release automation script using svu for semantic versioning +# Usage: scripts/release.sh [patch|minor|major|next] + +set -euo pipefail + +BUMP_TYPE="${1:-next}" + +# Calculate versions +CURRENT=$(svu current) +case "$BUMP_TYPE" in + patch) NEXT=$(svu patch) ;; + minor) NEXT=$(svu minor) ;; + major) NEXT=$(svu major) ;; + next) NEXT=$(svu next) ;; + *) echo "Usage: $0 [patch|minor|major|next]"; exit 1 ;; +esac + +echo "Current version: $CURRENT" +echo "Next version: $NEXT" +echo "" +echo "Commits since $CURRENT:" +git log "${CURRENT}..HEAD" --oneline +echo "" + +# Pre-release checks +echo "Running pre-release checks (make all)..." +make all + +# Confirm +read -p "Tag and push $NEXT? [y/N] " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "Aborted." + exit 1 +fi + +# Tag and push +git tag "$NEXT" +git push origin "$NEXT" + +# Get repo info for URL +REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner) +echo "" +echo "Release triggered! Monitor at:" +echo " https://github.com/$REPO/actions/workflows/release.yaml" +echo "" +echo "Release will be published at:" +echo " https://github.com/$REPO/releases/tag/$NEXT"