The devcontainer has two databases: seed (postgres) and prod-like (prodlike), controlled by SIPPY_DATA_MODE (default: seed).
To migrate both databases:
go run ./cmd/sippy migrate --database-dsn "$SIPPY_SEED_DATABASE_DSN"
go run ./cmd/sippy migrate --database-dsn "$SIPPY_PRODLIKE_DATABASE_DSN"
If no env vars are set, the dev default is: postgresql://postgres:password@localhost:5432/postgres
Restore prod-like from a backup: scripts/restore_prodlike_db.sh or MCP restore_prodlike_db. Instructions and slash-command text are defined in .apm/prompts/sippy-dev-restore-prodlike.prompt.md; run make apm after changing that file so apm install redeploys generated command files. Stop sippy serve first.
Run lint: make lint
Run unit tests: make test
This runs Go tests via gotestsum and sippy-ng Vitest tests.
- When your change alters setup steps, usage instructions, or architecture,
update the relevant README (root
README.md,sippy-ng/README.md,mcp/README.md, etc.) in the same PR. - When API endpoints are added, removed, or modified, update
pkg/api/README.md(or create it if it doesn't exist). - When configuration options, environment variables, or CLI flags change,
update
config/README.mdor the relevant section of the rootREADME.md. - When new conventions, workflows, or tooling are introduced, consider
adding or updating an
.apm/instructions/file so that AI coding assistants stay aligned with the project's practices. - When your change affects a feature documented in
docs/features/, update the relevant feature doc in the same PR. Feature docs describe purpose, data flow, and key code locations; keep them accurate as the implementation evolves. If you add a new major feature, create a new doc indocs/features/. - Documentation and code belong in the same PR; never treat a docs update as a follow-up task.
- Do not use em dashes when writing docs. Use commas, parentheses, or periods instead.
Sources under .apm/ (instructions, prompts, apm.yml, etc.) drive generated agent context. After editing those files, run make apm to regenerate AGENTS.md, CLAUDE.md, GEMINI.md, and the integrated copies under .claude/, .cursor/, .gemini/, and .opencode/. CI enforces freshness with make verify-apm.
Slash / agent commands: content under .apm/prompts/*.prompt.md is the single source of truth. apm install (part of make apm) copies each prompt into editor command targets (e.g. .claude/commands/, .opencode/commands/, .gemini/commands/). Do not add those generated paths by hand or installs will skip them as unmanaged duplicates.
Sippy (CIPI - Continuous Integration Private Investigator) is a tool used within the OpenShift engineering organization to analyze CI job results. Its primary goals are to:
- Provide insights into job and test statistics.
- Monitor release health and detect regressions.
- Support release management decisions through statistical analysis (e.g., Component Readiness).
The system consists of:
- A Go-based API backend.
- A React/Material-UI frontend (located in
sippy-ng). - Data sources including PostgreSQL, and BigQuery
Favor clarity and maintainability over cleverness. Comments should be minimal, helpful, and explain the "why" not the "what".
- When adding or updating APIs, use HATEOAS in responses to support discoverability and consistent client interaction.
- Follow idiomatic Go practices.
- Use
k8s.io/apimachinery/pkg/util/sets(e.g.sets.New[string]()) to deduplicate or collect unique strings. Do not usemap[string]boolas a hand-rolled set. - Prefer structured logging where it makes sense; particularly for names and IDs, and often for counts, a log.WithField() call is preferred over formatting values into a string.
- After making changes, always run
gofmt -won modified files to ensure proper formatting. - When modifying any data provider (BigQuery or PostgreSQL), ensure parity between both implementations. Changes to query logic, filtering, or returned data in one provider must be reflected in the other.
- Use
go vetandgo test ./pkg/...to validate changes before resorting to a full e2e run. - Run
make e2e 2>&1 | tee e2e-test.logto verify your changes don't break end-to-end tests. You MUST read the log file (e2e-test.log) for results. Do not re-run e2e just to grep for different things. All output is already in the log file. - Do not mock storage clients (BigQuery, GCS, Postgres, etc.) when constructing golang unit tests.
Go does not make it easy to substitute mocks for concrete SDK clients, and mock-heavy tests tend
to verify the mock implementation rather than real behavior. Instead, structure code to separate
pure logic from client calls. Unit test the logic functions directly (validation, data
transformation, result aggregation and analysis). Enable testing against real storage systems with
functional tests that skip unless the user supplies connection credentials via environment
variables (see
releasesync_functional_test.gofor the pattern). - When a struct method needs a single, narrow query or RPC that would otherwise force a
database connection in tests, extract that call behind a function type field on the struct
(e.g.
type counterFunc func(id uint) (int, error)). This is a thin adapter seam, not a general-purpose mock — the function type replaces one specific call, not an entire storage client. The production constructor wires the real implementation; tests supply a closure. Seeregressiontracker.go(failureCounterFunc) for the pattern. This does not override the rule above: do not mock or stub BigQuery, GCS, Postgres clients, or any broad storage interface. - Prefer table-driven tests with descriptive case names. Search the same package for existing test patterns before writing new ones.
This file was generated by APM CLI. Do not edit manually.
To regenerate: apm compile