Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ jobs:
- name: Test (race detector)
run: mise run test-race

- name: Vulnerability scan
run: mise run vuln

- name: Build binary
run: mise run build

- name: Test schema migration
run: go test -run TestMigration ./internal/store/ -count=1 -v
9 changes: 3 additions & 6 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,22 +235,19 @@ Removed from the old "already correct" list — disproven by this review:

### H2. `mise run check`: order fmt before lint [XS] ✅ done (batch 1) — `lint` depends on `fmt`.

### H3. govulncheck in CI [S] (was 7.2)
- `mise run vuln` task + CI step after lint. Fatal from day one if baseline is clean.
### H3. govulncheck in CI [S] (was 7.2) ✅ done (batch 2) — `mise run vuln` + fatal CI step (baseline verified by the introducing PR's own CI run).

### H4. `ci-snitch doctor` [S] (was 7.3)
- Validate token, rate limit, cache path writable, SQLite openable, git remote detectable. One line per check.

### H5. Fix install.sh Windows path [S]
- The MINGW/MSYS/CYGWIN branch downloads the zip then `mv`s a binary named `ci-snitch` (archive contains `ci-snitch.exe`) into `/usr/local/bin` with `sudo` — can never succeed (`install.sh:17,41-46,74`). Handle `.exe` + a sensible dir, or explicitly refuse with a pointer to the release zip.

### H6. Smoke test the production path [S]
- `cmd/smoke/main.go:77` exercises REST `FetchRunDetails`, but the CLI uses `FetchRunDetailsGraphQL` (`internal/app/service.go:349`), and it stops before analyzers/formatters. The mandated pre-PR smoke test skips the most bug-prone path. Switch to the GraphQL path and run the full pipeline through a formatter.
### H6. Smoke test the production path [S] ✅ done (batch 2) — smoke hydrates via `FetchRunDetailsGraphQL` and finishes with engine + LLM formatter: fetch → store → analyze → render.

### H7. goreleaser: migrate deprecated `format` keys [XS] ✅ done (batch 1) — `formats: [tar.gz]` / `[zip]`.

### H8. Make the CI migration step real, or drop it [S]
- "Test schema migration" re-runs `TestMigration` already covered by `mise run test` (`.github/workflows/ci.yml:42-43`). Either build the last tagged release, create a DB, and open it with new code — or delete the step.
### H8. Make the CI migration step real, or drop it [S] ✅ done (batch 2) — dropped; it re-ran `TestMigration` already covered by `mise run test`, and the migration unit tests construct genuine old-schema DBs.

### H9. Store-layer cleanups batch [XS total] ✅ done (batch 1)
- Labels stored as JSON (legacy comma rows still read); dead `idx_runs_status` dropped from schema and migrated DBs; cache read failures log a warning instead of silently re-fetching everything. (`runByID` went with D4.)
Expand Down
19 changes: 18 additions & 1 deletion cmd/smoke/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@
package main

import (
"bytes"
"context"
"fmt"
"log"
"os"
"path/filepath"
"time"

"github.com/vertti/ci-snitch/internal/analyze"
"github.com/vertti/ci-snitch/internal/github"
"github.com/vertti/ci-snitch/internal/output"
"github.com/vertti/ci-snitch/internal/store"
)

Expand Down Expand Up @@ -74,7 +77,9 @@ func run() error {
return nil
}

details, warnings := c.FetchRunDetails(ctx, runs[:limit])
// The production hot path is GraphQL batching (REST is the fallback);
// smoke must exercise what the CLI actually runs.
details, warnings := c.FetchRunDetailsGraphQL(ctx, runs[:limit])
fmt.Printf("Hydrated %d runs, %d warnings\n", len(details), len(warnings))

for _, w := range warnings {
Expand Down Expand Up @@ -118,5 +123,17 @@ func run() error {
}
fmt.Printf("\nIncomplete runs in store: %d\n", len(incomplete))

// Run the full production pipeline over the loaded data: analyzers and
// a formatter, so a smoke run covers fetch -> store -> analyze -> render.
engine := analyze.NewEngine(analyze.DefaultAnalyzers()...)
result := engine.Run(ctx, loaded, loaded, nil, map[int64]string{wf.ID: wf.Name})
fmt.Printf("Analyzed %d runs: %d findings, %d diagnostics\n", len(loaded), len(result.Findings), len(result.Diagnostics))

var briefing bytes.Buffer
if err := (output.LLMFormatter{}).Format(&briefing, &result); err != nil {
return fmt.Errorf("format: %w", err)
}
fmt.Printf("LLM briefing renders (%d bytes)\n", briefing.Len())

return nil
}
4 changes: 4 additions & 0 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ run = "go test ./..."
description = "Run all tests with the race detector"
run = "go test -race ./..."

[tasks.vuln]
description = "Scan dependencies for known vulnerabilities"
run = "go run golang.org/x/vuln/cmd/govulncheck@latest ./..."

[tasks.fmt]
description = "Run goimports and gofmt on all Go files"
run = "golangci-lint fmt ./..."
Expand Down