summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-07-22fix(errcheck): handle all unchecked error returns without changing behaviormainPaul Buetow
errcheck ./... flagged unchecked HTTP response Close(), file Close(), os.RemoveAll(), fmt.Scanln(), and fmt.Fprintf() calls across codeberg, github, release, showcase, and sync. None of these were bugs causing incorrect behavior today, but leaving them unchecked hid real failure modes (e.g. a lagging NFS mount failing a file Close() after writes, which this codebase has hit before per commit 23ecaa2). - internal/codeberg/codeberg.go, internal/github/github.go, internal/release/release.go: added a small closeResponseBody(resp) helper per package and used it for all deferred resp.Body.Close() calls. The body is always fully read (or abandoned on an earlier error) by the time Close() runs, so the error is intentionally discarded - matching the explicit `_ = ...` discard convention already used elsewhere in this repo (e.g. showcase.go's os.RemoveAll on the worktree-add failure path). - internal/release/release.go: the two fmt.Scanln(&response) prompts now explicitly discard the return values; a Scanln error already leaves response == "", which the existing y/yes check already treats as a safe decline, so behavior is unchanged. - internal/showcase/code_extractor.go, images.go, language_detector.go: added a shared closeFile(*os.File) helper (package showcase) for the read-only file Close() calls, matching the same discard rationale. copyFile's destination Close() is the one write-side case where a close failure is real data-loss information, so it now uses a named return to surface it via err without masking any earlier error. - internal/showcase/showcase.go: the deferred os.RemoveAll(tempRoot) now explicitly discards its error, matching the sibling `_ =` call three lines above in the same function. - internal/sync/branch_analyzer.go: GenerateDeleteScript's per-repository fmt.Fprintf(file, ...) calls are now checked and wrapped with fmt.Errorf(...: %w), matching the error-wrapping convention already used by writeBranchDeletionBlock right below it in the same file (the repeated repo-header writes were pulled into a new writeDeleteScriptRepoHeader helper to keep this readable). The script file's defer file.Close() now uses a named return so a close failure is reported instead of silently discarded. Added focused tests for the two behavior-relevant paths: copyFile's missing-source/success paths after the named-return change, and PromptConfirmation's empty-input-declines/explicit-yes behavior after touching the Scanln call. Trivial defer-Close discards elsewhere are not additionally unit tested per the task's guidance against overengineering. Verified: go build ./..., go vet ./..., errcheck ./... (clean), and go test ./... all pass. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22fix(sync): make SSH backup repo creation survive non-root pushes and NFS lagPaul Buetow
Auditing a full bidirectional sync to the r0 git-server backup destination showed a stale/missing-repo pattern that cgit idle times alone did not explain: several public repos (rampage, ggaze, comicforge, fastforge, gonf, quicklog, shuriken.sh) were entirely absent from r0 even though they synced fine to GitHub/Codeberg. Root cause #1: createSSHBareRepository provisions missing backup repos by running `git init --bare` over a root SSH session directly on the r0 filesystem. That leaves the new repo directory at mode 0755 (root's session umask), owner-write only. Pushes into it later go through the git-server pod's own SSH endpoint as a different, non-root UID (1001, GID 33/www-data per the git-server helm chart's docker-image/Dockerfile), which then cannot write new objects into the 0755 tree ("unable to create temporary object directory"). Fixed by initializing with `git init --bare --shared=group` (mode 2775, matching the already-working repos on r0). Root cause #2: even with correct permissions, the push immediately following repository creation can still fail transiently (the git-server's own view of the newly created directory can lag behind, e.g. across an NFS mount). handlePushError treats any backup push failure as fatal for the remainder of that sync run and disables the backup destination entirely (disableBackupForSession) - so one transient failure early in a shuffled repo order silently skipped backup for every repo processed afterward in that pass, explaining the fuller set of stale repos. Fixed by retrying the post-creation push up to 3 times with a short backoff in the new createAndPushSSHBackupRepo helper, and by capturing/propagating the actual git stderr on failure (previously swallowed via cmd.Run()) so any future failure is diagnosable instead of a bare "exit status 128". Verified against the live r0 git-server (ssh://git@r0:30022/repos, /data/nfs/k3svolumes/git-server/repos): reinstalled gitsyncer and reran `sync bidirectional --force --backup --auto-create-releases` end to end with zero backup-disable events across both passes; all previously missing/broken repos (plus the pre-existing broken player.git and irregular.ninja.git, repaired directly via chmod) now match GitHub/Codeberg HEAD exactly and are browsable on c-git.f3s.buetow.org. Adds a regression test for the --shared=group init command. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22feat(sync): make backup fail-fast per-destination and add ↵Paul Buetow
forcePush/descriptionSync creation support Backup failures now disable retries only for the failing remote instead of the whole session, add an opt-in forcePush flag for backup organizations, and allow repository creation to go through descriptionSyncHost/Root when configured so the git remote endpoint can stay restricted. Also fixes the AI release-notes cache being bypassed by --force, which is meant to control sync scheduling, not cache invalidation. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-06-17feat(ai): switch default showcase model to glm-5.2:cloud and bump version to ↵v0.18.5Paul Buetow
0.18.5
2026-06-12chore(ci): remove GitHub Actions workflowPaul Buetow
2026-06-07feat(showcase): add human-readable cgit access hint with obfuscated URLv0.18.4Paul Buetow
2026-06-07chore(version): bump version to 0.18.3v0.18.3Paul Buetow
2026-05-29chore(release): bump version to 0.18.2Paul Buetow
2026-05-29fix(ci): harden lint baseline fallback (yq)Paul Buetow
2026-05-29ci(yq): pin golangci-lint and gate lint on new issuesPaul Buetow
2026-05-29fix(yq): gate vet/lint in CI and drop redundant SprintfPaul Buetow
2026-05-29fix(vq): restore version-prefix parsing and stash no-op handlingPaul Buetow
2026-05-29fix(vq): handle ignored stash/pop and parse errors explicitlyPaul Buetow
2026-05-29feat(showcase): uq move cgit host and output dir into configPaul Buetow
2026-05-29fix(showcase): remove unsupported flags from CLI (tq)Paul Buetow
2026-05-29chore(showcase): remove dead countLinesOfCode helper (sq)Paul Buetow
2026-05-29refactor(sync): move backup session state to Syncer instance (qq)Paul Buetow
2026-05-29test(httpclient): strengthen transport assertions (pq)Paul Buetow
2026-05-29fix(httpclient): tune transport defaults for pqPaul Buetow
2026-05-29fix(cli): stabilize public factory tests and nil guards (mq)Paul Buetow
2026-05-29test(cli): cover mq factory init/public handler branchesPaul Buetow
2026-05-29refactor(cli): inject repo client factory for mqPaul Buetow
2026-05-29refactor(showcase): extract summary and asset helpers (kq)Paul Buetow
2026-05-29refactor(showcase): split gemtext sanitize/format helpers (jq)Paul Buetow
2026-05-29refactor(cli): use org host helpers in forge client dispatch (lq)Paul Buetow
2026-05-29refactor(localrepos): extract shared ListLocalRepos helper (nq)Paul Buetow
2026-05-29refactor(showcase): decompose formatGemtext and guard zero totals (oq)Paul Buetow
2026-05-29docs(configuration): align troubleshooting errors with cobra output (rq)Paul Buetow
2026-05-29docs(readme): replace --batch-run with manage batch-run (rq)Paul Buetow
2026-05-29docs(cli): replace legacy flag examples with cobra subcommands (rq)Paul Buetow
2026-05-29refactor(cli): remove dead legacy flag layer (rq)Paul Buetow
2026-05-29fix(config): return stored org pointer in FindOrganization (wq)Paul Buetow
2026-05-29refactor(showcase): clarify stripComments precedence (xq)Paul Buetow
2026-05-28test(showcase): add renderAxes/renderLines boundary tests (fq)Paul Buetow
2026-05-28refactor(showcase): split rank history svg generator (fq)Paul Buetow
2026-05-28fix(release): honor manager aiTool dispatch (cq)Paul Buetow
2026-05-28refactor(aitool): extract shared AI tool dispatch chain (cq)Paul Buetow
2026-05-28test(cli): add codeberg constructor callsite regression (iq)Paul Buetow
2026-05-28fix(clients): normalize constructor signatures and pointer returns (iq)Paul Buetow
2026-05-28fix(random): remove deprecated rand seeding (hq)Paul Buetow
2026-05-28test(showcase): add non-version tag regression test (gq)Paul Buetow
2026-05-28refactor(version): unify version tag detection across packages (gq)Paul Buetow
2026-05-28refactor(sync): template delete script generation (eq)Paul Buetow
2026-05-28fix(cli): restore exact forge host matching parity (dq)Paul Buetow
2026-05-28refactor(forge): unify repo lifecycle across GitHub and Codeberg (dq)Paul Buetow
2026-05-28test(cli): add release helper orchestration coverage (bq)Paul Buetow
2026-05-28refactor(cli): deduplicate release target handling (bq)Paul Buetow
2026-05-28fix(sync): correct local tag peel syntax in getTagCommitHash (kp)Paul Buetow
2026-05-27chore: bump version to 0.18.1Paul Buetow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27showcase: align inactivity condition and wording between SVG and gemtextPaul Buetow
Both the rank-history SVG and the gemtext showcase now use the same rule: inactive = AvgCommitAge (last 42 commits on HEAD) > 730 days (~2 years) Changes: - SVG subtitle: 'no meaningful commits in 1+ years' → 'avg commit age > 2 years' - SVG struct comment: updated to describe the 730-day/42-commit rule accurately - gemtext: dropped the secondary 'lastCommit > 365 days' guard (it allowed projects like muttdelay to escape despite a single stray recent commit) - gemtext notice text: 'Last meaningful activity was over 2 years ago' → 'The average age of its last 42 commits exceeds 2 years' Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>