Skip to content

ci: add Docker build and ghcr push to CI pipeline - #10

Closed
rophy wants to merge 27 commits into
mainfrom
ci/docker-build
Closed

ci: add Docker build and ghcr push to CI pipeline#10
rophy wants to merge 27 commits into
mainfrom
ci/docker-build

Conversation

@rophy

@rophy rophy commented May 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds a docker job to CI that runs after e2e tests pass
  • On PRs: builds the Docker image only (validates Dockerfile)
  • On main: checks if version from package.json already exists in ghcr, fails if so, otherwise pushes ghcr.io/null-ptr-exception/rulemgmt:<version> and latest
  • Uses BuildKit with GitHub Actions cache

Test plan

  • PR CI builds Docker image without pushing
  • Merge to main pushes image to ghcr with correct version tag
  • Duplicate version push fails with clear error message

Summary by CodeRabbit

  • Chores
    • Enhanced CI pipeline with automated Docker image building and publishing to container registry, including version management to prevent duplicate releases.

Review Change Stack

rophy added 27 commits May 15, 2026 11:58
* feat: add test scaffolding, linting, and CI pipeline

- Vitest config and smoke test
- Playwright config with auto webServer start/stop
- ESLint flat config with recommended rules
- GitHub Actions CI: lint+test job, e2e job (skips if no tests found)
- .gitignore for node_modules, dist, playwright artifacts

* fix: use if/then/else for e2e skip logic to avoid masking failures

* fix: regenerate package-lock.json for CI compatibility

* fix: regenerate package-lock.json with node 22 for CI compatibility

* fix: check for e2e test files instead of parsing playwright output

* fix: add static serving, e2e smoke test, and simplify CI

- Add express.static + SPA catch-all to server.js so e2e tests work
- Add PORT env var support to server.js
- Add e2e smoke test that verifies the app loads
- Simplify CI: always run e2e tests (no skip logic)
…outes

New Express routes for chart/template CRUD, deployment management,
and Helm render. Schema stored in values.schema.json (native Helm).
- AlertTable, ChartSelector, DeploymentSelector, VariablesPanel, RuleBuilder
- AlertUserView and TemplateDevEditor pages
- schemaUtils, templateGenerator, helmTestGenerator, chartApi utilities
- Rule builder with PromQL + {{ THRESHOLD }} placeholder pattern
- Resizable sidebar with drag grip and touch support
- App shell uses antd Layout + Menu with grouped sections
- All existing pages migrated from custom CSS to antd components
- Strip App.css to global reset only
- Add antd dependency
Remove unused editor pages (AlertSuiteEditor, AlertTypeEditor,
AlertTypePackEditor, AlertmanagerConfigEditor, SystemEditor) and
legacy sample templates/gitops-deploy directories.
Native Helm chart covering 4 golden signals + infrastructure:
latency, traffic, errors, saturation (connections, buffer pool,
CPU, memory, disk). Includes production and staging deployments.
Also adds demo-app chart for gitops editor.
- Unit tests: schemaUtils, templateGenerator, treeGrouping, smoke
- Integration tests: API endpoint validation
- Chart rendering tests using helm template
- Helm-unittest integration via generated test suites
- E2e tests for Ant Design navigation and page loading
- Dockerfile with helm CLI and sample data seeding
- docker-compose for local dev
- Makefile with apply-sample and clean targets
- CI installs helm + unittest plugin
- PR preview support
- Promote no-unused-vars to error
…tes editor

- New NotificationRoutesEditor: single page for receivers, routes,
  inhibit rules with YAML preview
- API: CRUD on gitops/alertmanager-configs/*.yaml (no Helm, no versioning)
- Remove old ReceiversEditor, AlertmanagerSmartEditor, EditorLayout, VersionModal
- Untrack dist/ (was gitignored but still tracked from before)
- Add sample alertmanager-config for platform-routing
…fig selector

Removes standalone "Notification Rules" nav section — Routes now lives
under "Alert Rules" alongside Templates and Alerts.  Config selection
moved from a sidebar list to a compact top-bar dropdown, giving the
form full page width.
…splay

Both Templates and Alerts editors now use the same recursive buildTree
logic — underscore segments define nesting depth.
- Git CLI wrapper library for clone, commit, push, status operations
- Per-user workspace middleware with git directory management
- Route handlers refactored to read gitopsDir from request context
- GitLab OAuth auth routes and useAuth hook
- Git operations API (status, commit, push, discard, sync)
- LoginPage, GitStatusBar, and useGitStatus polling hook
- Dockerfile with git, Skaffold config for minikube deployment
- JupyterHub Helm values with init-clone and per-user branches
- Base URL support via apiFetch, removed standalone auth
- WIP recovery banner in GitStatusBar
- Removed v1 legacy routes, pages, and utilities
- Chart discovery with type filtering, CHARTS_DIR/DEPLOYMENTS_DIR env vars
- Folders API with tree listing, sample scaffolding
- FolderSelector component wired into deployment UI
- AlertForge branding with user info and logout
- Git controls moved from top bar to sidebar Git panel
- PVC for user workspace, simplified git push
- CodeMirror merge diff viewer for file changes
- GitChanges, GitHistory, GitDiffViewer components
- Two-column GitPanel layout with tabs
- GET /log, GET /diff, POST /pull backend endpoints
- Inlined init-clone script into helm values
- Backend integration tests for alertmanager configs, render, templates
- E2E tests with Playwright for sidebar, templates, git panel
- Chart type migrated from alert-templates to annotations for helm compat
- Added @vitest/coverage-v8 for test coverage collection
@rophy

rophy commented May 19, 2026

Copy link
Copy Markdown
Contributor Author

PR Preview Bot

Preview environment torn down.

@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Free

Run ID: 0ef056f0-2542-4801-b480-652817d8eaac

📥 Commits

Reviewing files that changed from the base of the PR and between 921553c and 401542d.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml

📝 Walkthrough

Walkthrough

A new docker job is added to the CI workflow that automatically builds and pushes Docker images to GitHub Container Registry. The job reads the application version from package.json, validates that the image tag does not already exist on the main branch, and conditionally builds and pushes the image with both version and latest tags using Docker Buildx.

Changes

Docker Image Build and Push

Layer / File(s) Summary
Docker build and push job with GHCR validation
.github/workflows/ci.yml
New docker job runs after e2e completion, reads version from package.json, checks GHCR for existing image tags on main, fails if tag already exists, and conditionally builds and pushes the Docker image to ghcr.io with version and latest tags using Docker Buildx with GitHub Actions caching.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A Docker job joins the CI chain,
Reading versions, checking the main,
If tags don't clash, the image will flow,
To the registry, latest in tow!


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

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

@rophy rophy closed this May 19, 2026
@rophy
rophy deleted the ci/docker-build branch May 19, 2026 22:22
HahaSula added a commit that referenced this pull request Jun 28, 2026
…guation and strict numeric parsing

#10: WorkspaceFilterBar now dedupes columns by name+type. Same-named columns
with different types appear as separate options (e.g. threshold (number) /
threshold (string)); unique names show without suffix. Filter key remains the
column name so matchesFilter per-section type lookup is unaffected.

#11: parseFloat → Number() for strict numeric parsing so prefix-numeric strings
like "100ms" are rejected (NaN) instead of silently truncated to 100. Null cell
values explicitly coerced to NaN to preserve existing null-rejection behaviour.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rophy pushed a commit that referenced this pull request Jun 29, 2026
…pace (#37)

* feat: add alert overview mode with sidebar checkboxes and multi-section workspace

- OverviewTemplateTree: checkbox tree with search, group/leaf toggle, indeterminate state
- AlertOverviewWorkspace: multi-section workspace with workspace-level and per-section filters
- AlertTable: lift filter state to props (filters/onFiltersChange), attach __realIndex for correct edit/delete on filtered rows
- AlertUserView: Single/Overview mode toggle via Segmented control, overview checked state persisted via useSessionState

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: string filter case-insensitive, enum-aware ops, filter header persists on no-match

- matchesFilter: case-insensitive string compare, fix null/undefined guard
- FilterHeader: string ops ['contains','='], enum ops depend on value type (numeric enum → numeric ops, string enum → ['='] only)
- Table: replace display:none with locale.emptyText so filter inputs stay visible when no rows match
- AlertUserView single mode: add Clear filters button to save bar
- SectionPanel: add Clear filters button in section header (clears both section and workspace filters)
- e2e: alert-filter.spec.js covers contains/exact string filter, numeric filter, filter-input persistence on no-match, Clear filters button in single and overview modes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: common var columns now filter correctly using commonValues lookup

matchesFilter was reading row[varName] for common vars which is always
undefined — their value lives in commonValues. Now falls back to
commonValues[varName] when the field is a common var.
Added e2e test: common var column filter keeps/removes rows correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add e2e tests for alert filter and overview mode

- Fix race condition: allValues added to useEffect deps so rows load
  correctly when alert type is clicked before deployment fetch completes
- Correct e2e test fixture to use mariadb_latency_slow_queries key and
  actual schema fields (instance_name, warn_threshold, critical_threshold)
- Fix overview mode tests: use { exact: true } to avoid strict mode
  violations from substring matches on folder names containing "overview"
- Add waitForResponse after clicking deployment node to ensure data is
  loaded before clicking alert type templates
- Fix WorkspaceFilterBar conflict: target column headers by th text
  selector instead of generic getByPlaceholder('value').first()
- Use .first() on row count locators to handle strict mode when multiple
  sections render the same pattern

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add categorized e2e tests for alert filter and overview mode

Adds alert-overview-save.spec.js and expands alert-filter.spec.js and
alert-overview-mode.spec.js with new describe blocks:

- alert-filter.spec.js: Overview mode section filters, Filter state management
- alert-overview-mode.spec.js: Workspace filter bar, Session persistence
- alert-overview-save.spec.js: Save all persistence, Add/delete rows in sections

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: address CodeRabbit review — split useEffect, extract matchesFilter, fix workspace filter ops

- AlertUserView: split useEffect into reset effect ([activeAlert, schema]) and
  row-sync effect ([activeAlert, allValues]) so overview saves don't accidentally
  clear filters/dirty state
- Extract matchesFilter to src/utils/filterUtils.js shared by AlertTable and
  AlertOverviewWorkspace (removes duplication)
- AlertTable: add commonValues to filteredRows useMemo deps
- AlertOverviewWorkspace: use shared matchesFilter, add commonValues to matchCount
  useMemo deps, derive workspace filter operators per column type (adds 'contains'
  for string columns)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: add instance_name to schema and fix test selectors broken by Segmented toggle

- Add instance_name string field to mariadb_latency_slow_queries schema so
  CI (fresh cluster from sample chart) has the column that filter tests require
- Fix alert-overview-save: make dirty via Add instance instead of cell edit
  (td.nth(1) landed on a common-var span with no input)
- Fix nested-deployment: use getByRole('textbox') to skip hidden Segmented
  radio inputs that became first in DOM after mode toggle was added; add
  10s timeout to modal visibility checks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: edit cell instead of adding row to avoid inter-test row count drift

Save all test now edits instance_name text (available since schema was
extended) rather than adding a row, so subsequent tests still see the
seeded 2-row count.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve CodeRabbit review issues — filter isolation, spec self-seeding, stable selectors

- AlertTable: add effectiveFilters prop so workspace filters drive row
  filtering without leaking into section filter state via FilterHeader spread
- AlertOverviewWorkspace: pass sectionFilters (display only) and
  effectiveFilters (ws + section merged) to SectionPanel/AlertTable separately
- alert-filter.spec.js: self-seed e2e-overview-test/dev in Filter state
  management beforeAll to remove cross-spec dependency
- alert-overview-mode.spec.js: self-seed e2e-filter-test/dev in Workspace
  filter bar beforeAll to remove cross-spec dependency
- alert-overview-save.spec.js: use dynamic getCurrentRowCount() instead of
  hardcoded '3 / 3'; remove unused ALERT_TYPE_LABEL constant
- nested-deployment.spec.js: use 'input.ant-input:visible' to skip hidden
  Segmented radio buttons and potential FilterHeader inputs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add unit tests for filterUtils (matchesFilter + getWsOperators)

Move NUM_OPERATORS, STR_OPERATORS, and getWsOperators from
AlertOverviewWorkspace into filterUtils so they can be tested in isolation.
Add 38 unit tests covering:
- getWsOperators: all var types (string, number, integer, numeric enum, string enum, unknown)
- matchesFilter: empty/null guards, string contains/=, all numeric ops (>=/<=/>/</=),
  NaN cell and filter value, numeric enum, string enum, commonValues lookup,
  multi-filter AND semantics, unknown var fallback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: complete PR-37 unit test coverage — filterUtils & schemaUtils

filterUtils.js:
- Rename getWsOperators → getFilterOperators (shared by FilterHeader and
  WorkspaceFilterBar; update all callers)
- Extract mergeFilters() from AlertOverviewWorkspace closure so it is
  independently testable; update component to call the imported helper

filterUtils.test.js (45 tests):
- getFilterOperators: undefined / string / number / integer / numeric enum /
  string enum / unknown type
- mergeFilters: pass-through, non-overlapping merge, section override of ws,
  skip empty-string value, skip null value, empty inputs, immutability guard
- matchesFilter: unchanged from previous commit (31 tests)

schemaUtils.test.js (30 tests — new file):
- schemaAlertNames: happy path, $-prefix exclusion, null/missing schema
- getCommonVars: shape, required flags, enum type, missing section, null schema
- schemaToVars: common-first ordering, no duplication, default/required/enum
  propagation, unknown alert, null schema, no items.properties
- setCommonVars: set, clear on empty/null, preserve other props, enum prop
- varsMapToSchema: full build, omit required when none, multiple alerts
- updateSchemaAlert: add new, overwrite existing, immutability, required array

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve CodeRabbit #10 and #11 — workspace filter column disambiguation and strict numeric parsing

#10: WorkspaceFilterBar now dedupes columns by name+type. Same-named columns
with different types appear as separate options (e.g. threshold (number) /
threshold (string)); unique names show without suffix. Filter key remains the
column name so matchesFilter per-section type lookup is unaffected.

#11: parseFloat → Number() for strict numeric parsing so prefix-numeric strings
like "100ms" are rejected (NaN) instead of silently truncated to 100. Null cell
values explicitly coerced to NaN to preserve existing null-rejection behaviour.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: address CodeRabbit review on filterUtils.test.js

- Fix filter.value=undefined test case (was passing null entry, not {value:undefined})
- Use deep copy (JSON.parse/stringify) for mergeFilters immutability assertion
- Document wsFilters same-name/different-type overwrite as intended behaviour
  with two tests covering key collision semantics and per-section type evaluation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: add sidebar collapse toggle for mobile usability

Sidebar (alerts panel) was fixed at 300px with no way to hide it on narrow
screens, leaving the workspace invisible on mobile. Move the resize handle
outside the sidebar div so it remains clickable when collapsed, and add a
click-to-toggle behaviour (‹/›) alongside the existing drag-to-resize.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: use position:fixed for sidebar collapse toggle to stay in viewport

The toggle button was position:absolute inside a flex child, causing it to
scroll off-screen when the sidebar tree expanded beyond the viewport height.
Switch to position:fixed so it always stays at the bottom-left of the viewport,
with left transitioning alongside the sidebar open/close animation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant