feat(git): implement Git repository operations #136

Merged
fuzzy merged 1 commit from feat/git-operations into main 2026-08-02 17:33:51 +00:00
Owner

What

Implement the GitService interface from task #32 on Service in internal/git using go-git v5.19.2:

  • Clone (#42) — shallow clone (Depth: 1, single branch) including all tags, into a temp directory. Shallow clones prevent disk-space abuse on the server.
  • Fetch (#43) — fetches all refs (+refs/*:refs/*) so new tags/branches appear on webhook push.
  • Checkout (#44) — resolves a tag or branch to its commit (ResolveRevision, which correctly peels annotated tags) and checks out detached.
  • VerifyAssets (#45) — confirms index.html exists in the worktree.
  • Token-based BasicAuth auth when a token is configured.
  • var _ GitService = (*Service)(nil) compile-time assertion.

Dependency: added github.com/go-git/go-git/v5 v5.19.2 and vendored its dependency tree per THWAP policy (vendor grows 79MB → 83MB).

Tests: exercise the real go-git SDK against local repositories in t.TempDir() — clone + asset verification, tag checkout (annotated tag peeled to commit), fetch picking up a newly created tag, missing assets, and unknown refs.

Why

Phase 3 task #46 — completes the Forgejo Integration phase. This is the build step used by the webhook receiver (#72) and rollback (#90).

Testing

  • go mod tidy
  • go mod vendor
  • go build ./...
  • go vet ./...
  • go test -race ./internal/git/ — 5 tests pass
  • gofmt -l ./cmd ./internal ./pkg clean
  • golangci-lint run — 0 issues
  • pre-commit hooks all pass

Breaking Changes

None.

Notes

  • Rollback strategy (per THWAP decision): remove the old clone and re-clone shallow (depth 1), so older tags not present in the shallow clone are handled by a fresh clone.
  • Issues #42–#46 were closed via the Forgejo API as part of this task per the workflow.
  • Phase 3 (Forgejo Integration) is now complete.

Closes #42
Closes #43
Closes #44
Closes #45
Closes #46

## What Implement the `GitService` interface from task #32 on `Service` in `internal/git` using go-git v5.19.2: - **Clone (#42)** — shallow clone (`Depth: 1`, single branch) including all tags, into a temp directory. Shallow clones prevent disk-space abuse on the server. - **Fetch (#43)** — fetches all refs (`+refs/*:refs/*`) so new tags/branches appear on webhook push. - **Checkout (#44)** — resolves a tag or branch to its commit (`ResolveRevision`, which correctly peels annotated tags) and checks out detached. - **VerifyAssets (#45)** — confirms `index.html` exists in the worktree. - Token-based `BasicAuth` auth when a token is configured. - `var _ GitService = (*Service)(nil)` compile-time assertion. **Dependency**: added `github.com/go-git/go-git/v5 v5.19.2` and vendored its dependency tree per THWAP policy (vendor grows 79MB → 83MB). **Tests**: exercise the real go-git SDK against local repositories in `t.TempDir()` — clone + asset verification, tag checkout (annotated tag peeled to commit), fetch picking up a newly created tag, missing assets, and unknown refs. ## Why Phase 3 task #46 — completes the Forgejo Integration phase. This is the build step used by the webhook receiver (#72) and rollback (#90). ## Testing - [x] `go mod tidy` - [x] `go mod vendor` - [x] `go build ./...` - [x] `go vet ./...` - [x] `go test -race ./internal/git/` — 5 tests pass - [x] `gofmt -l ./cmd ./internal ./pkg` clean - [x] `golangci-lint run` — 0 issues - [x] pre-commit hooks all pass ## Breaking Changes None. ## Notes - Rollback strategy (per THWAP decision): remove the old clone and re-clone shallow (`depth 1`), so older tags not present in the shallow clone are handled by a fresh clone. - Issues #42–#46 were closed via the Forgejo API as part of this task per the workflow. - Phase 3 (Forgejo Integration) is now complete. Closes #42 Closes #43 Closes #44 Closes #45 Closes #46
feat(git): implement Git repository operations
All checks were successful
Test and Release / lint (pull_request) Successful in 4m12s
Test and Release / test (pull_request) Successful in 20m5s
10ec49ef40
Implement the GitService interface on Service using go-git:

- Clone performs a shallow (depth 1) single-branch clone including tags
- Fetch updates all refs so new tags and branches appear on webhook
- Checkout resolves tags or branches to their commit and checks out
  detached
- VerifyAssets confirms index.html is present in the worktree
- Token-based authentication via BasicAuth when a token is configured

Vendor go-git and its dependency tree per THWAP policy. Add tests that
exercise clone, tag checkout, fetch of new tags, asset verification,
and error paths against local repositories. Mark task done in ROADMAP.md.

closes #42
closes #43
closes #44
closes #45
closes #46
fuzzy scheduled this pull request to auto merge when all checks succeed 2026-08-02 17:14:36 +00:00
the.auditor left a comment

Review Summary

Verified locally on the PR head (10ec49e): go build, go vet, go mod verify, gofmt (incl. ./pkg), golangci-lint run all clean; all 5 git tests pass with -race. Re-ran the full release cross-compile matrix (linux/freebsd/openbsd × amd64/arm64, CGO_ENABLED=0) with the new go-git dependency — all six targets build.

Implementation is solid. Clone (shallow, single-branch, all tags), Fetch (all refs, correctly short-circuits NoErrAlreadyUpToDate), Checkout (ResolveRevision + detached checkout, which peels annotated tags — verified by TestCheckoutTag), and VerifyAssets are all correct. Token BasicAuth matches Forgejo's HTTPS auth scheme. The tests exercise the real go-git SDK against local repos, including the fetch-picks-up-new-tag flow.

No blocking issues.

Non-blocking observations:

  1. Checkout claims tag-or-branch support in the interface doc, but only tag checkout is tested — a branch-checkout test (e.g. after Fetch) would close the gap.
  2. Service.CloneURL is only used for the Fetch error message (Clone takes cloneURL as an argument) — effectively dead state otherwise. Consider dropping it or using it to make Fetch's error message reliable.
  3. VerifyAssets checks only index.html — fine for now, but subdirectory-rooted sites may need a configurable asset path later.

Approving.

## Review Summary Verified locally on the PR head (`10ec49e`): `go build`, `go vet`, `go mod verify`, `gofmt` (incl. `./pkg`), `golangci-lint run` all clean; all 5 git tests pass with `-race`. Re-ran the full release cross-compile matrix (linux/freebsd/openbsd × amd64/arm64, `CGO_ENABLED=0`) with the new go-git dependency — all six targets build. Implementation is solid. `Clone` (shallow, single-branch, all tags), `Fetch` (all refs, correctly short-circuits `NoErrAlreadyUpToDate`), `Checkout` (`ResolveRevision` + detached checkout, which peels annotated tags — verified by `TestCheckoutTag`), and `VerifyAssets` are all correct. Token `BasicAuth` matches Forgejo's HTTPS auth scheme. The tests exercise the real go-git SDK against local repos, including the fetch-picks-up-new-tag flow. **No blocking issues.** Non-blocking observations: 1. `Checkout` claims tag-or-branch support in the interface doc, but only tag checkout is tested — a branch-checkout test (e.g. after `Fetch`) would close the gap. 2. `Service.CloneURL` is only used for the `Fetch` error message (Clone takes `cloneURL` as an argument) — effectively dead state otherwise. Consider dropping it or using it to make Fetch's error message reliable. 3. `VerifyAssets` checks only `index.html` — fine for now, but subdirectory-rooted sites may need a configurable asset path later. Approving.
fuzzy merged commit 10ec49ef40 into main 2026-08-02 17:33:51 +00:00
fuzzy deleted branch feat/git-operations 2026-08-02 17:33:52 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
thwap/thwap-pagesd!136
No description provided.