Consolidate documentation: move maintainer docs to docs/, remove redundant files
- Move RELEASING.md and LINTING.md to docs/ (maintainer-only content) - Delete WORKFLOW.md (agent workflow content belongs in AGENTS.md) - Delete TEXT_FORMATS.md (technical details belong in ADVANCED.md) - Update all cross-references to point to new locations - Keep CLAUDE.md (required by Claude Code) Reduces root-level docs from 20 to 16 files with clearer organization. Amp-Thread-ID: https://ampcode.com/threads/T-fe1db4f3-16c6-4a79-8887-c7f4c1f11c43 Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
# Linting Policy
|
||||
|
||||
This document explains our approach to `golangci-lint` warnings in this codebase.
|
||||
|
||||
## Current Status
|
||||
|
||||
Running `golangci-lint run ./...` currently reports **34 issues** as of Oct 27, 2025. These are not actual code quality problems - they are false positives or intentional patterns that reflect idiomatic Go practice.
|
||||
|
||||
**Historical note**: The count was ~200 before extensive cleanup in October 2025. The remaining issues represent the acceptable baseline that doesn't warrant fixing.
|
||||
|
||||
## Issue Breakdown
|
||||
|
||||
### errcheck (24 issues)
|
||||
|
||||
**Pattern**: Unchecked errors from `defer` cleanup operations
|
||||
**Status**: Intentional and idiomatic
|
||||
|
||||
Examples:
|
||||
```go
|
||||
defer rows.Close()
|
||||
defer tx.Rollback()
|
||||
defer os.RemoveAll(tmpDir) // in tests
|
||||
```
|
||||
|
||||
**Rationale**: In Go, it's standard practice to ignore errors from deferred cleanup operations:
|
||||
- `rows.Close()` - closing already-consumed result sets rarely errors
|
||||
- `tx.Rollback()` - rollback on defer is a safety net; if commit succeeded, rollback is a no-op
|
||||
- Test cleanup - errors during test cleanup don't affect test outcomes
|
||||
|
||||
Fixing these would add noise without improving code quality. The critical cleanup operations (where errors matter) are already checked explicitly.
|
||||
|
||||
### gosec (10 issues)
|
||||
|
||||
**Pattern 1**: G204 - Subprocess launched with variable (3 issues)
|
||||
**Status**: Intentional - launching editor and git commands with user-specified paths
|
||||
|
||||
Examples:
|
||||
- Launching `$EDITOR` for issue editing
|
||||
- Executing git commands
|
||||
- Running bd daemon binary
|
||||
|
||||
**Pattern 2**: G304 - File inclusion via variable (3 issues)
|
||||
**Status**: Intended feature - user-specified file paths for import/export
|
||||
|
||||
All file paths are either:
|
||||
- User-provided CLI arguments (expected for import/export commands)
|
||||
- Test fixtures in controlled test environments
|
||||
- Validated paths with security checks
|
||||
|
||||
**Pattern 3**: G301/G302/G306 - File permissions (3 issues)
|
||||
**Status**: Acceptable for user-facing database files
|
||||
|
||||
- G301: 0755 for database directories (allows other users to read)
|
||||
- G302: 0644 for JSONL files (version controlled, needs to be readable)
|
||||
- G306: 0644 for new JSONL files (consistency with existing files)
|
||||
|
||||
**Pattern 4**: G115 - Integer overflow conversion (1 issue)
|
||||
**Status**: False positive - bounded by max retry count
|
||||
|
||||
The exponential backoff calculation is bounded by a small retry counter, making overflow impossible in practice.
|
||||
|
||||
## golangci-lint Configuration Challenges
|
||||
|
||||
We've attempted to configure `.golangci.yml` to exclude these false positives, but golangci-lint's exclusion mechanisms have proven challenging:
|
||||
- `exclude-functions` works for some errcheck patterns
|
||||
- `exclude` patterns with regex don't match as expected
|
||||
- `exclude-rules` with text matching doesn't work reliably
|
||||
|
||||
This appears to be a known limitation of golangci-lint's configuration system.
|
||||
|
||||
## Recommendation
|
||||
|
||||
**For contributors**: Don't be alarmed by the 34 lint warnings. The code quality is high.
|
||||
|
||||
**For code review**: Focus on:
|
||||
- New issues introduced by changes (not the baseline 34)
|
||||
- Actual logic errors
|
||||
- Missing error checks on critical operations (file writes, database commits)
|
||||
- Security concerns beyond gosec's false positives
|
||||
|
||||
**For CI/CD**: The current GitHub Actions workflow runs linting but doesn't fail on these known issues. We may add `--issues-exit-code=0` or configure the workflow to check for regressions only.
|
||||
|
||||
## Future Work
|
||||
|
||||
Potential approaches to reduce noise:
|
||||
1. Disable specific linters (errcheck, revive) if the signal-to-noise ratio doesn't improve
|
||||
2. Use `//nolint` directives sparingly for clear false positives
|
||||
3. Investigate alternative linters with better exclusion support
|
||||
4. Contribute to golangci-lint to improve exclusion mechanisms
|
||||
|
||||
## Summary
|
||||
|
||||
These "issues" are not technical debt - they represent intentional, idiomatic Go code. The codebase maintains high quality through:
|
||||
- Comprehensive test coverage (>80%)
|
||||
- Careful error handling where it matters
|
||||
- Security validation of user input
|
||||
- Clear documentation
|
||||
|
||||
Don't let the linter count distract from the actual code quality.
|
||||
@@ -0,0 +1,261 @@
|
||||
# Release Process
|
||||
|
||||
Quick guide for releasing a new version of beads.
|
||||
|
||||
## 🚀 The Easy Way (Recommended)
|
||||
|
||||
Use the fully automated release script:
|
||||
|
||||
```bash
|
||||
./scripts/release.sh 0.9.3
|
||||
```
|
||||
|
||||
This does **everything**: version bump, tests, git tag, Homebrew update, and local installation.
|
||||
|
||||
See [scripts/README.md](scripts/README.md#releasesh--the-easy-button) for details.
|
||||
|
||||
---
|
||||
|
||||
## 📋 The Manual Way
|
||||
|
||||
If you prefer step-by-step control:
|
||||
|
||||
### Pre-Release Checklist
|
||||
|
||||
1. **Kill all running daemons (CRITICAL)**:
|
||||
```bash
|
||||
# Kill by process name
|
||||
pkill -f "bd.*daemon"
|
||||
|
||||
# Verify no daemons are running
|
||||
pgrep -lf "bd.*daemon" || echo "No daemons running ✓"
|
||||
|
||||
# Alternative: find and kill by socket
|
||||
find ~/.config -name "bd.sock" -type f 2>/dev/null | while read sock; do
|
||||
echo "Found daemon socket: $sock"
|
||||
done
|
||||
```
|
||||
|
||||
**Why this matters**: Old daemon versions can cause:
|
||||
- Auto-flush race conditions leaving working tree dirty after commits
|
||||
- Version mismatches between client (new) and daemon (old)
|
||||
- Confusing behavior where changes appear to sync incorrectly
|
||||
|
||||
2. **Run tests and build**:
|
||||
```bash
|
||||
TMPDIR=/tmp go test ./...
|
||||
golangci-lint run ./...
|
||||
TMPDIR=/tmp go build -o bd ./cmd/bd
|
||||
./bd version # Verify it shows new version
|
||||
```
|
||||
|
||||
3. **Skip local install** (avoid go install vs brew conflicts):
|
||||
- Use `./bd` directly from the repo for testing
|
||||
- Your system bd will be updated via brew after Homebrew formula update
|
||||
- Or temporarily: `alias bd="$PWD/bd"` if needed
|
||||
|
||||
4. **Update CHANGELOG.md**:
|
||||
- Add version heading: `## [0.9.X] - YYYY-MM-DD`
|
||||
- Summarize changes under: Added, Fixed, Changed, Performance, Community
|
||||
- Update Version History section
|
||||
- Add Upgrade Guide section if needed
|
||||
|
||||
5. **Commit changelog**:
|
||||
```bash
|
||||
git add CHANGELOG.md
|
||||
git commit -m "Add 0.9.X release notes"
|
||||
```
|
||||
|
||||
## Version Bump
|
||||
|
||||
Use the automated script to update all version files:
|
||||
|
||||
```bash
|
||||
./scripts/bump-version.sh 0.9.X --commit
|
||||
git push origin main
|
||||
```
|
||||
|
||||
This updates:
|
||||
- `cmd/bd/version.go`
|
||||
- `.claude-plugin/plugin.json`
|
||||
- `.claude-plugin/marketplace.json`
|
||||
- `integrations/beads-mcp/pyproject.toml`
|
||||
- `integrations/beads-mcp/src/beads_mcp/__init__.py`
|
||||
- `README.md`
|
||||
- `PLUGIN.md`
|
||||
|
||||
**IMPORTANT**: After version bump, rebuild the local binary:
|
||||
```bash
|
||||
go build -o bd ./cmd/bd
|
||||
./bd version # Should show new version
|
||||
```
|
||||
|
||||
## Publish to All Channels
|
||||
|
||||
### 1. Create Git Tag
|
||||
|
||||
```bash
|
||||
git tag v0.9.X
|
||||
git push origin main
|
||||
git push origin v0.9.X
|
||||
```
|
||||
|
||||
**That's it!** GitHub Actions automatically handles the rest:
|
||||
- GoReleaser builds and publishes binaries to GitHub Releases
|
||||
- PyPI publish job uploads the MCP server package to PyPI
|
||||
|
||||
### 2. GitHub Secrets Setup (One-Time)
|
||||
|
||||
The automation requires this secret to be configured:
|
||||
|
||||
**PYPI_API_TOKEN**: Your PyPI API token
|
||||
1. Generate token at https://pypi.org/manage/account/token/
|
||||
2. Add to GitHub at https://github.com/steveyegge/beads/settings/secrets/actions
|
||||
3. Name: `PYPI_API_TOKEN`
|
||||
4. Value: `pypi-...` (your full token)
|
||||
|
||||
### 3. Manual PyPI Publish (If Needed)
|
||||
|
||||
If the automated publish fails, you can manually upload:
|
||||
|
||||
```bash
|
||||
cd integrations/beads-mcp
|
||||
|
||||
# Clean and rebuild
|
||||
rm -rf dist/ build/ src/*.egg-info
|
||||
uv build
|
||||
|
||||
# Upload to PyPI
|
||||
TWINE_USERNAME=__token__ TWINE_PASSWORD=pypi-... uv tool run twine upload dist/*
|
||||
```
|
||||
|
||||
See [integrations/beads-mcp/PYPI.md](integrations/beads-mcp/PYPI.md) for detailed PyPI instructions.
|
||||
|
||||
### 3. Update Homebrew Formula
|
||||
|
||||
**CRITICAL**: This step must be done AFTER pushing the git tag in step 1, otherwise the tarball won't exist yet.
|
||||
|
||||
The formula needs the SHA256 of the tag tarball:
|
||||
|
||||
```bash
|
||||
# Compute SHA256 from tag (wait a few seconds after pushing tag if you get 404)
|
||||
curl -sL https://github.com/steveyegge/beads/archive/refs/tags/v0.9.X.tar.gz | shasum -a 256
|
||||
|
||||
# Navigate to tap repo (if already cloned) or clone it
|
||||
cd /tmp/homebrew-beads || git clone https://github.com/steveyegge/homebrew-beads /tmp/homebrew-beads
|
||||
|
||||
# Pull latest changes
|
||||
cd /tmp/homebrew-beads
|
||||
git pull
|
||||
|
||||
# Update Formula/bd.rb (replace version and SHA256):
|
||||
# - url: https://github.com/steveyegge/beads/archive/refs/tags/v0.9.X.tar.gz
|
||||
# - sha256: <computed SHA256>
|
||||
|
||||
# Commit and push
|
||||
git add Formula/bd.rb
|
||||
git commit -m "Update bd formula to v0.9.X"
|
||||
git push origin main
|
||||
|
||||
# CRITICAL: Verify the installation works
|
||||
brew update
|
||||
brew upgrade bd # Or: brew reinstall bd
|
||||
bd version # MUST show v0.9.X - if not, the release is incomplete!
|
||||
```
|
||||
|
||||
**⚠️ DO NOT SKIP THE VERIFICATION STEP ABOVE** - This ensures users can actually install the new version.
|
||||
|
||||
**Note**: Until this step is complete, users with Homebrew-installed bd will still have the old version.
|
||||
|
||||
**Note:** If you have an old bd binary from `go install` in your PATH, remove it to avoid conflicts:
|
||||
```bash
|
||||
# Find where bd is installed
|
||||
which bd
|
||||
|
||||
# If it's in a Go toolchain path (e.g., ~/go/bin/bd or mise-managed Go), remove it
|
||||
# Common locations:
|
||||
rm ~/go/bin/bd # Standard go install location
|
||||
rm ~/.local/share/mise/installs/go/*/bin/bd # mise-managed Go installs
|
||||
|
||||
# Verify you're using the correct version
|
||||
which bd # Should show /opt/homebrew/bin/bd or your package manager's path
|
||||
bd version # Should show the latest version
|
||||
```
|
||||
|
||||
### 4. GitHub Releases (Automated)
|
||||
|
||||
**GoReleaser automatically creates releases when you push tags!**
|
||||
|
||||
The `.github/workflows/release.yml` workflow:
|
||||
- Triggers on `v*` tags
|
||||
- Builds cross-platform binaries (Linux, macOS, Windows for amd64/arm64)
|
||||
- Generates checksums
|
||||
- Creates GitHub release with binaries and changelog
|
||||
- Publishes release automatically
|
||||
|
||||
Just push your tag and wait ~5 minutes:
|
||||
```bash
|
||||
git push origin v0.9.X
|
||||
```
|
||||
|
||||
Monitor at: https://github.com/steveyegge/beads/actions
|
||||
|
||||
The release will appear at: https://github.com/steveyegge/beads/releases
|
||||
|
||||
## Post-Release
|
||||
|
||||
1. **Kill old daemons again**:
|
||||
```bash
|
||||
pkill -f "bd.*daemon"
|
||||
pgrep -lf "bd.*daemon" || echo "No daemons running ✓"
|
||||
```
|
||||
This ensures your local machine picks up the new version immediately.
|
||||
|
||||
2. **Verify installations**:
|
||||
```bash
|
||||
# Homebrew
|
||||
brew update && brew upgrade bd && bd version
|
||||
|
||||
# PyPI
|
||||
pip install --upgrade beads-mcp
|
||||
beads-mcp --help
|
||||
|
||||
# Check daemon version matches client
|
||||
bd version --daemon # Should match client version after first command
|
||||
```
|
||||
|
||||
3. **Announce** (optional):
|
||||
- Project Discord/Slack
|
||||
- Twitter/social media
|
||||
- README badges
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Stale dist/ directory
|
||||
Always `rm -rf dist/` before `uv build` to avoid uploading old versions.
|
||||
|
||||
### PyPI version conflict
|
||||
PyPI doesn't allow re-uploading same version. Increment version number even for fixes.
|
||||
|
||||
### Homebrew SHA256 mismatch
|
||||
Wait a few seconds after pushing tag for GitHub to make tarball available, then recompute SHA256.
|
||||
|
||||
### Missing PyPI credentials
|
||||
Set up API token at https://pypi.org/manage/account/token/ and use `__token__` as username.
|
||||
|
||||
## Automation Status
|
||||
|
||||
✅ **Automated:**
|
||||
- GitHub releases with binaries (GoReleaser + GitHub Actions)
|
||||
- PyPI publish (automated via GitHub Actions)
|
||||
- Cross-platform builds (Linux, macOS, Windows)
|
||||
- Checksums and changelog generation
|
||||
|
||||
🔄 **TODO:**
|
||||
- Auto-update Homebrew formula
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [CHANGELOG.md](CHANGELOG.md) - Release history
|
||||
- [scripts/README.md](scripts/README.md) - Version bump script details
|
||||
- [integrations/beads-mcp/PYPI.md](integrations/beads-mcp/PYPI.md) - Detailed PyPI guide
|
||||
Reference in New Issue
Block a user