[teamai] Push 87 resource(s) from XingfenD

This commit is contained in:
2026-09-10 16:10:45 +08:00
parent 425c9c078a
commit 65c04def51
1314 changed files with 211681 additions and 0 deletions
@@ -0,0 +1,84 @@
# Auditing Dependencies
## Test-Only vs Binary Dependencies
Go's `go.mod` does **not** distinguish between test-only and production dependencies. All modules appear together, with `// indirect` marking transitive dependencies.
### What Gets Included in Your Binary
- `*_test.go` files are **never** compiled by `go build` — only by `go test`
- Packages imported only by test files are not linked into the final binary
- However, their modules still appear in `go.mod`
### Module Graph Pruning (Go 1.17+)
With `go 1.17` or higher in `go.mod`, Go prunes the module graph: transitive dependencies needed only for tests of other modules are excluded from the build graph. This reduces `go.mod` size and avoids downloading unnecessary modules.
### Upgrading With or Without Test Dependencies
```bash
go get -u ./... # Upgrade deps, EXCLUDING test-only deps
go get -u -t ./... # Upgrade deps, INCLUDING test-only deps
```
### Impact on Binary Size
To check whether a large dependency is actually linked into your binary (vs. only used in tests), use `goweight` or `go-size-analyzer` — if the package doesn't appear in the binary breakdown, it's test-only and not contributing to binary size.
## Vulnerability Scanning with govulncheck
`govulncheck` reports known vulnerabilities that affect your code. It uses static analysis to narrow reports to vulnerabilities in code paths your project actually calls — unlike generic CVE scanners that flag every dependency regardless of usage.
```bash
# Scan source code (most common)
govulncheck ./...
# Or, when govulncheck is pinned with a Go 1.24+ tool directive:
go tool govulncheck ./...
# Scan a compiled binary
govulncheck -mode=binary ./bin/myapp
# JSON output (for CI integration)
govulncheck -format json ./...
# Include test code in analysis
govulncheck -test ./...
```
Output shows the vulnerability ID, affected module, fixed version, and the call trace from your code to the vulnerable function. If a vulnerability exists in a dependency but your code never calls the affected function, `govulncheck` does not flag it.
For CI pipeline integration, see the `samber/cc-skills-golang@golang-continuous-integration` skill.
## Tracking Outdated Dependencies with go-mod-outdated
`psampaz/go-mod-outdated` lists outdated direct dependencies with available updates.
```bash
# Show outdated direct dependencies with available updates
go list -u -m -json all | go-mod-outdated -update -direct
# Fail in CI if dependencies are outdated
go list -u -m -json all | go-mod-outdated -update -direct -ci
# Markdown output
go list -u -m -json all | go-mod-outdated -update -direct -style markdown
```
Output columns: MODULE, CURRENT version, WANTED (latest minor/patch), LATEST (latest overall), and VALID TIMESTAMPS (warns if an "update" is chronologically older than current).
## Analyzing Dependency Size with goweight
`jondot/goweight` lists every package linked into the binary sorted by size contribution. It helps identify bloated dependencies and evaluate whether a lighter alternative exists.
```bash
goweight # Sort by size
goweight --json # JSON output for CI tracking
```
**Modern alternative**: [go-size-analyzer](https://github.com/Zxilly/go-size-analyzer) (`gsa`) supports ELF, Mach-O, PE, and WebAssembly formats with interactive HTML/SVG visualization:
```bash
go get -tool github.com/Zxilly/go-size-analyzer/cmd/gsa@latest
go build -o ./myapp ./cmd/myapp
go tool gsa -f html -o size-report.html ./myapp
```
@@ -0,0 +1,35 @@
# Automated Dependency Updates
Automate minor/patch dependency updates to reduce maintenance burden and stay current with security fixes. This requires a solid CI pipeline — tests and linting must pass before any auto-merge.
## Dependabot vs Renovate
| Feature | Dependabot | Renovate |
| --- | --- | --- |
| Platform | GitHub only | GitHub, GitLab, Bitbucket, self-hosted |
| `go mod tidy` | Automatic | Opt-in (`gomodTidy`) |
| Automerge | Separate workflow | Native support |
| Grouping | Pattern-based | More flexible rules |
| Monorepo support | Basic | Go workspaces aware |
| Regex managers | No | Yes (Dockerfiles, Makefiles, etc) |
**Renovate is generally more mature and configurable.** Dependabot is simpler to set up for GitHub-only projects.
## Auto-Merge Strategy
- **Minor and patch updates**: Auto-merge only after CI passes (tests + lint + govulncheck) and the package is low-risk for the project
- **Major updates**: Create PR for manual review (may contain breaking changes)
- **Security updates**: Auto-merge regardless of version bump type
For workflow configuration files (dependabot.yml, renovate.json, auto-merge workflows), see the `samber/cc-skills-golang@golang-continuous-integration` skill.
## Update Verification
Before committing a dependency update:
0. Changelogs may suggest improvements applicable to the project.
1. Run `go test ./...` and `go build ./...`
2. Scan with `govulncheck ./...` or `go tool govulncheck ./...`
3. Release notes/changelogs for libraries that affect persistence, serialization, networking, authentication, authorization, cryptography, or public APIs may contain important information about breaking changes
4. Major version upgrades may contain breaking changes — the package's changelog documents them
5. New APIs or patterns introduced in the updated version may offer improvements worth considering
@@ -0,0 +1,75 @@
# Dependency Conflicts & Resolution
## Diagnosing Conflicts
```bash
# See why a module is in your build
go mod why -m github.com/some/module
# See which version is selected
go list -m github.com/some/module
# See the full requirement graph
go mod graph
# List all modules in the build
go list -m all
```
## Resolution Strategies
**Force a specific version** (when two deps require incompatible versions):
```bash
go mod edit -replace=example.com/pkg@v1.2.0=example.com/pkg@v1.3.1
```
```go
// go.mod
replace example.com/pkg v1.2.0 => example.com/pkg v1.3.1
```
**Use a local fork** (for debugging or patching):
```go
replace example.com/pkg => ../my-local-fork
```
**Block a problematic version**:
```bash
go mod edit -exclude=example.com/pkg@v1.3.0
```
When a version is excluded, any requirement on that version is redirected to the next higher available version.
**Force upgrade a transitive dependency**:
```bash
go get github.com/transitive/dep@v1.5.0
```
This adds an explicit requirement in your `go.mod`, overriding whatever the transitive dependency chain would select via MVS.
## Resolution Workflow
1. Run `go mod graph` and `go mod why -m <module>` to understand the dependency chain
2. Identify which of your direct dependencies pulls in the conflicting version
3. Try upgrading the direct dependency first: `go get github.com/direct/dep@latest`
4. If that doesn't resolve it, use `replace` or `exclude` as a temporary fix
5. Run `go mod tidy` to clean up
6. Verify with `go build ./...` and `go test ./...`
**Important**: `replace` and `exclude` directives only take effect in the **main module's** `go.mod`. They are ignored when your module is used as a dependency. Remove `replace` directives before publishing a library.
## Retract (For Module Authors)
Mark versions as broken or accidentally published:
```go
// go.mod
retract v1.0.0 // Contains critical bug in auth
retract [v1.1.0, v1.2.0] // Range of broken versions
```
Retracted versions are still downloadable but `go get` will not select them by default, and `go list -m -u` warns about them.
@@ -0,0 +1,57 @@
# Versioning & Minimal Version Selection
## Semantic Versioning (SemVer)
Go modules use **`vMAJOR.MINOR.PATCH`** (the `v` prefix is required):
- **MAJOR**: Breaking changes to the public API
- **MINOR**: Backward-compatible new functionality
- **PATCH**: Backward-compatible bug fixes
### Stability Rules
| Version | Stability |
| ----------- | ----------------------------------------- |
| `v0.x.x` | Unstable — no compatibility guarantees |
| `v1.x.x`+ | Stable — backward-compatible within major |
| Pre-release | Unstable (e.g., `v1.5.0-beta.1`) |
### Major Version Suffix Rule
For `v2` and above, the module path must include a `/vN` suffix. This is Go's import compatibility rule — different major versions are treated as entirely separate modules, allowing them to coexist in the same build:
```go
// go.mod
module github.com/example/pkg/v2
// Import in code
import "github.com/example/pkg/v2/subpkg"
```
Tags: `v2.0.0`, `v2.1.0`, etc. The `v0` and `v1` versions have no suffix.
### Special Cases
- **Pseudo-versions**: For untagged commits — `v0.0.0-20210101120000-abcdef123456` (base version + timestamp + commit hash)
- **`+incompatible`**: Marks `v2+` modules that have not adopted the `/vN` path convention
- **`gopkg.in`**: Always uses a version suffix with a dot — `gopkg.in/yaml.v3`
## Minimal Version Selection (MVS)
Go's dependency resolution algorithm is fundamentally different from npm, pip, or cargo.
### How It Works
Most package managers select the **latest** compatible version of each dependency. Go does the opposite: it selects the **minimum version that satisfies all requirements**. If module A requires `pkg@v1.2.0` and module B requires `pkg@v1.3.0`, MVS selects `v1.3.0` — the highest minimum required, not the latest available.
### Why This Design
- **Deterministic without a lock file**: Given the same `go.mod` inputs, MVS always produces the same build list. `go.sum` is just integrity verification.
- **High fidelity**: Builds closely match what module authors tested against, since the nearest compatible version is selected rather than the latest.
- **No solver needed**: The algorithm is simple graph traversal (under 50 lines of code), not an NP-hard constraint satisfaction problem.
- **Reproducible across machines**: No "works on my machine" from different lock file states.
### Upgrades and Downgrades
- **Upgrade**: `go get pkg@v1.5.0` adds an edge to `v1.5.0` in the module graph and reruns MVS. Only the minimum necessary changes propagate.
- **Downgrade**: `go get pkg@v1.2.0` removes all versions above `v1.2.0` from the graph, then walks backward to find the latest remaining versions of affected dependencies.
@@ -0,0 +1,48 @@
# Visualizing the Dependency Graph
## go mod graph (Built-in)
```bash
go mod graph
```
Output: each line contains two space-separated fields (module and its requirement) in `path@version` format:
```
example.com/main github.com/google/uuid@v1.6.0
example.com/main golang.org/x/text@v0.3.7
github.com/google/uuid@v1.6.0 golang.org/x/sys@v0.0.0-20210615035016
```
## go mod why
```bash
go mod why -m github.com/some/module
```
Shows the shortest import path from your code to the module — useful for understanding why an unexpected dependency exists.
## Generate a Graph Image with modgraphviz
Pin `modgraphviz` as a module tool, then pipe `go mod graph` into it.
```bash
go get -tool golang.org/x/exp/cmd/modgraphviz@latest
go mod graph | go tool modgraphviz | dot -Tpng -o deps.png
```
Green nodes represent versions selected by MVS (in the final build list). Grey nodes are versions that exist in the requirement graph but are not used.
## Interactive Visualization with go-mod-graph
`go-mod-graph` (samber/go-mod-graph) is a web-based interactive dependency explorer with zoomable graph, module weight indicators, searchable module list, and MVS algorithm visualization.
## Complementary Analysis
Pin `digraph` as a module tool for graph queries.
```bash
go get -tool golang.org/x/tools/cmd/digraph@latest
# General graph queries on go mod graph output
go mod graph | go tool digraph reverse example.com/some/module
```
@@ -0,0 +1,27 @@
# Go Workspaces (go.work)
## go.work vs go.mod
| Scenario | Use |
| ---------------------------------------------- | --------- |
| Single module project | `go.mod` |
| Developing multiple related local modules | `go.work` |
| Monorepo with separate Go modules | `go.work` |
| Testing local changes across module boundaries | `go.work` |
| Published library consumed by others | `go.mod` |
## Workspace Commands
```bash
go work init # Initialize workspace
go work use ./services/auth # Add module to workspace
go work use -rm ./old-module # Remove module from workspace
go work sync # Sync workspace with module changes
```
## Key Points
- Workspaces eliminate the need for `replace` directives during local development — the workspace automatically resolves local modules
- **Do not commit `go.work.sum`** to version control (add to `.gitignore`)
- `go.work` is for development only — it does not affect how consumers of your published modules resolve dependencies
- For workspace directory structure examples, see the `samber/cc-skills-golang@golang-project-layout` skill