chore: git cache cleanup
This commit is contained in:
420
docs/development/go_version_upgrades.md
Normal file
420
docs/development/go_version_upgrades.md
Normal file
@@ -0,0 +1,420 @@
|
||||
# Go Version Upgrades
|
||||
|
||||
**Last Updated:** 2026-02-12
|
||||
|
||||
## The Short Version
|
||||
|
||||
When Charon upgrades to a new Go version, your development tools (like golangci-lint) break. Here's how to fix it:
|
||||
|
||||
```bash
|
||||
# Step 1: Pull latest code
|
||||
git pull
|
||||
|
||||
# Step 2: Update your Go installation
|
||||
.github/skills/scripts/skill-runner.sh utility-update-go-version
|
||||
|
||||
# Step 3: Rebuild tools
|
||||
./scripts/rebuild-go-tools.sh
|
||||
|
||||
# Step 4: Restart your IDE
|
||||
# VS Code: Cmd/Ctrl+Shift+P → "Developer: Reload Window"
|
||||
```
|
||||
|
||||
That's it! Keep reading if you want to understand why.
|
||||
|
||||
---
|
||||
|
||||
## What's Actually Happening?
|
||||
|
||||
### The Problem (In Plain English)
|
||||
|
||||
Think of Go tools like a Swiss Army knife. When you upgrade Go, it's like switching from metric to imperial measurements—your old knife still works, but the measurements don't match anymore.
|
||||
|
||||
Here's what breaks:
|
||||
|
||||
1. **Renovate updates the project** to Go 1.26.0
|
||||
2. **Your tools are still using** Go 1.25.6
|
||||
3. **Pre-commit hooks fail** with confusing errors
|
||||
4. **Your IDE gets confused** and shows red squiggles everywhere
|
||||
|
||||
### Why Tools Break
|
||||
|
||||
Development tools like golangci-lint are compiled programs. They were built with Go 1.25.6 and expect Go 1.25.6's features. When you upgrade to Go 1.26.0:
|
||||
|
||||
- New language features exist that old tools don't understand
|
||||
- Standard library functions change
|
||||
- Your tools throw errors like: `undefined: someNewFunction`
|
||||
|
||||
**The Fix:** Rebuild tools with the new Go version so they match your project.
|
||||
|
||||
---
|
||||
|
||||
## Step-by-Step Upgrade Guide
|
||||
|
||||
### Step 1: Know When an Upgrade Happened
|
||||
|
||||
Renovate (our automated dependency manager) will open a PR titled something like:
|
||||
|
||||
```
|
||||
chore(deps): update golang to v1.26.0
|
||||
```
|
||||
|
||||
When this gets merged, you'll need to update your local environment.
|
||||
|
||||
### Step 2: Pull the Latest Code
|
||||
|
||||
```bash
|
||||
cd /projects/Charon
|
||||
git checkout development
|
||||
git pull origin development
|
||||
```
|
||||
|
||||
### Step 3: Update Your Go Installation
|
||||
|
||||
**Option A: Use the Automated Skill (Recommended)**
|
||||
|
||||
```bash
|
||||
.github/skills/scripts/skill-runner.sh utility-update-go-version
|
||||
```
|
||||
|
||||
This script:
|
||||
- Detects the required Go version from `go.work`
|
||||
- Downloads it from golang.org
|
||||
- Installs it to `~/sdk/go{version}/`
|
||||
- Updates your system symlink to point to it
|
||||
- Rebuilds your tools automatically
|
||||
|
||||
**Option B: Manual Installation**
|
||||
|
||||
If you prefer to install Go manually:
|
||||
|
||||
1. Go to [go.dev/dl](https://go.dev/dl/)
|
||||
2. Download the version mentioned in the PR (e.g., 1.26.0)
|
||||
3. Install it following the official instructions
|
||||
4. Verify: `go version` should show the new version
|
||||
5. Continue to Step 4
|
||||
|
||||
### Step 4: Rebuild Development Tools
|
||||
|
||||
Even if you used Option A (which rebuilds automatically), you can always manually rebuild:
|
||||
|
||||
```bash
|
||||
./scripts/rebuild-go-tools.sh
|
||||
```
|
||||
|
||||
This rebuilds:
|
||||
- **golangci-lint** — Pre-commit linter (critical)
|
||||
- **gopls** — IDE language server (critical)
|
||||
- **govulncheck** — Security scanner
|
||||
- **dlv** — Debugger
|
||||
|
||||
**Duration:** About 30 seconds
|
||||
|
||||
**Output:** You'll see:
|
||||
|
||||
```
|
||||
🔧 Rebuilding Go development tools...
|
||||
Current Go version: go version go1.26.0 linux/amd64
|
||||
|
||||
📦 Installing golangci-lint...
|
||||
✅ golangci-lint installed successfully
|
||||
|
||||
📦 Installing gopls...
|
||||
✅ gopls installed successfully
|
||||
|
||||
...
|
||||
|
||||
✅ All tools rebuilt successfully!
|
||||
```
|
||||
|
||||
### Step 5: Restart Your IDE
|
||||
|
||||
Your IDE caches the old Go language server (gopls). Reload to use the new one:
|
||||
|
||||
**VS Code:**
|
||||
- Press `Cmd/Ctrl+Shift+P`
|
||||
- Type "Developer: Reload Window"
|
||||
- Press Enter
|
||||
|
||||
**GoLand or IntelliJ IDEA:**
|
||||
- File → Invalidate Caches → Restart
|
||||
- Wait for indexing to complete
|
||||
|
||||
### Step 6: Verify Everything Works
|
||||
|
||||
Run a quick test:
|
||||
|
||||
```bash
|
||||
# This should pass without errors
|
||||
go test ./backend/...
|
||||
```
|
||||
|
||||
If tests pass, you're done! 🎉
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "golangci-lint: command not found"
|
||||
|
||||
**Problem:** Your `$PATH` doesn't include Go's binary directory.
|
||||
|
||||
**Fix:**
|
||||
|
||||
```bash
|
||||
# Add to ~/.bashrc or ~/.zshrc
|
||||
export PATH="$PATH:$(go env GOPATH)/bin"
|
||||
|
||||
# Reload your shell
|
||||
source ~/.bashrc # or source ~/.zshrc
|
||||
```
|
||||
|
||||
Then rebuild tools:
|
||||
|
||||
```bash
|
||||
./scripts/rebuild-go-tools.sh
|
||||
```
|
||||
|
||||
### Error: Pre-commit hook still failing
|
||||
|
||||
**Problem:** Pre-commit is using a cached version of the tool.
|
||||
|
||||
**Fix 1: Let the hook auto-rebuild**
|
||||
|
||||
The pre-commit hook detects version mismatches and rebuilds automatically. Just commit again:
|
||||
|
||||
```bash
|
||||
git commit -m "your message"
|
||||
# Hook detects mismatch, rebuilds tool, and retries
|
||||
```
|
||||
|
||||
**Fix 2: Manual rebuild**
|
||||
|
||||
```bash
|
||||
./scripts/rebuild-go-tools.sh
|
||||
git commit -m "your message"
|
||||
```
|
||||
|
||||
### Error: "package X is not in GOROOT"
|
||||
|
||||
**Problem:** Your project's `go.work` or `go.mod` specifies a Go version you don't have installed.
|
||||
|
||||
**Check required version:**
|
||||
|
||||
```bash
|
||||
grep '^go ' go.work
|
||||
# Output: go 1.26.0
|
||||
```
|
||||
|
||||
**Install that version:**
|
||||
|
||||
```bash
|
||||
.github/skills/scripts/skill-runner.sh utility-update-go-version
|
||||
```
|
||||
|
||||
### IDE showing errors but code compiles fine
|
||||
|
||||
**Problem:** Your IDE's language server (gopls) is out of date.
|
||||
|
||||
**Fix:**
|
||||
|
||||
```bash
|
||||
# Rebuild gopls
|
||||
go install golang.org/x/tools/gopls@latest
|
||||
|
||||
# Restart IDE
|
||||
# VS Code: Cmd/Ctrl+Shift+P → "Developer: Reload Window"
|
||||
```
|
||||
|
||||
### "undefined: someFunction" errors
|
||||
|
||||
**Problem:** Your tools were built with an old Go version and don't recognize new standard library functions.
|
||||
|
||||
**Fix:**
|
||||
|
||||
```bash
|
||||
./scripts/rebuild-go-tools.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### How often do Go versions change?
|
||||
|
||||
Go releases **two major versions per year**:
|
||||
- February (e.g., Go 1.26.0)
|
||||
- August (e.g., Go 1.27.0)
|
||||
|
||||
Plus occasional patch releases (e.g., Go 1.26.1) for security fixes.
|
||||
|
||||
**Bottom line:** Expect to run `./scripts/rebuild-go-tools.sh` 2-3 times per year.
|
||||
|
||||
### Do I need to rebuild tools for patch releases?
|
||||
|
||||
**Usually no**, but it doesn't hurt. Patch releases (like 1.26.0 → 1.26.1) rarely break tool compatibility.
|
||||
|
||||
**Rebuild if:**
|
||||
- Pre-commit hooks start failing
|
||||
- IDE shows unexpected errors
|
||||
- Tools report version mismatches
|
||||
|
||||
### Why don't CI builds have this problem?
|
||||
|
||||
CI environments are **ephemeral** (temporary). Every workflow run:
|
||||
1. Starts with a fresh container
|
||||
2. Installs Go from scratch
|
||||
3. Installs tools from scratch
|
||||
4. Runs tests
|
||||
5. Throws everything away
|
||||
|
||||
**Local development** has persistent tool installations that get out of sync.
|
||||
|
||||
### Can I use multiple Go versions on my machine?
|
||||
|
||||
**Yes!** Go officially supports this via `golang.org/dl`:
|
||||
|
||||
```bash
|
||||
# Install Go 1.25.6
|
||||
go install golang.org/dl/go1.25.6@latest
|
||||
go1.25.6 download
|
||||
|
||||
# Install Go 1.26.0
|
||||
go install golang.org/dl/go1.26.0@latest
|
||||
go1.26.0 download
|
||||
|
||||
# Use specific version
|
||||
go1.25.6 version
|
||||
go1.26.0 test ./...
|
||||
```
|
||||
|
||||
But for Charon development, you only need **one version** (whatever's in `go.work`).
|
||||
|
||||
### What if I skip an upgrade?
|
||||
|
||||
**Short answer:** Your local tools will be out of sync, but CI will still work.
|
||||
|
||||
**What breaks:**
|
||||
- Pre-commit hooks fail (but will auto-rebuild)
|
||||
- IDE shows phantom errors
|
||||
- Manual `go test` might fail locally
|
||||
- CI is unaffected (it always uses the correct version)
|
||||
|
||||
**When to catch up:**
|
||||
- Before opening a PR (CI checks will fail if your code uses old Go features)
|
||||
- When local development becomes annoying
|
||||
|
||||
### Should I keep old Go versions installed?
|
||||
|
||||
**No need.** The upgrade script preserves old versions in `~/sdk/`, but you don't need to do anything special.
|
||||
|
||||
If you want to clean up:
|
||||
|
||||
```bash
|
||||
# See installed versions
|
||||
ls ~/sdk/
|
||||
|
||||
# Remove old versions
|
||||
rm -rf ~/sdk/go1.25.5
|
||||
rm -rf ~/sdk/go1.25.6
|
||||
```
|
||||
|
||||
But they only take ~400MB each, so cleanup is optional.
|
||||
|
||||
### Why doesn't Renovate upgrade tools automatically?
|
||||
|
||||
Renovate updates **Dockerfile** and **go.work**, but it can't update tools on *your* machine.
|
||||
|
||||
**Think of it like this:**
|
||||
- Renovate: "Hey team, we're now using Go 1.26.0"
|
||||
- Your machine: "Cool, but my tools are still Go 1.25.6. Let me rebuild them."
|
||||
|
||||
The rebuild script bridges that gap.
|
||||
|
||||
### What's the difference between `go.work`, `go.mod`, and my system Go?
|
||||
|
||||
**`go.work`** — Workspace file (multi-module projects like Charon)
|
||||
- Specifies minimum Go version for the entire project
|
||||
- Used by Renovate to track upgrades
|
||||
|
||||
**`go.mod`** — Module file (individual Go modules)
|
||||
- Each module (backend, tools) has its own `go.mod`
|
||||
- Inherits Go version from `go.work`
|
||||
|
||||
**System Go** (`go version`) — What's installed on your machine
|
||||
- Must be >= the version in `go.work`
|
||||
- Tools are compiled with whatever version this is
|
||||
|
||||
**Example:**
|
||||
```
|
||||
go.work says: "Use Go 1.26.0 or newer"
|
||||
go.mod says: "I'm part of the workspace, use its Go version"
|
||||
Your machine: "I have Go 1.26.0 installed"
|
||||
Tools: "I was built with Go 1.25.6" ❌ MISMATCH
|
||||
```
|
||||
|
||||
Running `./scripts/rebuild-go-tools.sh` fixes the mismatch.
|
||||
|
||||
---
|
||||
|
||||
## Advanced: Pre-commit Auto-Rebuild
|
||||
|
||||
Charon's pre-commit hook automatically detects and fixes tool version mismatches.
|
||||
|
||||
**How it works:**
|
||||
|
||||
1. **Check versions:**
|
||||
```bash
|
||||
golangci-lint version → "built with go1.25.6"
|
||||
go version → "go version go1.26.0"
|
||||
```
|
||||
|
||||
2. **Detect mismatch:**
|
||||
```
|
||||
⚠️ golangci-lint Go version mismatch:
|
||||
golangci-lint: 1.25.6
|
||||
system Go: 1.26.0
|
||||
```
|
||||
|
||||
3. **Auto-rebuild:**
|
||||
```
|
||||
🔧 Rebuilding golangci-lint with current Go version...
|
||||
✅ golangci-lint rebuilt successfully
|
||||
```
|
||||
|
||||
4. **Retry linting:**
|
||||
Hook runs again with the rebuilt tool.
|
||||
|
||||
**What this means for you:**
|
||||
|
||||
The first commit after a Go upgrade will be **slightly slower** (~30 seconds for tool rebuild). Subsequent commits are normal speed.
|
||||
|
||||
**Disabling auto-rebuild:**
|
||||
|
||||
If you want manual control, edit `scripts/pre-commit-hooks/golangci-lint-fast.sh` and remove the rebuild logic. (Not recommended.)
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- **[Go Version Management Strategy](../plans/go_version_management_strategy.md)** — Research and design decisions
|
||||
- **[CONTRIBUTING.md](../../CONTRIBUTING.md)** — Quick reference for contributors
|
||||
- **[Go Official Docs](https://go.dev/doc/manage-install)** — Official multi-version management guide
|
||||
|
||||
---
|
||||
|
||||
## Need Help?
|
||||
|
||||
**Open a [Discussion](https://github.com/Wikid82/charon/discussions)** if:
|
||||
- These instructions didn't work for you
|
||||
- You're seeing errors not covered in troubleshooting
|
||||
- You have suggestions for improving this guide
|
||||
|
||||
**Open an [Issue](https://github.com/Wikid82/charon/issues)** if:
|
||||
- The rebuild script crashes
|
||||
- Pre-commit auto-rebuild isn't working
|
||||
- CI is failing for Go version reasons
|
||||
|
||||
---
|
||||
|
||||
**Remember:** Go upgrades happen 2-3 times per year. When they do, just run `./scripts/rebuild-go-tools.sh` and you're good to go! 🚀
|
||||
Reference in New Issue
Block a user