fix(ci): more changes to fix failing CI (#415)
Fixes from maphew including: - Remove test for deleted isPathWithinDir function - Add gosec nolint directives for safe file operations - Add rm -rf .beads before init in CI workflow - Simplify panic handling and file operations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: maphew <maphew@users.noreply.github.com> Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -92,11 +92,11 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
noAutoFlush bool
|
||||
noAutoImport bool
|
||||
sandboxMode bool
|
||||
allowStale bool // Use --allow-stale: skip staleness check (emergency escape hatch)
|
||||
noDb bool // Use --no-db mode: load from JSONL, write back after each command
|
||||
noAutoFlush bool
|
||||
noAutoImport bool
|
||||
sandboxMode bool
|
||||
allowStale bool // Use --allow-stale: skip staleness check (emergency escape hatch)
|
||||
noDb bool // Use --no-db mode: load from JSONL, write back after each command
|
||||
profileEnabled bool
|
||||
profileFile *os.File
|
||||
traceFile *os.File
|
||||
@@ -289,35 +289,34 @@ var rootCmd = &cobra.Command{
|
||||
jsonlPath := filepath.Join(beadsDir, "issues.jsonl")
|
||||
configPath := filepath.Join(beadsDir, "config.yaml")
|
||||
|
||||
// Check if JSONL exists and config.yaml has no-db: true
|
||||
// Check if JSONL exists and config.yaml has no-db: true
|
||||
jsonlExists := false
|
||||
if _, err := os.Stat(jsonlPath); err == nil {
|
||||
jsonlExists = true
|
||||
}
|
||||
|
||||
isNoDbMode := false
|
||||
if configData, err := os.ReadFile(configPath); err == nil {
|
||||
isNoDbMode := false
|
||||
// configPath is safe: constructed from filepath.Join(beadsDir, hardcoded name)
|
||||
if configData, err := os.ReadFile(configPath); err == nil { //nolint:gosec
|
||||
isNoDbMode = strings.Contains(string(configData), "no-db: true")
|
||||
}
|
||||
|
||||
// If JSONL-only mode is configured, auto-enable it
|
||||
// If JSONL-only mode is configured, auto-enable it
|
||||
if jsonlExists && isNoDbMode {
|
||||
noDb = true
|
||||
if err := initializeNoDbMode(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error initializing JSONL-only mode: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
// Set actor for audit trail
|
||||
// Set actor from flag, viper, or env
|
||||
if actor == "" {
|
||||
if bdActor := os.Getenv("BD_ACTOR"); bdActor != "" {
|
||||
actor = bdActor
|
||||
} else if user := os.Getenv("USER"); user != "" {
|
||||
if user := os.Getenv("USER"); user != "" {
|
||||
actor = user
|
||||
} else {
|
||||
actor = "unknown"
|
||||
}
|
||||
}
|
||||
return // Skip SQLite initialization
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,7 +324,7 @@ var rootCmd = &cobra.Command{
|
||||
// - import: auto-initializes database if missing
|
||||
// - setup: creates editor integration files (no DB needed)
|
||||
if cmd.Name() != "import" && cmd.Name() != "setup" {
|
||||
// No database found - provide helpful error message
|
||||
// No database found - error out instead of falling back to ~/.beads
|
||||
fmt.Fprintf(os.Stderr, "Error: no beads database found\n")
|
||||
fmt.Fprintf(os.Stderr, "Hint: run 'bd init' to create a database in the current directory\n")
|
||||
fmt.Fprintf(os.Stderr, " or use 'bd --no-db' to work with JSONL only (no SQLite)\n")
|
||||
@@ -628,14 +627,8 @@ var rootCmd = &cobra.Command{
|
||||
if store != nil {
|
||||
_ = store.Close()
|
||||
}
|
||||
if profileFile != nil {
|
||||
pprof.StopCPUProfile()
|
||||
_ = profileFile.Close()
|
||||
}
|
||||
if traceFile != nil {
|
||||
trace.Stop()
|
||||
_ = traceFile.Close()
|
||||
}
|
||||
if profileFile != nil { pprof.StopCPUProfile(); _ = profileFile.Close() }
|
||||
if traceFile != nil { trace.Stop(); _ = traceFile.Close() }
|
||||
|
||||
// Cancel the signal context to clean up resources
|
||||
if rootCancel != nil {
|
||||
@@ -667,24 +660,6 @@ func isFreshCloneError(err error) bool {
|
||||
strings.Contains(errStr, "required config key missing: issue_prefix")
|
||||
}
|
||||
|
||||
// isPathWithinDir reports whether candidate resides within baseDir (or is the same path).
|
||||
// Paths are cleaned before comparison to defend against directory traversal.
|
||||
func isPathWithinDir(baseDir, candidate string) bool {
|
||||
cleanBase := filepath.Clean(baseDir)
|
||||
cleanCandidate := filepath.Clean(candidate)
|
||||
|
||||
rel, err := filepath.Rel(cleanBase, cleanCandidate)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if rel == ".." || strings.HasPrefix(rel, ".."+string(os.PathSeparator)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// handleFreshCloneError displays a helpful message when a fresh clone is detected
|
||||
// and returns true if the error was handled (so caller should exit).
|
||||
// If not a fresh clone error, returns false and does nothing.
|
||||
@@ -698,20 +673,13 @@ func handleFreshCloneError(err error, beadsDir string) bool {
|
||||
issueCount := 0
|
||||
|
||||
if beadsDir != "" {
|
||||
if absBeadsDir, err := filepath.Abs(beadsDir); err == nil {
|
||||
beadsDir = absBeadsDir
|
||||
}
|
||||
|
||||
// Check for issues.jsonl (canonical) first, then beads.jsonl (legacy)
|
||||
for _, name := range []string{"issues.jsonl", "beads.jsonl"} {
|
||||
candidate := filepath.Join(beadsDir, name)
|
||||
if !isPathWithinDir(beadsDir, candidate) {
|
||||
continue
|
||||
}
|
||||
if info, statErr := os.Stat(candidate); statErr == nil && !info.IsDir() {
|
||||
jsonlPath = candidate
|
||||
// Count lines (approximately = issue count)
|
||||
// #nosec G304 -- candidate limited to known JSONL files inside .beads
|
||||
// #nosec G304 -- candidate is constructed from beadsDir which is .beads/
|
||||
if data, readErr := os.ReadFile(candidate); readErr == nil {
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
if strings.TrimSpace(line) != "" {
|
||||
|
||||
Reference in New Issue
Block a user