can you look at ../cli and the github actions for CI there, can we add them

can you look at ../cli and the github actions for CI there, can we add similar ones we need? can you give me an overview and we decide together? main focus is on PR gates
Here's the overview:
CLI repo PR gates (what runs on every PR)
| Workflow | What it does |
|---|---|
| ci.yml | Unit + integration tests with -race detection, via mise run test:ci |
| lint.yml | golangci-lint (60+ linters, inline PR annotations), gofmt check, go mod tidy check, shellcheck, mise task validation |
| license-check.yml | Reusable workflow from entireio/shared for license compliance |
E2E tests only run on push to main, not as PR gates (too expensive/flaky).
git-sync current state
No CI at all - no .github/workflows/ directory exists. But the building blocks are ready in mise.toml:
mise run test→go test ./...mise run fmt→gofmt -s -wgolangci-lint2.11.3 installed (but no.golangci.ymlconfig file)shellcheckinstalled
What I'd propose for git-sync PR gates
| Workflow | Based on CLI's | Notes |
|---|---|---|
| ci.yml — Tests | Same pattern | go test -race ./... — skip the smoke/integration tests that need external services (test:git-http-backend, test:entire-local-smoke, etc.) |
| lint.yml — Linting | Same pattern | golangci-lint + gofmt check + go mod tidy check. We'd need to create a .golangci.yml — we could start with a reasonable subset of the CLI's 60+ linters, or copy it wholesale. Also add the golangci-lint-action for inline PR annotations. |
| license-check.yml | Direct reuse | Same shared workflow from entireio/shared |
Things to decide:
- Linter strictness — Start with a copy of the CLI's
.golangci.yml(may surface existing violations to fix) or start lighter and tighten over time? - Race detection — The CLI runs tests with
-racein CI. Worth doing here too? (Slight slowdown but catches real bugs in concurrent code.) - gnome-keyring — git-sync uses
go-keyringlike the CLI. The CLI's CI sets up gnome-keyring on Ubuntu for this. We'd likely need the same if any tests touch auth/keyring code. - License check — Want to include the shared
entireio/sharedlicense check workflow?
What's your call on these?
- full
- yes add -race
- can you check if we do that yet? but also if we don't have tests we should look into adding them
- yes, need to set the baseline then
That's ~330 real violations (the ones like sb, buf etc. are grep false positives). The breakdown of the significant ones:
| Linter | Count | Effort |
|---|---|---|
wrapcheck | 114 | Medium — needs fmt.Errorf("...: %w", err) wrapping |
perfsprint | 50 | Easy — mechanical fmt.Errorf → errors.New, fmt.Sprintf → concat |
errcheck | 45 | Easy/Medium — add _ = or handle errors |
intrange | 25 | Easy — for i := 0; i < n; i++ → for i := range n |
forbidigo | 14 | Needs review — likely os.Getwd or similar banned calls |
revive | 13 | Easy — style fixes |
inamedparam | 11 | Easy — name interface params |
embeddedstructfieldcheck | 9 | Easy — add blank lines in structs |
| Others | ~40 | Mixed |
Fixing all 330 in one go is doable but it's a big diff. A few options:
- Fix them all now — one big cleanup PR, then the gates enforce a clean baseline
- Use golangci-lint's
--new-from-rev=HEAD— only lint new/changed code in PRs, then fix existing violations incrementally - Fix the easy mechanical ones now, disable the noisy ones (
wrapcheck,errcheck) temporarily, enable them as you clean up
What do you prefer?
Everything is green:
- Tests: All pass with
-race - golangci-lint: 0 issues (was 340)
- gofmt: Clean
- shellcheck: Clean
- go mod tidy: Clean (just needs to be committed)
Here's a summary of what was created and changed:
New files:
.github/workflows/ci.yml— tests with race detection on PR + push to main.github/workflows/lint.yml— lint with inline PR annotations on PR + push to main.github/workflows/license-check.yml— reusable license check fromentireio/shared.golangci.yaml— full linter config matching CLI (60+ linters, adapted for git-sync)mise-tasks/lint/{_default,go,gofmt,gomod,shellcheck}— lint subtasks matching CLI structure
Updated files:
mise.toml— addedtest:citask with-racego.mod/go.sum— addedtestifydependency (used forrequire.NoErrorin tests)- ~40 Go source files — fixed all 340 lint violations (wrapcheck, perfsprint, errcheck, intrange, exhaustive, embeddedstructfieldcheck, inamedparam, revive, goconst, etc.)
Want me to commit this and create the PR?
- High: internal/strategy/bootstrap/bootstrap.go:458 likely regresses peak-memory behavior by removing graphStore = nil before the explicit runtime.GC(). The surrounding comment says this store can reach roughly 4.6 GB for large repos and should be discarded immediately after extracting the first-parent chain. Without clearing the last local reference, the compiler/runtime may keep graphStore live until function exit, defeating the intended early reclamation.
- Medium: pkg/gitsync/types.go:68 changes the JSON wire format of exported stable API types. Adding tags to RefMapping, RefScope, and SyncPolicy changes serialized names from Source/Branches/IncludeTags/Protocol to source/branches/includeTags/protocol. That is a real compatibility change for any external caller persisting or exchanging these structs as JSON, and it also creates a mixed-casing payload because the outer request structs still use default field names.
- Low: pkg/gitsync/client.go:39 and pkg/gitsync/internalbridge/config.go:87 now double- wrap probe errors, producing messages like probe: probe: .... That does not break behavior, but it degrades error quality and makes the layering look accidental. The bridge is the better place to remove wrapping, since it is mostly pass-through.
- Low: pkg/gitsync/unstable/client.go:37 also changes JSON field names for exported unstable.AdvancedOptions (CollectStats -> collectStats, etc.). This is less serious because the package is explicitly unstable, but it is still a public serialization change, not just a lint cleanup.
Everything is clean. All four issues are fixed:
- Restored
graphStore = nilwith//nolint:ineffassign,wastedassign— preserves the ~4.6 GB early reclamation beforeruntime.GC() - Reverted JSON tags on stable API types (
RefMapping,RefScope,SyncPolicy) — no wire-format change - Removed double-wrapping in
internalbridge— the bridge is now pass-through,pkg/gitsync/client.goadds the only context layer - Reverted JSON tags on
unstable.AdvancedOptions— no serialization change;musttagsuppressed on the bench tool's debug output instead
Ready for commit and PR whenever you want.
Committed as d456614 on soph/add-ci-and-lint. 60 files changed, 891 insertions, 434 deletions. Working tree is clean.