* fix: repair Renovate config and convert Makefile to go run (#117) - Remove non-existent `github>renovatebot/presets:golang` preset that broke Renovate PR creation - Replace deprecated `fileMatch` with `managerFilePatterns` in customManagers - Rewrite regex to match new Makefile pattern (renovate comment above version variable assignment) - Fix `matchFileNames` glob pattern (`*.mk` -> `**/*.mk`) - Convert all tool invocations from `go install` + global binary to `go run tool@version` for reproducible builds - Convert npm global tools to `npx --yes` invocations - Remove `dev-deps` and `check-deps` targets (tools auto-download) - Add mdformat pre-commit hook with GFM support and config - Add `fmt-md` Makefile target for manual markdown formatting - Update local golangci-lint pre-commit hook to use `go run` - Apply golangci-lint v2.10.1 auto-fixes (fmt.Fprintf optimization) - Add nolint:gosec annotations for legitimate exec.Command usage - Exclude .serena/ from mdformat and megalinter - Add markdown indent_size=unset in .editorconfig for CommonMark compat * chore(deps): update GitHub Actions to latest versions - anthropics/claude-code-action: v1.0.34 -> v1.0.64 - actions/setup-go: v6.2.0 -> v6.3.0 - actions/upload-artifact: v6.0.0 -> v7.0.0 - goreleaser/goreleaser-action: v6.4.0 -> v7.0.0 - docker/login-action: v3.6.0 -> v3.7.0 - ivuorinen/actions: v2026.01.21 -> v2026.02.24 * fix: address code review feedback - Fix issue template YAML frontmatter (replace underscore separators with proper --- delimiters); exclude templates from mdformat - Replace string(rune(n)) with strconv.Itoa(n) in test files to produce deterministic numeric directory names instead of Unicode characters - Remove stale `make dev-deps` reference in README, replace with `make dev-setup` - Extract ban/unban format strings into shared.MetricsFmtBanOperations and shared.MetricsFmtUnbanOperations constants - Replace hardcoded coverage percentages in README with evergreen phrasing * fix: address round 2 code review feedback for PR #120 - Fix corrupted path traversal example in docs/security.md - Fix Renovate .mk regex to match nested paths (.*\.mk$) - Update checkmake pre-commit hook to v0.3.2 to match Makefile - Add sync.WaitGroup to unsynchronized goroutines in security tests - Fix fmt-md target to use pre-commit run mdformat - Pin markdownlint-cli2 to v0.21.0 in lint-md target - Standardize //nolint:gosec to // #nosec annotations for gosec CLI * fix(ci): install PyYAML dependency for PR lint workflow The pr-lint workflow uses ivuorinen/actions/pr-lint which internally calls validate-inputs running a Python script that imports yaml. Python was set up but PyYAML was never installed, causing ModuleNotFoundError at runtime. * fix: address round 3 code review feedback for PR #120 - Wrap Windows-style path traversal example in backtick code span so backslashes render literally in docs/security.md - Add Renovate-managed MARKDOWNLINT_CLI2_VERSION variable in Makefile to match the pattern used by all other tool versions
8.4 KiB
Linting and Code Quality
This document describes the linting and code quality tools used in the f2b project.
Overview
The project uses a unified pre-commit approach for linting and code quality, ensuring consistency across development, CI, and pre-commit hooks.
Supported Tools
- Go:
gofmt,go-build-mod,go-mod-tidy,golangci-lint - Markdown:
markdownlint - YAML:
yamlfmt(Google's YAML formatter) - GitHub Actions:
actionlint - EditorConfig:
editorconfig-checker - Makefile:
checkmake
Quick Start
Install Development Dependencies
make dev-deps
Set Up Pre-commit (Recommended)
make pre-commit-setup
# or manually:
pip install pre-commit
pre-commit install
Run All Linters
Preferred Method (Unified Tooling):
# Run all linting and formatting checks
make lint
# Run all linters with strict mode
make lint-strict
# Run linters with auto-fix
make lint-fix
Individual Pre-commit Hooks:
# Run specific hook
pre-commit run yamlfmt --all-files
pre-commit run golangci-lint --all-files
pre-commit run markdownlint --all-files
pre-commit run checkmake --all-files
Individual Tool Commands:
make lint-go # Go only
make lint-yaml # YAML only
make lint-actions # GitHub Actions only
make lint-make # Makefile only
Configuration Files
Read these files BEFORE making changes:
.editorconfig: Indentation, final newlines, encoding.golangci.yml: Go linting rules and timeout settings.markdownlint.json: Markdown formatting rules (120 char limit).yamlfmt.yaml: YAML formatting rules.pre-commit-config.yaml: Pre-commit hook configuration
Linting Tools
Go Linting
gofmt (via pre-commit-golang)
- Purpose: Code formatting
- Configuration: Uses Go standard formatting
- Hook:
go-fmt
go-build-mod (via pre-commit-golang)
- Purpose: Verify code builds
- Configuration: Uses go.mod
- Hook:
go-build-mod
go-mod-tidy (via pre-commit-golang)
- Purpose: Clean up go.mod and go.sum
- Configuration: Automatic
- Hook:
go-mod-tidy
golangci-lint (local hook)
- Purpose: Comprehensive Go linting with multiple analyzers
- Configuration:
.golangci.yml - Features: 50+ linters, fast caching, detailed reporting
- Hook:
golangci-lint
Markdown Linting
markdownlint (local hook)
- Purpose: Markdown formatting and style consistency
- Configuration:
.markdownlint.json - Key rules:
- Line length limit: 120 characters
- Disabled: HTML tags, bare URLs, first-line heading requirement
- Hook:
markdownlint
YAML Linting
yamlfmt (official Google repo)
- Purpose: YAML formatting and linting
- Configuration:
.yamlfmt.yaml - Key features:
- Document start markers (
---) - Line length limit: 120 characters
- Respects .gitignore
- Retains single line breaks
- EOF newlines
- Document start markers (
- Hook:
yamlfmt
GitHub Actions Linting
actionlint (local hook)
- Purpose: GitHub Actions workflow validation
- Configuration: Default configuration
- Features:
- Syntax validation
- shellcheck integration
- Action version checking
- Expression validation
- Hook:
actionlint
EditorConfig
editorconfig-checker (local hook)
- Purpose: Verify EditorConfig compliance
- Configuration:
.editorconfig - Features: Checks indentation, final newlines, encoding
- Hook:
editorconfig-checker
Makefile Linting
checkmake (official repo)
- Purpose: Makefile syntax and best practices validation
- Configuration: Default rules (no config file needed)
- Features:
- Checks for missing
.PHONYdeclarations - Validates target dependencies
- Enforces Makefile best practices
- Detects syntax errors and common mistakes
- Checks for missing
- Hook:
checkmake - Manual Usage:
checkmake Makefile
Pre-commit Integration
The project uses .pre-commit-config.yaml for unified tooling:
Hook Sources
- pre-commit/pre-commit-hooks: Basic file checks
- tekwizely/pre-commit-golang: Go-specific hooks
- google/yamlfmt: Official YAML formatter
- mrtazz/checkmake: Official Makefile linter
- local: Custom hooks for project-specific tools
Automatic Setup
# Install pre-commit and hooks
make pre-commit-setup
# Hooks will run automatically on commit
git commit -m "your changes"
Manual Execution
# Run all hooks
pre-commit run --all-files
# Run specific hook
pre-commit run yamlfmt
pre-commit run golangci-lint
pre-commit run checkmake
# Update hook versions
pre-commit autoupdate
CI Integration
GitHub Actions
Both workflows now use unified pre-commit:
.github/workflows/lint.yml: Main linting workflow.github/workflows/pr-lint.yml: Pull request linting
Workflow Features
- Single
pre-commit/action@v3.0.1step - Automatic tool installation and caching
- Consistent behavior with local development
- Python and Go environment setup
Development Workflow
Before Committing
- Read configuration files first:
.editorconfig,.golangci.yml,.markdownlint.json,.yamlfmt.yaml,.pre-commit-config.yaml - Apply configuration rules during development
- Run pre-commit checks:
pre-commit run --all-files - Fix all issues across the project
- Run tests:
go test ./...
Recommended IDE Setup
- Go: Use
goplslanguage server with auto-format on save - Markdown: Install markdownlint extension
- YAML: Install YAML extension with yamlfmt support
- EditorConfig: Install EditorConfig plugin
Configuration Details
.yamlfmt.yaml
---
# yaml-language-server: $schema=https://raw.githubusercontent.com/google/yamlfmt/main/schema.json
formatter:
type: basic
include_document_start: true
gitignore_excludes: true
retain_line_breaks_single: true
eof_newline: true
max_line_length: 120
indent: 2
.markdownlint.json
{
"default": true,
"MD013": {
"line_length": 120,
"headings": false,
"tables": false,
"code_blocks": false
},
"MD033": false,
"MD041": false,
"MD034": false
}
.golangci.yml
Comprehensive Go linting configuration with timeout settings and enabled/disabled linters.
Schema Support
All YAML files include schema references for better IDE support:
- GitHub workflows:
$schema=https://json.schemastore.org/github-workflow.json - Pre-commit config:
$schema=https://json.schemastore.org/pre-commit-config.json - GitHub labels:
$schema=https://json.schemastore.org/github-labels.json
Troubleshooting
Common Issues
Pre-commit hook failures
Solution: Run pre-commit run --all-files locally to identify issues
"command not found" errors
Solution: Run make dev-deps and make pre-commit-setup
YAML formatting differences
Solution: Use yamlfmt . to format files consistently
Debugging Tips
- Run individual hooks to isolate issues
- Use
--verboseflag with pre-commit - Check configuration files for rule customizations
- Verify tool versions match CI environment
Adding New Linting Rules
Process
- Update configuration files (
.markdownlint.json,.yamlfmt.yaml, etc.) - Test changes locally:
pre-commit run --all-files - Update
.pre-commit-config.yamlif adding new hooks - Document changes in this file
- Consider backward compatibility
Best Practices
- Start with warnings before making rules errors
- Use pre-commit for consistency across environments
- Test with existing codebase before enforcing
- Leverage auto-fix capabilities when available
Security Considerations
Tool Installation
- All tools installed from official repositories
- Versions pinned in
.pre-commit-config.yaml - Dependencies verified before execution
Code Analysis
- Linters help identify potential security issues
- Static analysis catches common vulnerabilities
- Configuration validation prevents misconfigurations
Performance
Optimization Tips
- Pre-commit caches tool installations
- Hooks run in parallel when possible
- Use
golangci-lintcache for faster Go linting - Skip unchanged files automatically
Benefits of Pre-commit
- Consistency: Same tools in dev, CI, and pre-commit
- Speed: Cached tool installations
- Reliability: No version mismatches
- Maintenance: Centralized configuration