diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aaaeb30f..dd1fc756 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -71,7 +71,7 @@ jobs: run: go build -v ./cmd/bd - name: Test - run: go test -v -short ./... + run: go test -v -short -timeout=20m ./... lint: name: Lint diff --git a/.golangci.yml b/.golangci.yml index 670dc5d5..31da97cf 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -28,6 +28,7 @@ linters: - (os).Unsetenv - (os).Chdir - (os).MkdirAll + - (fmt).Sscanf misspell: locale: US @@ -44,7 +45,7 @@ linters: - gosec text: "G306" # G304: Safe file reads from known JSONL and error paths - - path: 'cmd/bd/autoflush\.go|internal/daemon/discovery\.go|internal/daemonrunner/sync\.go' + - path: 'cmd/bd/autoflush\.go|internal/beads/beads\.go|internal/daemon/discovery\.go|internal/daemonrunner/sync\.go|internal/syncbranch/worktree\.go' linters: - gosec text: "G304" @@ -63,7 +64,7 @@ linters: - gosec text: "G306.*0700" # G204: Safe subprocess launches with validated arguments - - path: 'cmd/bd/daemon_autostart\.go|cmd/bd/daemon_sync_branch\.go|cmd/bd/show\.go|cmd/bd/sync\.go|internal/git/worktree\.go' + - path: 'cmd/bd/daemon_autostart\.go|cmd/bd/daemon_sync_branch\.go|cmd/bd/doctor\.go|cmd/bd/doctor/fix/sync_branch\.go|cmd/bd/jira\.go|cmd/bd/migrate_sync\.go|cmd/bd/show\.go|cmd/bd/sync\.go|internal/git/worktree\.go|internal/syncbranch/worktree\.go' linters: - gosec text: 'G204' @@ -88,5 +89,11 @@ linters: - errcheck text: "Error return value of .*(Close|Rollback|RemoveAll|Setenv|Unsetenv|Chdir|MkdirAll|Remove|Write|SetReadDeadline|SetDeadline|Start|Stop).* is not checked" + # unparam: Placeholder functions that may return errors in future implementation + - path: 'cmd/bd/jira\.go' + linters: + - unparam + text: 'reimportConflicts|resolveConflictsByTimestamp' + issues: uniq-by-line: true diff --git a/cmd/bd/doctor.go b/cmd/bd/doctor.go index 9a35a430..377d8054 100644 --- a/cmd/bd/doctor.go +++ b/cmd/bd/doctor.go @@ -2515,7 +2515,7 @@ func checkSyncBranchHealth(path string) doctorCheck { fileCount := len(strings.Split(diffFiles, "\n")) // Parse ahead count as int for comparison aheadCountInt := 0 - fmt.Sscanf(aheadCount, "%d", &aheadCountInt) + _, _ = fmt.Sscanf(aheadCount, "%d", &aheadCountInt) // Only warn if significantly behind (20+ commits AND 50+ source files) // Small drift is normal between bd sync operations diff --git a/cmd/bd/jira.go b/cmd/bd/jira.go index dbe4a2a5..f064b755 100644 --- a/cmd/bd/jira.go +++ b/cmd/bd/jira.go @@ -642,7 +642,7 @@ func detectJiraConflicts(ctx context.Context) ([]JiraConflict, error) { // reimportConflicts re-imports conflicting issues from Jira (Jira wins). // NOTE: This is a placeholder - full implementation requires fetching individual // issues from Jira API and updating local copies. -func reimportConflicts(ctx context.Context, conflicts []JiraConflict) error { +func reimportConflicts(_ context.Context, conflicts []JiraConflict) error { if len(conflicts) == 0 { return nil } @@ -657,7 +657,7 @@ func reimportConflicts(ctx context.Context, conflicts []JiraConflict) error { // resolveConflictsByTimestamp resolves conflicts by keeping the newer version. // NOTE: This is a placeholder - full implementation requires fetching Jira // timestamps and comparing with local timestamps. -func resolveConflictsByTimestamp(ctx context.Context, conflicts []JiraConflict) error { +func resolveConflictsByTimestamp(_ context.Context, conflicts []JiraConflict) error { if len(conflicts) == 0 { return nil } diff --git a/cmd/bd/sync.go b/cmd/bd/sync.go index 411e649f..ae7333a4 100644 --- a/cmd/bd/sync.go +++ b/cmd/bd/sync.go @@ -419,7 +419,7 @@ Use --merge to merge the sync branch back to main branch.`, fmt.Printf("✓ Pushed merged changes to %s\n", syncBranchName) pushedViaSyncBranch = true } else { - fmt.Println("Push cancelled. Run 'bd sync' again to retry.") + fmt.Println("Push canceled. Run 'bd sync' again to retry.") fmt.Println("If this was unintended, use 'git reflog' on the sync branch to recover.") } } else if pullResult.Pushed { diff --git a/internal/syncbranch/worktree.go b/internal/syncbranch/worktree.go index 3488c662..3cdbd86b 100644 --- a/internal/syncbranch/worktree.go +++ b/internal/syncbranch/worktree.go @@ -473,7 +473,7 @@ func performContentMerge(ctx context.Context, worktreePath, branch, remote, json if err != nil { return nil, fmt.Errorf("failed to create temp dir: %w", err) } - defer os.RemoveAll(tmpDir) + defer func() { _ = os.RemoveAll(tmpDir) }() baseFile := filepath.Join(tmpDir, "base.jsonl") localFile := filepath.Join(tmpDir, "local.jsonl")