fix: resolve CI lint errors and Windows test timeout

- Fix gosec G204/G304 warnings by adding exclusions for safe subprocess
  launches and file reads in doctor.go, jira.go, migrate_sync.go, and
  syncbranch/worktree.go
- Fix misspell: "cancelled" -> "canceled" in sync.go
- Fix unparam: mark unused ctx params in jira.go placeholder functions
- Fix errcheck: explicitly ignore fmt.Sscanf return in doctor.go and
  use closure pattern for deferred os.RemoveAll in worktree.go
- Increase Windows test timeout from 10m to 20m to prevent CI timeouts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-03 17:50:23 -08:00
parent a71155028d
commit 76f7341cf4
6 changed files with 15 additions and 8 deletions

View File

@@ -71,7 +71,7 @@ jobs:
run: go build -v ./cmd/bd run: go build -v ./cmd/bd
- name: Test - name: Test
run: go test -v -short ./... run: go test -v -short -timeout=20m ./...
lint: lint:
name: Lint name: Lint

View File

@@ -28,6 +28,7 @@ linters:
- (os).Unsetenv - (os).Unsetenv
- (os).Chdir - (os).Chdir
- (os).MkdirAll - (os).MkdirAll
- (fmt).Sscanf
misspell: misspell:
locale: US locale: US
@@ -44,7 +45,7 @@ linters:
- gosec - gosec
text: "G306" text: "G306"
# G304: Safe file reads from known JSONL and error paths # 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: linters:
- gosec - gosec
text: "G304" text: "G304"
@@ -63,7 +64,7 @@ linters:
- gosec - gosec
text: "G306.*0700" text: "G306.*0700"
# G204: Safe subprocess launches with validated arguments # 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: linters:
- gosec - gosec
text: 'G204' text: 'G204'
@@ -88,5 +89,11 @@ linters:
- errcheck - errcheck
text: "Error return value of .*(Close|Rollback|RemoveAll|Setenv|Unsetenv|Chdir|MkdirAll|Remove|Write|SetReadDeadline|SetDeadline|Start|Stop).* is not checked" 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: issues:
uniq-by-line: true uniq-by-line: true

View File

@@ -2515,7 +2515,7 @@ func checkSyncBranchHealth(path string) doctorCheck {
fileCount := len(strings.Split(diffFiles, "\n")) fileCount := len(strings.Split(diffFiles, "\n"))
// Parse ahead count as int for comparison // Parse ahead count as int for comparison
aheadCountInt := 0 aheadCountInt := 0
fmt.Sscanf(aheadCount, "%d", &aheadCountInt) _, _ = fmt.Sscanf(aheadCount, "%d", &aheadCountInt)
// Only warn if significantly behind (20+ commits AND 50+ source files) // Only warn if significantly behind (20+ commits AND 50+ source files)
// Small drift is normal between bd sync operations // Small drift is normal between bd sync operations

View File

@@ -642,7 +642,7 @@ func detectJiraConflicts(ctx context.Context) ([]JiraConflict, error) {
// reimportConflicts re-imports conflicting issues from Jira (Jira wins). // reimportConflicts re-imports conflicting issues from Jira (Jira wins).
// NOTE: This is a placeholder - full implementation requires fetching individual // NOTE: This is a placeholder - full implementation requires fetching individual
// issues from Jira API and updating local copies. // 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 { if len(conflicts) == 0 {
return nil return nil
} }
@@ -657,7 +657,7 @@ func reimportConflicts(ctx context.Context, conflicts []JiraConflict) error {
// resolveConflictsByTimestamp resolves conflicts by keeping the newer version. // resolveConflictsByTimestamp resolves conflicts by keeping the newer version.
// NOTE: This is a placeholder - full implementation requires fetching Jira // NOTE: This is a placeholder - full implementation requires fetching Jira
// timestamps and comparing with local timestamps. // 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 { if len(conflicts) == 0 {
return nil return nil
} }

View File

@@ -419,7 +419,7 @@ Use --merge to merge the sync branch back to main branch.`,
fmt.Printf("✓ Pushed merged changes to %s\n", syncBranchName) fmt.Printf("✓ Pushed merged changes to %s\n", syncBranchName)
pushedViaSyncBranch = true pushedViaSyncBranch = true
} else { } 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.") fmt.Println("If this was unintended, use 'git reflog' on the sync branch to recover.")
} }
} else if pullResult.Pushed { } else if pullResult.Pushed {

View File

@@ -473,7 +473,7 @@ func performContentMerge(ctx context.Context, worktreePath, branch, remote, json
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create temp dir: %w", err) 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") baseFile := filepath.Join(tmpDir, "base.jsonl")
localFile := filepath.Join(tmpDir, "local.jsonl") localFile := filepath.Join(tmpDir, "local.jsonl")