Skip to content

Conversation

@sosiouxme
Copy link
Member

@sosiouxme sosiouxme commented Nov 11, 2025

This defines symptom/label data structures and displays labels in the job runs table. There is also an update to the seed data generator to add some labels and randomly apply them to job runs generated so you can see labels in action.

Adds a column to job runs table exposing any labels:
image

Clicking on it displays the full label explanation:
image

...and of course you can filter by it as well:
image

Summary by CodeRabbit

Release Notes

  • New Features
    • Job runs now support labels for better categorization and filtering
    • New labels dialog displays detailed label information including titles and explanations
    • Autocomplete search enhanced to filter by labels
    • Predefined labels and symptoms automatically seeded into the system

✏️ Tip: You can customize this high-level summary in your review settings.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Nov 11, 2025
@openshift-ci-robot
Copy link

openshift-ci-robot commented Nov 11, 2025

@sosiouxme: This pull request references TRT-2376 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

example on the job runs table

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Nov 11, 2025
@openshift-ci-robot
Copy link

Pipeline controller notification
This repository is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. Review these jobs and use /test <job> to manually trigger optional jobs most likely to be impacted by the proposed changes.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Nov 11, 2025

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 11, 2025

Walkthrough

This change introduces a labels and symptoms system for job runs. It adds database models for labels and symptoms, extends seed data to populate these entities and assign them to runs, adds a backend API endpoint to retrieve labels, enhances autocomplete functionality, and extends the frontend UI to display and interact with labels within job run tables.

Changes

Cohort / File(s) Summary
Database Models
pkg/db/models/jobrunscan/label.go, pkg/db/models/jobrunscan/symptom.go, pkg/db/models/prow.go, pkg/apis/api/types.go
Adds Label and Symptom structs with GORM mappings and JSON serialization. Extends ProwJobRun and JobRun with Labels fields (pq.StringArray) for storing label IDs. Includes MatcherType constants and display context definitions.
Database Infrastructure
pkg/db/db.go, pkg/db/views.go
Refactors schema migration to use a list-driven loop including jobrunscan models. Updates materialized view to include labels column in SELECT list.
Seed Data
cmd/sippy/seed_data.go
Adds createLabelsAndSymptoms and applyLabelsToJobRuns helpers. Computes OverallResult for test runs with randomized distribution and persists to ProwJobRun. Assigns 1–3 random labels to ~25% of runs during seed workflow.
Backend API
pkg/api/autocomplete.go, pkg/sippyserver/server.go
Introduces LabelOption struct and special-case labels branch in PrintAutocompleteFromDB with ILIKE search and 50-item limit. Adds /api/labels endpoint with jsonLabelsFromDB handler and 24h cache.
Frontend Autocomplete
sippy-ng/src/datagrid/GridToolbarAutocomplete.js
Refactors fetchOptions to handle both string and object results. Updates onChange, isOptionEqualToValue, and getOptionLabel to work with objects containing name and optional title fields.
Frontend Job Runs UI
sippy-ng/src/jobs/JobRunsTable.js
Adds labels column to table with click-to-open dialog. Introduces labelsDialogOpen, selectedLabels, selectedJobRun, and allLabels state. Fetches label definitions from /api/labels. Renders Dialog with markdown-formatted label explanations.
Logging Enhancements
pkg/filter/filterable.go
Adds error logging for numeric parsing failures in BigQuery path and unknown filter operators.

Sequence Diagram(s)

sequenceDiagram
    participant FE as Frontend (JobRunsTable)
    participant API as Backend API
    participant DB as Database
    
    Note over FE,DB: On Component Mount
    FE->>API: GET /api/labels
    API->>DB: Query all Labels
    DB-->>API: Labels (id, label_title, explanation)
    API-->>FE: { labels: [...] }
    FE->>FE: Store in allLabels state
    
    Note over FE,DB: On Label Button Click
    FE->>FE: Open Dialog with selectedLabels<br/>(from current job run's labels array)
    
    Note over FE: Dialog Render
    FE->>FE: Map selectedLabels to allLabels<br/>Render label_title & explanation<br/>(markdown formatted)
    FE-->>FE: Display in Dialog with Close button
Loading
sequenceDiagram
    participant Seed as Seeding Process
    participant DB as Database
    
    Note over Seed,DB: Seed Workflow
    Seed->>Seed: Create test models & ProwJobRuns
    Seed->>Seed: Compute OverallResult per run<br/>(70% TestFailure, 15% Upgrade,<br/>7% Install, 8% Infrastructure)
    Seed->>DB: Persist ProwJobRuns with OverallResult
    
    Seed->>Seed: createLabelsAndSymptoms()
    Seed->>DB: Upsert predefined Labels<br/>(with display contexts)
    Seed->>DB: Upsert predefined Symptoms<br/>(with LabelIDs associations)
    
    Seed->>Seed: applyLabelsToJobRuns()
    Seed->>DB: Query all JobRuns & Labels
    DB-->>Seed: JobRuns, Labels
    Seed->>Seed: Assign 1–3 random labels<br/>to ~25% of runs
    Seed->>DB: Persist JobRun.Labels updates
    Seed->>Seed: Log seeding results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • Database schema & model changes: Label and Symptom structs with multiple fields, GORM mappings, and linked data structures require verification of table design, constraints, and relationships.
  • Seeding logic: Complex randomization (70/15/7/8% distribution) and label assignment (~25% coverage) warrant attention to ensure correctness and fairness.
  • Multi-layer integration: Changes span database, API, and frontend—verify consistency across layers (field names, types, serialization).
  • Frontend state management: New Dialog component with multiple state variables (labelsDialogOpen, selectedLabels, allLabels, selectedJobRun) requires review for state initialization, effects, and cleanup.
  • API autocomplete behavior change: Special-case labels branch alters control flow; verify it doesn't break existing autocomplete for other fields.

Pre-merge checks and finishing touches

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 warning, 2 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 24.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Go Error Handling ❓ Inconclusive Repository could not be accessed to verify Go error handling patterns and compliance with best practices in modified source files. Provide direct access to modified Go source files or code diffs showing error handling implementations in seed_data.go, server.go, db.go, and autocomplete.go for verification.
Sql Injection Prevention ❓ Inconclusive Unable to directly access repository code to verify SQL query parameterization in modified database functions. Provide direct access to modified code files or have reviewers manually inspect functions to confirm GORM parameterized queries are used instead of string concatenation.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'TRT-2376: labels in sippy UI' directly references the Jira ticket and accurately describes the main change: adding label display functionality to the sippy UI.
Excessive Css In React Should Use Styles ✅ Passed React components use Material-UI components for styling rather than complex inline CSS objects, following standard Material Design patterns.
Single Responsibility And Clear Naming ✅ Passed The pull request demonstrates strong adherence to single responsibility and clear naming principles. The new jobrunscan package is well-scoped and cohesive.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Nov 11, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: sosiouxme

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Nov 11, 2025
@openshift-ci-robot
Copy link

openshift-ci-robot commented Nov 11, 2025

@sosiouxme: This pull request references TRT-2376 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

example on the job runs table

Summary by CodeRabbit

Release Notes

  • New Features

  • Added labels system to job runs with searchable autocomplete support.

  • New labels dialog in job runs table displays label titles and explanations.

  • Introduced job run overall result classification based on failure types (test, upgrade, install, infrastructure).

  • Added /api/labels endpoint for label data retrieval.

  • Refactor

  • Improved autocomplete handling for diverse data types.

  • Enhanced filter logic for consistent string and array field searching.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot
Copy link

openshift-ci-robot commented Nov 11, 2025

@sosiouxme: This pull request references TRT-2376 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

example on the job runs table
image
image
image

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot
Copy link

openshift-ci-robot commented Nov 11, 2025

@sosiouxme: This pull request references TRT-2376 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

example on the job runs table. add a column exposing any labels:
image

Clicking on it displays the full label explanation:
image

...and of course you can filter by it as well:
image

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
pkg/sippyserver/server.go (1)

979-992: Consider pagination for scalability.

The endpoint fetches all labels without pagination or limits. While the 24-hour cache mitigates performance concerns, consider adding optional pagination parameters if the number of labels is expected to grow significantly.

sippy-ng/src/jobs/JobRunsTable.js (1)

391-412: Consider surfacing label fetch errors to users.

Currently, errors fetching labels are only logged to console (line 410). If label data is critical for the user experience, consider displaying an error message or notification when the fetch fails.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 34cc81c and d46a554.

📒 Files selected for processing (12)
  • cmd/sippy/seed_data.go (4 hunks)
  • pkg/api/autocomplete.go (1 hunks)
  • pkg/apis/api/types.go (3 hunks)
  • pkg/db/db.go (2 hunks)
  • pkg/db/models/jobrunscan/label.go (1 hunks)
  • pkg/db/models/jobrunscan/symptom.go (1 hunks)
  • pkg/db/models/prow.go (1 hunks)
  • pkg/db/views.go (1 hunks)
  • pkg/filter/filterable.go (5 hunks)
  • pkg/sippyserver/server.go (3 hunks)
  • sippy-ng/src/datagrid/GridToolbarAutocomplete.js (2 hunks)
  • sippy-ng/src/jobs/JobRunsTable.js (7 hunks)
🔇 Additional comments (11)
pkg/filter/filterable.go (2)

65-78: Helper correctly generates ILIKE SQL, but note usage context.

The ilikeFilter helper correctly centralizes ILIKE pattern generation for both string and array fields. The negation is baked into the returned SQL string (e.g., "NOT ILIKE" or "NOT EXISTS"), which is the correct approach for OR filters that build SQL strings.

However, this design choice creates a critical issue when used with applyIlikeFilter for AND filters (see next comment).


105-105: Refactoring approach is sound—centralizes ILIKE logic effectively.

The migration to use ilikeFilter and applyIlikeFilter successfully:

  • Eliminates code duplication across Contains, StartsWith, and EndsWith operators
  • Adds array field support via PostgreSQL unnest for pattern matching
  • Maintains consistency between OR filter (lines 105, 138, 140) and AND filter paths (lines 171, 210, 212)

Once the double negation bug in applyIlikeFilter is fixed, this refactoring will work correctly.

Also applies to: 138-140, 171-171, 210-212

pkg/db/db.go (1)

166-173: LGTM!

The migration order is correct, adding the new label and symptom tables before creating audit log indexes.

pkg/apis/api/types.go (1)

358-358: LGTM!

The Labels field is correctly added to JobRun with proper JSON and GORM tags, and all accessor methods (GetFieldType, GetArrayValue) are updated to support the new field.

Also applies to: 377-378, 444-445

pkg/db/views.go (1)

208-208: LGTM!

The materialized view is correctly extended to project the labels column from prow_job_runs.

pkg/sippyserver/server.go (1)

2001-2007: LGTM!

The endpoint is properly configured with LocalDBCapability requirement and appropriate 24-hour cache duration for relatively static label data.

sippy-ng/src/datagrid/GridToolbarAutocomplete.js (1)

30-37: LGTM!

The changes properly handle both string arrays (existing behavior) and object arrays (new label options), maintaining backward compatibility while supporting the new title-aware display.

Also applies to: 66-68

pkg/db/models/prow.go (1)

60-62: LGTM!

The Labels field is correctly defined with an appropriate GIN index for efficient array containment queries. The comment clearly explains the field's purpose.

pkg/api/autocomplete.go (1)

11-15: LGTM!

The LabelOption type correctly defines the structure for label autocomplete with both ID and title fields.

sippy-ng/src/jobs/JobRunsTable.js (2)

156-194: LGTM!

The Labels column implementation is well-designed with a tooltip showing label titles and a button that opens a detailed dialog. The rendering handles missing labels gracefully.


567-608: LGTM!

The labels dialog provides a clean UI for viewing label details with titles and markdown-rendered explanations. The dialog properly handles cases where labels might not be found.

@openshift-ci-robot
Copy link

openshift-ci-robot commented Nov 11, 2025

@sosiouxme: This pull request references TRT-2376 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

example on the job runs table. add a column exposing any labels:
image

Clicking on it displays the full label explanation:
image

...and of course you can filter by it as well:
image

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 16, 2025
@openshift-ci-robot
Copy link

openshift-ci-robot commented Dec 2, 2025

@sosiouxme: This pull request references TRT-2376 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

This defines symptom/label data structures and displays labels in the job runs table. Note: some of the groundwork I found along the way was broken out to #3117 and this is based on that, so review only the last 3 commits.

Adds a column to job runs table exposing any labels:
image

Clicking on it displays the full label explanation:
image

...and of course you can filter by it as well:
image

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@sosiouxme sosiouxme force-pushed the 20251105-TRT-2376-sippy-UI-labels branch from d46a554 to 2b1edab Compare December 2, 2025 23:25
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Dec 2, 2025
@openshift-ci-robot
Copy link

openshift-ci-robot commented Dec 2, 2025

@sosiouxme: This pull request references TRT-2376 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

This defines symptom/label data structures and displays labels in the job runs table. Note: some of the groundwork I found along the way was broken out to #3117 and this is based on that, so review only the last 3 commits.

Adds a column to job runs table exposing any labels:
image

Clicking on it displays the full label explanation:
image

...and of course you can filter by it as well:
image

Summary by CodeRabbit

Release Notes

  • New Features
  • Added Labels system to tag and track job runs with explanations and display contexts
  • Introduced Symptoms detection model for identifying common issues
  • Enhanced filtering operators for array fields: "has entry" and "has entry containing"
  • Added Overall Result categorization to classify failure types
  • Labels search and autocomplete functionality across the application

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/api/autocomplete.go (1)

97-99: Missing return after 404 response in default case.

The default case calls RespondWithJSON with a 404 status but does not return. Execution continues to the release filter, search filter, limit, and scan operations with an uninitialized/base query, which could produce unexpected behavior or errors.

 	default:
 		RespondWithJSON(404, w, map[string]string{"message": "Autocomplete field not found."})
+		return
 	}
🧹 Nitpick comments (5)
pkg/sippyserver/server.go (1)

982-995: /api/labels handler looks correct; consider adding a deterministic sort.

The handler and endpoint wiring are consistent with the rest of the server (capability‑gated, cached, proper error handling). To make UI behavior deterministic and cache keys more stable when labels change infrequently, consider explicitly ordering the query (e.g., by id or label_title) before returning.

 func (s *Server) jsonLabelsFromDB(w http.ResponseWriter, req *http.Request) {
-	var labels []jobrunscan.Label
-	if err := s.db.DB.Find(&labels).Error; err != nil {
+	var labels []jobrunscan.Label
+	if err := s.db.DB.
+		Order("id ASC").
+		Find(&labels).Error; err != nil {
 		log.WithError(err).Error("error fetching labels")
 		failureResponse(w, http.StatusInternalServerError, "Error fetching labels: "+err.Error())
 		return
 	}

Also applies to: 2004-2010

cmd/sippy/seed_data.go (1)

298-324: OverallResult seeding logic is fine; consider wiring infra flags for more realistic data.

The randomized assignment of OverallResult based on testFailures and failureType looks correct and guarantees a non‑zero value for each run. For closer fidelity to production data, you might also set the corresponding boolean flags (InfrastructureFailure, KnownFailure, etc.) when assigning specific failure types so downstream dashboards that key off those flags behave consistently in seeded environments.

pkg/db/models/jobrunscan/symptom.go (1)

10-64: Symptom model looks solid; only minor naming/doc nits.

The Symptom schema (string ID primary key, matcher config, label ID array, filters, and explicit timestamps) is well-structured and aligns with how you seed and will likely query these records. Not embedding gorm.Model avoids the duplicate primary‑key problem called out in earlier reviews.

One small nit: MatcherTypeFile being backed by the string "none" while comments refer to a “file exists” behavior may be slightly confusing for future readers; consider either renaming the constant or clarifying in the comment that "none" is the historical wire value meaning “file existence only”.

sippy-ng/src/helpers.js (1)

210-218: Pre-existing bug: filter.items === [] always evaluates to false.

In JavaScript, comparing an array to an empty array literal using === always returns false due to reference comparison. This should use filter.items.length === 0 instead. Note: this line is not changed by this PR, but if you're modifying this area, consider fixing it.

 export function pathForJobRunsWithFilter(release, filter) {
-  if (!filter || filter.items === []) {
+  if (!filter || filter.items.length === 0) {
     return `/jobs/${release}/runs`
   }
sippy-ng/src/jobs/JobRunsTable.js (1)

359-380: Consider surfacing label fetch errors to the user.

The fetch silently returns an empty object on non-200 status, causing labels to display as IDs rather than titles. While this degradation is acceptable, consider showing a dismissible warning to inform users that label details couldn't be loaded.

Example addition after line 378:

       .catch((error) => {
         console.error('Could not fetch labels:', error)
+        // Optionally set a state variable to show a warning banner
       })
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between d46a554 and 2b1edab.

📒 Files selected for processing (21)
  • .coderabbit.yaml (1 hunks)
  • cmd/sippy/seed_data.go (4 hunks)
  • pkg/api/autocomplete.go (1 hunks)
  • pkg/api/tests.go (6 hunks)
  • pkg/apis/api/types.go (3 hunks)
  • pkg/db/db.go (2 hunks)
  • pkg/db/models/jobrunscan/label.go (1 hunks)
  • pkg/db/models/jobrunscan/symptom.go (1 hunks)
  • pkg/db/models/prow.go (1 hunks)
  • pkg/db/views.go (1 hunks)
  • pkg/filter/filterable.go (7 hunks)
  • pkg/sippyserver/server.go (3 hunks)
  • sippy-ng/src/constants.js (1 hunks)
  • sippy-ng/src/datagrid/GridToolbarAutocomplete.js (2 hunks)
  • sippy-ng/src/datagrid/GridToolbarFilterItem.js (1 hunks)
  • sippy-ng/src/helpers.js (6 hunks)
  • sippy-ng/src/jobs/JobRunsTable.js (8 hunks)
  • sippy-ng/src/jobs/VariantStatus.js (3 hunks)
  • sippy-ng/src/tests/FeatureGates.js (6 hunks)
  • sippy-ng/src/tests/TestAnalysis.js (1 hunks)
  • sippy-ng/src/tests/TestTable.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • pkg/apis/api/types.go
  • pkg/db/views.go
  • sippy-ng/src/datagrid/GridToolbarAutocomplete.js
  • pkg/db/models/jobrunscan/label.go
  • pkg/db/db.go
🧰 Additional context used
🧬 Code graph analysis (6)
sippy-ng/src/tests/TestTable.js (1)
sippy-ng/src/helpers.js (1)
  • filterFor (280-282)
sippy-ng/src/tests/TestAnalysis.js (1)
sippy-ng/src/helpers.js (2)
  • not (306-309)
  • filterFor (280-282)
sippy-ng/src/jobs/VariantStatus.js (1)
sippy-ng/src/helpers.js (1)
  • filterFor (280-282)
pkg/api/autocomplete.go (2)
pkg/db/db.go (1)
  • DB (27-33)
vendor/github.com/gorilla/mux/mux.go (1)
  • Vars (430-435)
pkg/filter/filterable.go (1)
pkg/apis/api/types.go (2)
  • ColumnTypeArray (24-24)
  • ColumnTypeTimestamp (25-25)
pkg/db/models/jobrunscan/symptom.go (1)
vendor/github.com/invopop/jsonschema/id.go (1)
  • ID (12-12)
🔇 Additional comments (33)
.coderabbit.yaml (1)

10-14: Good reorganization of tool configuration.

Moving linting tools (shellcheck, markdownlint) from chat to reviews is the right call—these are code quality/static analysis tools that belong in the review pipeline, not chat. The configuration is structurally correct per the CodeRabbit schema.

pkg/db/models/prow.go (1)

60-62: ProwJobRun.Labels field is well-aligned with existing model patterns.

Using pq.StringArray plus a GIN index for label IDs fits the existing schema conventions (e.g., variants) and should work well with the new filtering semantics. JSON exposure as "labels" is appropriate for the API representation.

sippy-ng/src/datagrid/GridToolbarFilterItem.js (1)

37-42: Array operator set matches new semantics and integrates cleanly.

Updating array operators to ['has entry', 'has entry containing', 'is empty'] aligns with the new membership semantics and still respects the existing “no value” handling for is empty. Users can express “is not empty” via the Not toggle, so no further changes seem required here.

sippy-ng/src/tests/TestTable.js (1)

737-745: Variant filter change to has entry is consistent and correct.

Switching the variants filter in the job‑runs links from contains to has entry matches the new array‑field semantics and the updated operator set in the toolbar. The rest of the filter construction logic is unchanged and remains compatible.

sippy-ng/src/tests/TestAnalysis.js (1)

58-66: Updated default variants filters in TestAnalysis correctly use has entry.

Using has entry (wrapped in not(...)) for the initial variants filters keeps TestAnalysis consistent with the rest of the UI and the backend’s array semantics while preserving the intent of excluding aggregated/never‑stable variants.

sippy-ng/src/jobs/VariantStatus.js (1)

34-41: VariantStatus now consistently uses has entry for variants filters.

All three variant‑based filters (chart, jobs table, job runs table) now use has entry, which matches the new array operator behavior elsewhere in the UI and should keep variant views and job‑run links in sync.

Also applies to: 63-68, 75-80

cmd/sippy/seed_data.go (1)

336-428: Fix pq.StringArray assignments for Symptom.LabelIDs and ProwJobRun.Labels (compile-time type mismatch).

jobrunscan.Symptom.LabelIDs and models.ProwJobRun.Labels are declared as pq.StringArray, but they are initialized/assigned from []string values. Since pq.StringArray is a named type over []string, direct assignment from []string is not assignable and will fail to compile without an explicit conversion.

Fix by importing github.com/lib/pq and wrapping []string values with pq.StringArray(...):

  • For each LabelIDs: []string{...} in the symptoms slice, use LabelIDs: pq.StringArray{...}
  • For the jobRuns[i].Labels = selectedLabels assignment, use jobRuns[i].Labels = pq.StringArray(selectedLabels)

Applies to lines 336-428 and 430-487. Run go build ./cmd/sippy to verify the fix resolves the type mismatch errors.

sippy-ng/src/helpers.js (7)

120-124: LGTM - Operator change aligns with array membership semantics.

The switch from contains to has entry for the variants field correctly reflects array membership checking rather than substring matching.


138-151: Consistent application of has entry for variant exclusion.

The negated filter using not(filterFor('variants', 'has entry', variant)) correctly excludes job runs containing specific variants from the analysis.


175-179: LGTM - Both array fields now use has entry.

Correctly applies has entry semantics for both failed_test_names and variants array fields.


182-194: LGTM - Consistent operator for test failure filtering.


196-208: LGTM - Flake filtering uses same semantics.


261-265: LGTM - Job variant path uses has entry.


284-286: LGTM - withoutUnstable helper updated consistently.

sippy-ng/src/constants.js (1)

117-128: LGTM - Bookmark operators updated for array field semantics.

The NO_NEVER_STABLE and NO_AGGREGATED bookmarks now correctly use has entry for the variants array field, consistent with the filtering behavior changes across the codebase.

pkg/api/autocomplete.go (2)

11-15: LGTM - Clean struct for label autocomplete results.

The LabelOption struct appropriately represents the label data with both Name (id) and Title for display purposes.


26-45: LGTM - Labels autocomplete returns structured objects.

The special handling for labels correctly queries job_run_labels and returns LabelOption objects with both the identifier and human-readable title, enabling richer autocomplete UX in the frontend.

sippy-ng/src/tests/FeatureGates.js (2)

27-58: Verify intentional distinction between has entry containing and has entry operators.

The defaultFilterModel uses has entry containing while staleFeatureGates (lines 60-89) uses has entry for the same enabled column exclusions. This means:

  • defaultFilterModel: Excludes if any array element contains the substring "Default:Hypershift"
  • staleFeatureGates: Excludes only if an array element exactly matches "Default:Hypershift"

Please confirm this is the intended behavior, as both filters appear to serve similar purposes (excluding default-enabled feature gates).


96-157: LGTM - Bookmarks consistently use has entry for exact array element matching.

The bookmark filters correctly use has entry for selecting or excluding exact values like Default:Hypershift, TechPreviewNoUpgrade:SelfManagedHA, etc. from the enabled array.

pkg/api/tests.go (4)

358-372: LGTM - Parameterized BigQuery queries prevent SQL injection.

Good improvement: using @release placeholder and collecting parameters via queryParams slice prevents SQL injection. The paramIndex pointer correctly tracks parameter naming across filter applications.


397-402: LGTM - Processed filter parameters correctly appended.

The processedFilter parameters are properly accumulated into queryParams using the same pattern as rawFilter.


446-455: LGTM - Parameters correctly assigned to query.

All accumulated parameters are properly assigned to the BigQuery query before execution.


468-469: LGTM - Parameter reuse for overall query is correct.

Reusing the same queryParams for the overall aggregation query ensures consistency and avoids parameter duplication.

sippy-ng/src/jobs/JobRunsTable.js (3)

156-195: LGTM! Well-structured Labels column implementation.

The column correctly handles missing label definitions by falling back to the label ID, and appropriately disables sorting for array fields. The tooltip and dialog interaction provides good UX.


535-576: LGTM! Clean dialog implementation.

The dialog correctly handles missing label definitions and uses ReactMarkdown for rich formatting. The title dynamically shows context (job name and timestamp), improving usability.


239-257: LGTM! Consistent type annotations.

Explicitly marking these columns as type: 'array' aligns with the new Labels column and likely supports proper filtering and autocomplete behavior for array fields.

pkg/filter/filterable.go (7)

69-104: LGTM! Well-structured helper functions.

The helper functions correctly handle ILIKE filtering for both scalar and array fields, with proper BigQuery and Postgres-specific logic for empty array checks. The fix to use db.Where unconditionally in applyIlikeFilter (avoiding double negation) is correct.


113-120: LGTM! Correct Postgres array operators.

The OperatorHasEntry correctly uses ANY for positive matches and ALL with NULL handling for negation. Unifying OperatorContains and OperatorHasEntryContaining through ilikeFilter is a good refactoring.


170-222: LGTM! Consistent filter application.

The andFilterToSQL correctly mirrors orFilterToSQL logic and appropriately delegates to helper functions for ILIKE filtering and empty checks.


257-263: LGTM! Correct BigQuery LIKE and EXISTS logic.

The Contains operators correctly generate NOT EXISTS (...) for negated array searches and NOT LOWER(field) LIKE @param for negated string searches. The NOT precedence is correct in both cases.


264-307: LGTM! Comprehensive BigQuery operator support.

The arithmetic operators correctly place comparison operators between field and parameter. The makeNumParam helper properly converts strings to numbers for BigQuery. StartsWith, EndsWith, and empty checks use appropriate BigQuery syntax.


467-502: LGTM! Clean BigQuery filter result structure.

The BQFilterResult type and ToBQStr method correctly build parameterized BigQuery WHERE clauses, tracking parameter indices to ensure unique parameter names and properly accumulating all parameters.


38-39: LGTM! Clear operator constant additions.

The new OperatorHasEntry and OperatorHasEntryContaining constants are well-named and properly integrated throughout the filtering logic.

@sosiouxme sosiouxme force-pushed the 20251105-TRT-2376-sippy-UI-labels branch from 2b1edab to 0ad1c2b Compare December 4, 2025 16:20
@sosiouxme sosiouxme marked this pull request as ready for review December 4, 2025 16:21
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Dec 4, 2025
@openshift-ci-robot
Copy link

openshift-ci-robot commented Dec 4, 2025

@sosiouxme: This pull request references TRT-2376 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

This defines symptom/label data structures and displays labels in the job runs table. Note: some of the groundwork I found along the way was broken out to #3117 and this is based on that, so review only the last 3 commits.

Adds a column to job runs table exposing any labels:
image

Clicking on it displays the full label explanation:
image

...and of course you can filter by it as well:
image

Summary by CodeRabbit

  • New Features

  • Labels system to tag job runs with explanations and display contexts; dialog to view per-run labels

  • Symptom detection with associated labels

  • New Overall Result categorization for job-run failures

  • Labels autocomplete for filter/search inputs

  • Enhancements

  • Expanded array-field filter operators: "has entry", "has entry containing", and "is empty"

  • Other

  • Removed several hidden columns from Job Runs table view (cleanup)

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
pkg/api/autocomplete.go (1)

25-45: Labels autocomplete implementation looks good.

The special handling for the "labels" field correctly:

  • Queries the job_run_labels table with proper column aliasing
  • Supports search filtering on both ID and title
  • Applies consistent limit of 50 results
  • Returns early with the structured response

As clarified in the previous review, the id field is varchar(80), so using ILIKE directly without casting is appropriate.

🧹 Nitpick comments (6)
sippy-ng/src/jobs/JobRunsTable.js (1)

359-380: Silent failure on non-200 responses could be more informative.

When the /api/labels endpoint returns a non-200 status, the code silently returns an empty object without logging. This makes debugging harder if labels aren't displaying correctly.

Consider logging non-200 responses for better observability:

   useEffect(() => {
     fetch(process.env.REACT_APP_API_URL + '/api/labels')
       .then((response) => {
         if (response.status !== 200) {
+          console.warn('Labels API returned status:', response.status)
           return {}
         }
         return response.json()
       })
pkg/db/models/jobrunscan/symptom.go (2)

19-22: Comment mentions matcher types not defined as constants.

The comment references "jq" and "xpath" as valid matcher types, but no corresponding constants are defined (lines 59-64). Either add the missing constants or update the comment to reflect the currently supported types.

 	// Type of matcher
-	// Simple types: "string", "regex", "jq", "xpath", "none"
+	// Simple types: "string", "regex", "none"
 	// Compound type: "cel" (Common Expression Language against label names)
 	MatcherType string `gorm:"type:varchar(50);not null" json:"matcher_type"`

58-64: Consider renaming MatcherTypeFile for clarity.

The constant name MatcherTypeFile is misleading since its value is "none". The name suggests file-based matching, while the value suggests no matching. Consider renaming to align with either the value or the purpose:

  • MatcherTypeNone (aligns with value)
  • MatcherTypeFileExists (aligns with comment/purpose)
 const (
 	MatcherTypeString = "string" // Simple substring match
 	MatcherTypeRegex  = "regex"  // Regular expression match
-	MatcherTypeFile   = "none"   // File exists (no content match)
+	MatcherTypeNone   = "none"   // File exists (no content match)
 	MatcherTypeCEL    = "cel"    // Common Expression Language for compound logic
 )
pkg/filter/filterable.go (3)

113-117: Consider adding array type validation for consistency.

The HasEntry operator handling in orFilterToSQL and andFilterToSQL assumes the field is an array type without checking (using ANY/ALL operators), while toBQStr (lines 253-256) validates the field type and falls back to "UnknownFilterOperator()" for non-arrays.

While the database will catch the error at runtime, adding consistent type validation in the SQL paths would provide earlier feedback and match the BigQuery path's behavior.

Example for orFilterToSQL:

 case OperatorHasEntry:
+	if filterable == nil || filterable.GetFieldType(f.Field) != apitype.ColumnTypeArray {
+		return "UnknownFilterOperator()", nil
+	}
 	if f.Not {
 		return fmt.Sprintf("%s IS NULL OR ? != ALL(%s)", field, field), f.Value
 	}
 	return fmt.Sprintf("? = ANY(%s)", field), f.Value

Also applies to: 170-175


244-250: Consider logging numeric conversion errors.

The makeNumParam helper handles conversion errors by embedding the error message in the parameter value (line 247), which will cause BigQuery to fail. While this achieves the intended fail-fast behavior, logging the error would aid debugging without relying solely on the downstream BigQuery error.

 makeNumParam := func() []bigquery.QueryParameter {
 	num, err := strconv.ParseFloat(f.Value, 64)
 	if err != nil {
+		log.Errorf("Failed to parse numeric filter value %q for field %s: %v", f.Value, f.Field, err)
 		return makeParam("NOT A NUMBER: " + f.Value) // which will break appropriately
 	}
 	return makeParam(num)
 }

160-160: Optional: Log unknown operators before SQL failure.

The fallback to "UnknownFilterOperator()" will cause obvious SQL failures, which is the intended behavior. However, logging the unknown operator before returning would improve debuggability by providing immediate feedback rather than relying on downstream SQL errors.

+	log.Errorf("Unknown filter operator %q for field %s", f.Operator, f.Field)
 	return "UnknownFilterOperator()", nil // cause SQL to fail in obvious way

Also applies to: 309-309

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 2b1edab and 0ad1c2b.

📒 Files selected for processing (12)
  • cmd/sippy/seed_data.go (4 hunks)
  • pkg/api/autocomplete.go (1 hunks)
  • pkg/apis/api/types.go (3 hunks)
  • pkg/db/db.go (2 hunks)
  • pkg/db/models/jobrunscan/label.go (1 hunks)
  • pkg/db/models/jobrunscan/symptom.go (1 hunks)
  • pkg/db/models/prow.go (1 hunks)
  • pkg/db/views.go (1 hunks)
  • pkg/filter/filterable.go (7 hunks)
  • pkg/sippyserver/server.go (3 hunks)
  • sippy-ng/src/datagrid/GridToolbarAutocomplete.js (2 hunks)
  • sippy-ng/src/jobs/JobRunsTable.js (8 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • pkg/db/views.go
  • pkg/apis/api/types.go
  • pkg/db/models/jobrunscan/label.go
  • cmd/sippy/seed_data.go
  • sippy-ng/src/datagrid/GridToolbarAutocomplete.js
🧰 Additional context used
🧬 Code graph analysis (5)
pkg/sippyserver/server.go (1)
pkg/sippyserver/capabilities.go (1)
  • LocalDBCapability (9-9)
pkg/db/db.go (2)
pkg/db/models/jobrunscan/label.go (2)
  • Label (11-33)
  • Label (41-43)
pkg/db/models/jobrunscan/symptom.go (2)
  • Symptom (11-52)
  • Symptom (54-56)
pkg/api/autocomplete.go (2)
pkg/db/db.go (1)
  • DB (27-33)
vendor/github.com/gorilla/mux/mux.go (1)
  • Vars (430-435)
pkg/filter/filterable.go (1)
pkg/apis/api/types.go (2)
  • ColumnTypeArray (24-24)
  • ColumnTypeTimestamp (25-25)
pkg/db/models/jobrunscan/symptom.go (1)
vendor/github.com/invopop/jsonschema/id.go (1)
  • ID (12-12)
🔇 Additional comments (16)
sippy-ng/src/jobs/JobRunsTable.js (3)

156-195: LGTM! Well-implemented Labels column.

The Labels column implementation handles edge cases properly:

  • Empty/null arrays return empty string
  • Label IDs gracefully fall back to showing the ID when lookup fails
  • Tooltip provides quick preview of label titles
  • Button opens detailed dialog with full explanations

535-576: LGTM! Labels dialog is well-structured.

The dialog provides a clean UX with:

  • Dynamic title showing job name and timestamp
  • List of labels with titles and markdown-rendered explanations
  • Fallback display when a label isn't found in the lookup

237-257: Good addition of type: 'array' for array fields.

Adding explicit type: 'array' to variants, failed_test_names, and flaked_test_names columns aligns with the filter/operator changes mentioned in the PR for handling array-based filtering.

pkg/db/models/prow.go (1)

60-62: LGTM! Well-designed Labels field addition.

The Labels field is properly defined with:

  • pq.StringArray for PostgreSQL text[] compatibility
  • GIN index for efficient array containment queries
  • Clear documentation explaining the field's purpose
pkg/db/db.go (1)

69-104: Good refactor to loop-based migrations.

The migration logic is now cleaner and more maintainable:

  • Consolidated list makes it easy to see all migrated models
  • Loop preserves fail-fast error handling
  • New jobrunscan.Label and jobrunscan.Symptom models are properly included
pkg/sippyserver/server.go (2)

982-995: LGTM! Clean handler implementation.

The handler correctly:

  • Queries all labels from the database
  • Logs errors with context before returning
  • Wraps response in a consistent structure matching frontend expectations

One minor consideration: If the labels table grows large, you may want to add pagination. However, labels are typically a small, controlled set, so this is likely fine for now.


2004-2010: LGTM! Endpoint properly registered.

The /api/labels endpoint is correctly configured with:

  • LocalDBCapability requirement
  • 24-hour cache (appropriate for relatively static label definitions)
pkg/api/autocomplete.go (1)

11-15: LGTM! Clean type definition for label autocomplete.

The LabelOption struct provides the necessary fields for the frontend autocomplete component to display both the label ID (for filtering) and the human-readable title.

pkg/db/models/jobrunscan/symptom.go (2)

54-56: LGTM!

The TableName method correctly overrides the default GORM table name convention.


10-52: Well-designed model addressing prior feedback.

The struct properly defines its own primary key (ID string) and metadata fields (CreatedAt, UpdatedAt, DeletedAt) without embedding gorm.Model, which resolves the previously raised issue about conflicting primary keys. The GORM tags and field types are appropriate for PostgreSQL.

pkg/filter/filterable.go (6)

10-10: LGTM: Well-designed BigQuery parameterization infrastructure.

The BQFilterResult struct and updated ToBQStr method signature properly support parameterized queries with parameter index tracking across multiple filter calls. The pointer-based paramIndex allows correct parameter numbering when filters are nested or called multiple times.

Also applies to: 467-502


34-41: LGTM: Clear operator definitions for array handling.

The new OperatorHasEntry and OperatorHasEntryContaining operators are well-named and follow the existing pattern. The distinction between exact and partial matching is clear.


68-104: LGTM: Clean helper abstractions for filter logic.

The helper functions properly abstract:

  • Conditional NOT prefix generation (optNot)
  • ILIKE pattern matching for both string and array fields (ilikeFilter, applyIlikeFilter)
  • Null/empty checks with BigQuery-specific array handling (isEmptyFilter)

The fix for the double negation bug (always using db.Where on line 88) is correctly implemented per past review comments.


257-263: LGTM: Correct case-insensitive pattern matching for arrays and strings.

The Contains and HasEntryContaining operators properly handle both array fields (using EXISTS with UNNEST) and string fields, with consistent case-insensitive matching via LOWER(). Negation is correctly applied via optNot.


233-242: LGTM: Proper SQL injection protection via parameter binding.

All user-supplied filter values are safely bound as named BigQuery parameters through makeParam and makeNumParam helpers. The 1-based parameter naming scheme (filterParam1, filterParam2, etc.) is clear and consistent.


477-502: LGTM: Robust parameter index management.

The pointer-based paramIndex parameter correctly tracks parameter numbers across multiple filter items, preventing naming collisions. The enhanced logging (line 496) with parameter counts is helpful for debugging parameterized queries.

@openshift-ci-robot
Copy link

Scheduling required tests:
/test e2e

@openshift-ci openshift-ci bot requested review from dgoodwin and neisw December 4, 2025 16:33
🤖 Assisted by Claude Code
* add labels column with tooltip
* add popup with full label explanations
* add labels to filtering

🤖 Assisted by Claude Code
This looked ugly anyway. Turn repetitive code into an array...

🤖 Assisted by Claude Code
@openshift-ci-robot
Copy link

openshift-ci-robot commented Dec 4, 2025

@sosiouxme: This pull request references TRT-2376 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

This defines symptom/label data structures and displays labels in the job runs table.

Adds a column to job runs table exposing any labels:
image

Clicking on it displays the full label explanation:
image

...and of course you can filter by it as well:
image

Summary by CodeRabbit

  • New Features

  • Labels system to tag job runs with explanations and display contexts; dialog to view per-run labels

  • Symptom detection with associated labels

  • New Overall Result categorization for job-run failures

  • Labels autocomplete for filter/search inputs

  • Enhancements

  • Expanded array-field filter operators: "has entry", "has entry containing", and "is empty"

  • Other

  • Removed several hidden columns from Job Runs table view (cleanup)

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot
Copy link

openshift-ci-robot commented Dec 4, 2025

@sosiouxme: This pull request references TRT-2376 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

This defines symptom/label data structures and displays labels in the job runs table. There is also an update to the seed data generator to add some labels and sporadically apply them to job runs generated.

Adds a column to job runs table exposing any labels:
image

Clicking on it displays the full label explanation:
image

...and of course you can filter by it as well:
image

Summary by CodeRabbit

  • New Features

  • Labels system to tag job runs with explanations and display contexts; dialog to view per-run labels

  • Symptom detection with associated labels

  • New Overall Result categorization for job-run failures

  • Labels autocomplete for filter/search inputs

  • Enhancements

  • Expanded array-field filter operators: "has entry", "has entry containing", and "is empty"

  • Other

  • Removed several hidden columns from Job Runs table view (cleanup)

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot
Copy link

openshift-ci-robot commented Dec 4, 2025

@sosiouxme: This pull request references TRT-2376 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

This defines symptom/label data structures and displays labels in the job runs table. There is also an update to the seed data generator to add some labels and sporadically apply them to job runs generated so you can see labels in action.

Adds a column to job runs table exposing any labels:
image

Clicking on it displays the full label explanation:
image

...and of course you can filter by it as well:
image

Summary by CodeRabbit

  • New Features

  • Labels system to tag job runs with explanations and display contexts; dialog to view per-run labels

  • Symptom detection with associated labels

  • New Overall Result categorization for job-run failures

  • Labels autocomplete for filter/search inputs

  • Enhancements

  • Expanded array-field filter operators: "has entry", "has entry containing", and "is empty"

  • Other

  • Removed several hidden columns from Job Runs table view (cleanup)

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot
Copy link

openshift-ci-robot commented Dec 4, 2025

@sosiouxme: This pull request references TRT-2376 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

This defines symptom/label data structures and displays labels in the job runs table. There is also an update to the seed data generator to add some labels and randomly apply them to job runs generated so you can see labels in action.

Adds a column to job runs table exposing any labels:
image

Clicking on it displays the full label explanation:
image

...and of course you can filter by it as well:
image

Summary by CodeRabbit

  • New Features

  • Labels system to tag job runs with explanations and display contexts; dialog to view per-run labels

  • Symptom detection with associated labels

  • New Overall Result categorization for job-run failures

  • Labels autocomplete for filter/search inputs

  • Enhancements

  • Expanded array-field filter operators: "has entry", "has entry containing", and "is empty"

  • Other

  • Removed several hidden columns from Job Runs table view (cleanup)

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@sosiouxme sosiouxme force-pushed the 20251105-TRT-2376-sippy-UI-labels branch from 0ad1c2b to c76313a Compare December 4, 2025 23:04
@openshift-ci-robot
Copy link

openshift-ci-robot commented Dec 4, 2025

@sosiouxme: This pull request references TRT-2376 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

In response to this:

This defines symptom/label data structures and displays labels in the job runs table. There is also an update to the seed data generator to add some labels and randomly apply them to job runs generated so you can see labels in action.

Adds a column to job runs table exposing any labels:
image

Clicking on it displays the full label explanation:
image

...and of course you can filter by it as well:
image

Summary by CodeRabbit

Release Notes

  • New Features
  • Job runs now support labels for better categorization and filtering
  • New labels dialog displays detailed label information including titles and explanations
  • Autocomplete search enhanced to filter by labels
  • Predefined labels and symptoms automatically seeded into the system

✏️ Tip: You can customize this high-level summary in your review settings.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (8)
pkg/filter/filterable.go (1)

311-311: LGTM! Consider adding similar logging to line 160 for consistency.

The error logging for unknown operators is a good improvement for debugging filter issues.

For consistency, consider adding similar logging to line 160 in orFilterToSQL, which has identical error handling but no logging:

+	log.Errorf("Unknown filter operator %q for field %s", f.Operator, f.Field)
 	return "UnknownFilterOperator()", nil // cause SQL to fail in obvious way
pkg/api/autocomplete.go (1)

26-45: Consider filtering out soft-deleted labels.

The Label model has a DeletedAt field for soft deletes. The current query may return deleted labels in autocomplete results.

Apply this diff to exclude soft-deleted labels:

 	if field == "labels" {
 		labelResult := make([]LabelOption, 0)
 		q := dbc.DB.Table("job_run_labels").
 			Select("id as name, label_title as title").
+			Where("deleted_at IS NULL").
 			Order("name")
sippy-ng/src/jobs/JobRunsTable.js (2)

359-383: Consider handling the race condition when labels are used before they're loaded.

The labels are fetched independently from the job runs data. If a user clicks on a label button before the /api/labels fetch completes, allLabels will be an empty object, causing all labels to show as "Label not found" in the dialog.

Consider either:

  1. Disabling the label button while allLabels is empty
  2. Adding a loading state for labels
  3. Ensuring the labels fetch completes before rendering the table (though this adds latency)

The current fallback to show labelId when label is not found (line 169, 559) provides a reasonable degraded experience, so this is a minor concern.


173-178: Prefer using labelId as the key instead of array index.

Using labelId as the key would provide more stable React reconciliation than array indices, especially if labels were reordered.

-                {labelTitles.map((title, idx) => (
-                  <div key={idx}>{title}</div>
+                {params.value.map((labelId, idx) => (
+                  <div key={labelId}>
+                    {allLabels[labelId]?.label_title || labelId}
+                  </div>
                 ))}
cmd/sippy/seed_data.go (2)

372-376: Minor: "New record" detection logic is inverted.

The condition existing.CreatedAt.IsZero() || existing.CreatedAt.Equal(existing.UpdatedAt) for detecting a newly created record is incorrect:

  • CreatedAt.IsZero() would only be true if GORM failed to set it (unlikely)
  • CreatedAt.Equal(UpdatedAt) is true for newly created records, but the log message says "Created new" when this is true

Since FirstOrCreate sets both CreatedAt and UpdatedAt to the same value for new records, the condition happens to work by accident for new records, but the "already exists" branch would never be reached because existing records loaded from DB also have equal timestamps initially. This only affects debug logging, so it's not critical.

A cleaner approach would be to check if the record was actually created:

-		if existing.CreatedAt.IsZero() || existing.CreatedAt.Equal(existing.UpdatedAt) {
-			log.Debugf("Created new Label: %s", label.ID)
-		} else {
-			log.Debugf("Label already exists: %s", label.ID)
-		}
+		// FirstOrCreate returns the existing record if found
+		// We can compare to see if we created or found
+		if existing.LabelTitle == label.LabelTitle {
+			log.Debugf("Label already exists or created: %s", label.ID)
+		}

Or simply log without the distinction since it's debug-level.

Also applies to: 420-424


430-487: Consider batching updates for better performance in large datasets.

The current implementation loads all job runs into memory and performs individual Save calls for each labeled run. For a seed data tool with moderate data volumes, this is acceptable. However, if the dataset grows large, this could become slow.

For future improvement, consider:

  1. Batching updates (e.g., using dbc.DB.Save(&batch) with slices)
  2. Using a raw SQL UPDATE with array concatenation for bulk operations

Since this is a development/seeding tool, the current approach is reasonable.

pkg/db/models/jobrunscan/symptom.go (2)

58-64: Consider clarifying the MatcherTypeFile constant naming.

The constant MatcherTypeFile = "none" could be confusing since "none" doesn't clearly indicate "file existence check." The comment helps, but the value "none" might be misinterpreted as "no matching" rather than "match by file existence."

Consider renaming for clarity, though this may have migration implications if the value is already stored in databases:

 const (
 	MatcherTypeString = "string" // Simple substring match
 	MatcherTypeRegex  = "regex"  // Regular expression match
-	MatcherTypeFile   = "none"   // File exists (no content match)
+	MatcherTypeFile   = "file"   // File exists (no content match)
 	MatcherTypeCEL    = "cel"    // Common Expression Language for compound logic
 )

If changing the value isn't feasible, the current naming with the comment is acceptable.


19-22: Documentation mentions matcher types without corresponding constants.

The comment lists "jq" and "xpath" as valid simple types, but there are no corresponding constants defined. Either these are planned for future implementation (in which case a TODO comment would help) or the documentation should be updated to reflect only the currently supported types.

 	// Type of matcher
-	// Simple types: "string", "regex", "jq", "xpath", "none"
+	// Simple types: "string", "regex", "none"
 	// Compound type: "cel" (Common Expression Language against label names)
 	MatcherType string `gorm:"type:varchar(50);not null" json:"matcher_type"`

Or add TODO for planned types:

// TODO: Future types may include "jq" and "xpath"
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 0ad1c2b and c76313a.

📒 Files selected for processing (12)
  • cmd/sippy/seed_data.go (4 hunks)
  • pkg/api/autocomplete.go (1 hunks)
  • pkg/apis/api/types.go (3 hunks)
  • pkg/db/db.go (2 hunks)
  • pkg/db/models/jobrunscan/label.go (1 hunks)
  • pkg/db/models/jobrunscan/symptom.go (1 hunks)
  • pkg/db/models/prow.go (1 hunks)
  • pkg/db/views.go (1 hunks)
  • pkg/filter/filterable.go (2 hunks)
  • pkg/sippyserver/server.go (3 hunks)
  • sippy-ng/src/datagrid/GridToolbarAutocomplete.js (2 hunks)
  • sippy-ng/src/jobs/JobRunsTable.js (7 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/sippyserver/server.go
  • sippy-ng/src/datagrid/GridToolbarAutocomplete.js
🧰 Additional context used
🧬 Code graph analysis (3)
pkg/db/db.go (2)
pkg/db/models/jobrunscan/label.go (2)
  • Label (11-33)
  • Label (41-43)
pkg/db/models/jobrunscan/symptom.go (2)
  • Symptom (11-52)
  • Symptom (54-56)
cmd/sippy/seed_data.go (4)
pkg/apis/sippyprocessing/v1/types.go (6)
  • JobOverallResult (69-69)
  • JobTestFailure (77-77)
  • JobUpgradeFailure (76-76)
  • JobInstallFailure (75-75)
  • JobInfrastructureFailure (74-74)
  • JobSucceeded (72-72)
pkg/db/models/jobrunscan/label.go (2)
  • Label (11-33)
  • Label (41-43)
pkg/db/models/jobrunscan/symptom.go (5)
  • Symptom (11-52)
  • Symptom (54-56)
  • MatcherTypeString (60-60)
  • MatcherTypeRegex (61-61)
  • MatcherTypeFile (62-62)
pkg/db/models/prow.go (1)
  • ProwJobRun (36-66)
pkg/api/autocomplete.go (2)
pkg/db/db.go (1)
  • DB (27-33)
vendor/github.com/gorilla/mux/mux.go (1)
  • Vars (430-435)
🔇 Additional comments (12)
pkg/filter/filterable.go (1)

247-248: LGTM! Good addition for observability.

The error logging provides helpful diagnostic information when numeric filter values fail to parse. This will make debugging filter issues much easier without changing the existing error-handling behavior.

pkg/apis/api/types.go (2)

358-358: LGTM!

The Labels field addition follows the established pattern for array fields in the JobRun struct, with appropriate GORM and JSON tags matching other pq.StringArray fields like Tags and Variants.


377-378: Field type and accessor methods correctly extended.

The GetFieldType and GetArrayValue implementations are consistent with the existing pattern for array fields, and properly integrate with the filtering infrastructure.

Also applies to: 444-445

pkg/db/views.go (1)

208-208: LGTM!

The labels column is correctly added to the materialized view, exposing the new field from prow_job_runs for downstream API queries.

pkg/db/models/prow.go (1)

60-62: LGTM!

The Labels field is well-documented and follows the established pattern for indexed array fields in this codebase. The GIN index will support efficient array containment queries for label filtering.

pkg/db/db.go (1)

69-104: Clean refactor to list-driven migrations.

The consolidation of AutoMigrate calls into a loop improves maintainability. The new jobrunscan.Label and jobrunscan.Symptom models are correctly included.

pkg/api/autocomplete.go (1)

11-15: LGTM!

The LabelOption struct provides the necessary fields for the UI to display both the label identifier and a human-readable title in the autocomplete dropdown.

pkg/db/models/jobrunscan/label.go (1)

10-43: LGTM! Clean model definition without embedded gorm.Model.

The Label struct correctly defines explicit fields for the primary key and timestamps, avoiding the previous issue with conflicting primary keys from embedding gorm.Model. The use of pq.StringArray for the HideDisplayContexts field is appropriate for PostgreSQL's text[] type, and the display context constants are well-documented.

sippy-ng/src/jobs/JobRunsTable.js (1)

538-579: LGTM! Well-structured dialog with proper accessibility handling.

The dialog implementation is clean with appropriate MUI components. Using ReactMarkdown for rendering label explanations allows for rich formatting in the explanation content. The key prop correctly uses labelId for stable list rendering.

cmd/sippy/seed_data.go (2)

298-323: LGTM! OverallResult assignment logic is correct.

The random distribution correctly covers all failure types with sensible proportions (70% test, 15% upgrade, 7% install, 8% infrastructure). The conditional boundaries are accurate and the v1.JobOverallResult constants are used appropriately.


338-365: Good sample data demonstrating various label features.

The sample labels effectively demonstrate the different capabilities: markdown formatting with links and lists, and the HideDisplayContexts feature for controlling where labels appear. This will be helpful for development and testing.

pkg/db/models/jobrunscan/symptom.go (1)

10-56: LGTM! Well-structured Symptom model with proper GORM configuration.

The Symptom struct correctly defines explicit fields without embedding gorm.Model, resolving the previous review concern. The use of pq.StringArray for multiple array fields is consistent, and the filter/validity window fields provide good flexibility for scoping symptom matching.

@openshift-ci-robot
Copy link

Scheduling required tests:
/test e2e

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Dec 4, 2025

@sosiouxme: all tests passed!

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants