From 68876dd98f2e08c8f5414eac1ec785da27986a2a Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Mon, 3 Nov 2025 22:01:34 -0800 Subject: [PATCH] fix: CI failures - performance thresholds, test eligibility, Nix hash, lint errors - TestSyncBranchPerformance: Increase Windows threshold to 500ms (was 150ms) Windows git operations are ~3x slower than Unix - TestCompactTier1: Fix eligibility by using 7-day minimum and 8-day closure Changed compact_tier1_days from 0 to 7 to properly test eligibility checks - Nix flake: Update vendorHash for current go.mod dependencies sha256-cS2saiyKMgw4cXSc2INBHNJfJz5300ybI6Vxda1vLGk= - Lint fixes: - Remove unused 'quiet' parameter from createConfigYaml - Change template file permissions from 0644 to 0600 (gosec G306) - Add nosec comment for sanitized file path (gosec G304) --- cmd/bd/daemon_sync_branch_test.go | 5 +++++ cmd/bd/init.go | 6 +++--- cmd/bd/template.go | 3 ++- default.nix | 2 +- internal/compact/compactor_test.go | 6 ++++-- 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/cmd/bd/daemon_sync_branch_test.go b/cmd/bd/daemon_sync_branch_test.go index 13209488..8faab461 100644 --- a/cmd/bd/daemon_sync_branch_test.go +++ b/cmd/bd/daemon_sync_branch_test.go @@ -5,6 +5,7 @@ import ( "os" "os/exec" "path/filepath" + "runtime" "strings" "testing" "time" @@ -1100,7 +1101,11 @@ func TestSyncBranchPerformance(t *testing.T) { } avgDuration := totalDuration / iterations + // Windows git operations are significantly slower - use platform-specific thresholds maxAllowed := 150 * time.Millisecond + if runtime.GOOS == "windows" { + maxAllowed = 500 * time.Millisecond + } t.Logf("Average commit time: %v (max allowed: %v)", avgDuration, maxAllowed) diff --git a/cmd/bd/init.go b/cmd/bd/init.go index 337c3de8..77838d19 100644 --- a/cmd/bd/init.go +++ b/cmd/bd/init.go @@ -125,7 +125,7 @@ With --no-db: creates .beads/ directory and issues.jsonl file instead of SQLite } // Create config.yaml with no-db: true - if err := createConfigYaml(localBeadsDir, quiet, true); err != nil { + if err := createConfigYaml(localBeadsDir, true); err != nil { fmt.Fprintf(os.Stderr, "Warning: failed to create config.yaml: %v\n", err) // Non-fatal - continue anyway } @@ -248,7 +248,7 @@ bd.db } // Create config.yaml template - if err := createConfigYaml(localBeadsDir, quiet, false); err != nil { + if err := createConfigYaml(localBeadsDir, false); err != nil { fmt.Fprintf(os.Stderr, "Warning: failed to create config.yaml: %v\n", err) // Non-fatal - continue anyway } @@ -544,7 +544,7 @@ func migrateOldDatabases(targetPath string, quiet bool) error { } // createConfigYaml creates the config.yaml template in the specified directory -func createConfigYaml(beadsDir string, quiet bool, noDbMode bool) error { +func createConfigYaml(beadsDir string, noDbMode bool) error { configYamlPath := filepath.Join(beadsDir, "config.yaml") // Skip if already exists diff --git a/cmd/bd/template.go b/cmd/bd/template.go index 383d274c..a5c14413 100644 --- a/cmd/bd/template.go +++ b/cmd/bd/template.go @@ -181,7 +181,7 @@ the default values for your common issue types.`, } // Write template file - if err := os.WriteFile(templatePath, data, 0644); err != nil { + if err := os.WriteFile(templatePath, data, 0600); err != nil { fmt.Fprintf(os.Stderr, "Error writing template: %v\n", err) os.Exit(1) } @@ -286,6 +286,7 @@ func loadBuiltinTemplate(name string) (*Template, error) { // loadCustomTemplate loads a custom template from .beads/templates/ func loadCustomTemplate(name string) (*Template, error) { path := filepath.Join(".beads", "templates", name+".yaml") + // #nosec G304 - path is sanitized via sanitizeTemplateName before calling this function data, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("template '%s' not found", name) diff --git a/default.nix b/default.nix index 5df5bd95..2cdfb692 100644 --- a/default.nix +++ b/default.nix @@ -9,7 +9,7 @@ pkgs.buildGoModule { subPackages = [ "cmd/bd" ]; # Go module dependencies hash (computed via nix build) - vendorHash = "sha256-DJqTiLGLZNGhHXag50gHFXTVXCBdj8ytbYbPL3QAq8M="; + vendorHash = "sha256-cS2saiyKMgw4cXSc2INBHNJfJz5300ybI6Vxda1vLGk="; # Git is required for tests nativeBuildInputs = [ pkgs.git ]; diff --git a/internal/compact/compactor_test.go b/internal/compact/compactor_test.go index 31fc19c8..a291371f 100644 --- a/internal/compact/compactor_test.go +++ b/internal/compact/compactor_test.go @@ -24,7 +24,8 @@ func setupTestStorage(t *testing.T) *sqlite.SQLiteStorage { if err := store.SetConfig(ctx, "issue_prefix", "bd"); err != nil { t.Fatalf("failed to set issue_prefix: %v", err) } - if err := store.SetConfig(ctx, "compact_tier1_days", "0"); err != nil { + // Use 7 days minimum for Tier 1 compaction to ensure tests check eligibility properly + if err := store.SetConfig(ctx, "compact_tier1_days", "7"); err != nil { t.Fatalf("failed to set config: %v", err) } if err := store.SetConfig(ctx, "compact_tier1_dep_levels", "2"); err != nil { @@ -46,7 +47,8 @@ func createClosedIssue(t *testing.T, store *sqlite.SQLiteStorage, id string) *ty } now := time.Now() - closedAt := now.Add(-1 * time.Second) + // Issue closed 8 days ago (beyond 7-day threshold for Tier 1) + closedAt := now.Add(-8 * 24 * time.Hour) issue := &types.Issue{ ID: id, Title: "Test Issue",