main
269
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5f1f455192 |
fix(docker): auth private hanzoai forks (sqlite, datastore-go) in backend build (#43)
The cmd/community image build 128'd on git ls-remote https://github.com/hanzoai/sqlite (could not read Username — terminal prompts disabled) — red on every main push since ~2026-07-13. Root cause: the sqlite + datastore-go driver swap added PRIVATE hanzoai/* deps, but the Dockerfile assumed all hanzoai forks are public and mounted no git token. Mirror the base/cloud pattern: mount a gh_token build secret (docker.yaml passes secrets.GH_PAT) and git url.insteadOf before go build. Unblocks the first post-rebrand (o11y_traces) backend image. Co-authored-by: Hanzo AI <ai@hanzo.ai> |
||
|
|
a132573506 |
chore(deps): reconcile go.mod with the pinned cloud sibling — unbreak CI (#38)
CI's `go build ./...` has failed on every commit for weeks with "updates to
go.mod needed; to update it: go mod tidy".
Root cause is a broken pairing, not rot. go.mod pins
`replace github.com/hanzoai/cloud => ../cloud`, and ci.yaml supplies that
sibling at an exact commit — deliberately, because cloud's main drifts
independently and would break the readonly graph. That makes go.mod and the
ci.yaml ref ONE fact expressed in two places, and they fell out of step: the
pinned commit (884bdebd) predates the collector fork, still carrying
SigNoz/signoz-otel-collector v0.144.2, zip v1.2.0 and ai v1.789.1, while
go.mod was moved forward toward current cloud (
|
||
|
|
09e675d385 |
ci: run linux jobs on hanzo-build-linux-amd64 ARC scale set (no GitHub-hosted builders)
Claude-Session: https://claude.ai/code/session_01RFrWpXc1BsqfrFYMbyDusJ |
||
|
|
fe4bfd3cf4 |
debrand: SigNoz -> O11y across the tree (+ otel-collector v0.144.7, schema cutover migration) (#28)
* debrand: signoz/SigNoz/SIGNOZ -> o11y/O11y/O11Y across the tree Rename all SigNoz *branding* to O11y in file contents, file/dir names, package names, env vars, config keys, comments, docs, SDK code, and the ClickHouse schema identifiers the querier reads. Collector dependency: - Repoint github.com/hanzoai/signoz-otel-collector -> github.com/hanzoai/otel-collector and bump v0.144.6 -> v0.144.7 (go.mod + go.sum reconciled via go mod tidy). Internal package paths also debranded upstream: signozschemamigrator -> o11yschemamigrator, signozlogspipelineprocessor -> o11ylogspipelineprocessor. - Fix: v0.144.7 dropped otelconst.DistributedFieldKeysTable from the collector's public constants; pin FieldKeysTable = "distributed_field_keys" locally in pkg/telemetrymetadata/tables.go. Package/dir renames (package decl + all importers): pkg/apiserver/signozapiserver -> o11yapiserver, plus signozalertmanager, signozauthzapi, signozglobal, signozquerier, signozruler, and pkg/signoz -> pkg/o11y. Schema (read plane): signoz_traces/metrics/logs/metadata/analytics/meter and signoz_index_v3/index_v2/error_index_v2/spans (+ distributed_*) -> o11y_*. Data-preserving cutover migration added: deploy/clickhouse/migrations/0001_rename_signoz_to_o11y.sql (metadata-only RENAME DATABASE/TABLE, no drop/recreate). Preserved (attribution / external / wire contracts): - LICENSE + NOTICE verbatim (incl. "software from SigNoz", "Copyright ... SigNoz Inc."). - Upstream github.com/SigNoz/* repo URLs + @SigNoz/* CODEOWNERS teams. - Billing resource-attribute regex "signoz.workspace.*" (external wire contract). go build ./pkg/... ./cmd/... = 0; gofmt clean; renamed+schema pkg tests pass. * o11y: bump collector to v0.144.8 (o11y_* physical schema writer) + lockstep deploy plan Collector v0.144.8's schema-migrator + exporters now CREATE/WRITE the same o11y_* physical databases/tables the querier reads and the RENAME migration (0001_rename_signoz_to_o11y.sql) targets. Cross-checked byte-identical: writer DB set == migration target DB set (6); writer prefixed-table set == migration target table set (8); o11y querier reads and cloud reads are subsets of that set. Zero table-name mismatches between writer, readers, and migration. Collector go.mod unchanged between v0.144.7 and v0.144.8 (identical go.mod hash) — pure source rename, no module-graph change. Adds deploy/clickhouse/DEPLOY_signoz_to_o11y_cutover.md: the lockstep order (collector v0.144.8 -> RENAME migration -> o11y+cloud readers) with a fresh/scratch-ClickHouse pre-flight (create via migrator, emit trace+metric, query back) and rollback. Ships together or telemetry blackholes. go build ./pkg/... ./cmd/community = 0. |
||
|
|
e910b25272 |
build(site): o11y-site SPA image via hanzoai/static (edge, no nginx)
The server image is headless (O11Y_WEB_ENABLED=false, /api only); this serves the dashboard SPA at the edge so o11y.hanzo.ai/ stays 200 with the newer backend. - Dockerfile.site: re-serves the proven in-production SPA (0.1.0 /etc/o11y/web) through hanzoai/static --spa (:3000), byte-identical — same pattern commerce-site used while its from-source build was broken. TODO: swap to a from-source node build stage once frontend/ pnpm build is green (mid rolldown-vite migration). - docker-site.yaml: CI build+push ghcr.io/hanzoai/o11y-site on main. |
||
|
|
1c93159031 |
build(docker): buildable o11y server image + CI docker workflow
Fix the root Dockerfile to build the real server binary ./cmd/community (./cmd/server does not exist) into a minimal Alpine runtime, and add a GitHub-hosted workflow that builds + pushes ghcr.io/hanzoai/o11y:<sha> (and :main) on push to main and on v* tags. cmd/community does not import github.com/hanzoai/cloud, so the go.mod replace => ../cloud is inert for the image build and no cloud sibling checkout is needed (unlike the go-build CI job, which compiles mount.go). Every external module in its graph is a public hanzoai/* fork, so no private git auth is required for the container build. Runs headless (SIGNOZ_WEB_ENABLED=false); the SPA is served by hanzoai/static at the edge. |
||
|
|
7de4162f17 |
fix(ci): run release-drafter on ubuntu-latest, not self-hosted
The kept release-drafter workflow still pointed at the unregistered self-hosted runner hanzo-build-linux-amd64, leaving its runs stuck queued. Move it to a GitHub-hosted runner so the only two remaining workflows (ci.yaml, release-drafter.yml) both run GitHub-hosted. |
||
|
|
98e4b74ca5 |
chore(ci): native GitHub-hosted Go CI; drop SigNoz-internal workflows
Replace the SigNoz-internal CI (observe/primus.workflows reusable workflows, .primus make system, self-hosted hanzo-build-linux-amd64 runners, ee/ builds) — all of which startup_failure in hanzoai — with one minimal ubuntu-latest Go CI. ci.yaml: checkout o11y + sibling hanzoai/cloud (satisfies replace => ../cloud), setup-go from go.mod (1.26.4), git auth via GH_PAT for private hanzoai/* deps (commerce, iam, kms, licensing … pulled transitively through cloud), go build ./... as the green gate, go test ./... (skipping one upstream go-smtp-brittle test, TestEmailRejected). Deleted: build-community, build-enterprise, build-ghcr, build-staging, goci, jsci, commitci, e2eci, integrationci, mergequeueci, postci, prereleaser, releaser, gor-observe, gor-signoz-community, gor-histogramquantile, docs, workflow-sanity (its reusable workflow runs on self-hosted runners). Kept release-drafter (public action; runner fixed to ubuntu-latest). |
||
|
|
c0d8a51943 |
fork: own SigNoz platform deps under hanzoai + repath off upstream brand (Phase 1) (#9)
* fork: own SigNoz platform deps under hanzoai, repath imports off upstream brand
Phase 1 of the full-fork mandate: eliminate upstream-branded SigNoz modules,
own them as public hanzoai forks, and repath all imports to hanzoai paths.
Owned deps (new public hanzoai forks, module renamed to hanzoai path):
github.com/SigNoz/signoz-otel-collector v0.144.3
-> github.com/hanzoai/signoz-otel-collector v0.144.6 (module renamed)
github.com/SigNoz/clickhouse-go-mock v0.14.0
-> github.com/hanzoai/clickhouse-go-mock v0.14.1 (module renamed)
github.com/SigNoz/govaluate v0.0.0-20240203125216-988004ccc7fd
-> github.com/hanzoai/govaluate v0.1.0 (module renamed)
github.com/SigNoz/expr (replace target for github.com/expr-lang/expr)
-> github.com/hanzoai/expr v1.17.8 (upstream module path preserved,
consumed via replace exactly like the prior SigNoz/expr fork)
In-repo repath: the vendored SigNoz source tree in pkg/, ee/, cmd/ is now
self-referenced as github.com/hanzoai/o11y/... instead of
github.com/SigNoz/signoz/... (1300+ import lines across 377 files), matching
the 750 files already on the hanzoai path. Zero SigNoz-branded module
references remain in go.mod or any .go import.
Generic ecosystem libraries (golang.org/x, google.golang.org, prometheus,
opentelemetry, gin, cobra, luxfi/*, etc.) are left untouched — only the
SigNoz platform fork is owned.
Pre-existing (NOT introduced here): origin/main does not `go build ./...`
because 22 packages are imported but absent from the vendored tree; 14 of
them (roletypes, grammar, cloudintegrations, resourcefilter, integrationtypes,
metricsexplorer, metrics_explorer, times, agg_rewrite, bucket_cache,
sqlitesqlstore, sqlschema/postgressqlschema, sqlstore/postgressqlstore,
cloudintegrations/services) exist in no upstream SigNoz version and must be
vendored into hanzoai/o11y from hanzoai/signoz@76ee2986 to finish. This
repath is orthogonal to that gap.
* docs(LLM.md): fork boundary map + pre-existing compile-gap inventory
---------
Co-authored-by: Hanzo AI <ai@hanzo.ai>
|
||
|
|
83cd75d4bc | chore(brand): dynamic hero banner | ||
|
|
e4f07525d5 |
ci: run on self-hosted ARC pool (hanzo-build-linux-amd64/deploy), not GitHub-hosted (#7)
Co-authored-by: zeekay <z@hanzo.ai> |
||
|
|
5c72ef49b5 |
merge: upstream/main (sync, brand preserved)
# Conflicts: # .github/workflows/build-community.yaml # .github/workflows/build-enterprise.yaml # .github/workflows/gor-signoz-community.yaml # cmd/community/Dockerfile # cmd/community/Dockerfile.multi-arch # cmd/community/main.go # cmd/community/server.go # cmd/enterprise/Dockerfile # cmd/enterprise/Dockerfile.integration # cmd/enterprise/Dockerfile.with-web.integration # cmd/server/metastore.go # cmd/zap.go # conf/prometheus.yml # deploy/docker-swarm/generator/hotrod/docker-compose.yaml # deploy/docker-swarm/generator/infra/docker-compose.yaml # deploy/docker-swarm/generator/infra/otel-agent-config.yaml # deploy/docker-swarm/generator/infra/otel-metrics-config.yaml # deploy/docker/generator/hotrod/docker-compose.yaml # deploy/docker/generator/infra/docker-compose.yaml # deploy/docker/generator/infra/otel-collector-config.yaml # docs/contributing/go/integration.md # ee/anomaly/hourly.go # ee/anomaly/params.go # ee/anomaly/seasonal.go # ee/authn/callbackauthn/oidccallbackauthn/authn.go # ee/authz/openfgaauthz/provider.go # ee/authz/openfgaschema/base.fga # ee/authz/openfgaserver/server.go # ee/licensing/config.go # ee/licensing/httplicensing/provider.go # ee/modules/dashboard/impldashboard/module.go # ee/querier/handler.go # ee/query-service/anomaly/seasonal.go # ee/query-service/app/api/cloudIntegrations.go # ee/query-service/app/api/featureFlags.go # ee/query-service/app/api/license.go # ee/query-service/app/api/queryrange.go # ee/query-service/rules/anomaly.go # ee/query-service/rules/anomaly_test.go # ee/query-service/rules/manager.go # ee/query-service/rules/manager_test.go # ee/query-service/usage/manager.go # ee/sqlschema/postgressqlschema/provider.go # ee/sqlstore/postgressqlstore/dialect.go # ee/sqlstore/postgressqlstore/provider.go # ee/zeus/config.go # ee/zeus/httpzeus/provider.go # frontend/.eslintrc.cjs # frontend/e2e/test-plan/README.md # frontend/e2e/test-plan/validation-report.md # frontend/e2e/tests/settings/account-settings/account-settings-settings.spec.ts # frontend/e2e/tests/settings/api-keys/api-keys-settings.spec.ts # frontend/playwright.config.ts # frontend/public/Images/signoz-hero-image.webp # frontend/public/Logos/signoz-brand-logo.svg # frontend/scripts/generate-permissions-type.cjs # frontend/src/assets/Images/o11y-hero-image.webp # frontend/src/assets/Images/signoz-hero-image.webp # frontend/src/assets/Logos/hanzo-brand-logo.svg # frontend/src/assets/Logos/hanzo-icon.svg # frontend/src/assets/Logos/o11y-brand-logo.svg # frontend/src/assets/Logos/signoz-brand-logo.svg # frontend/src/assets/SigNoz-dark.svg # frontend/src/assets/SigNoz-white.svg # frontend/src/assets/signoz.svg # frontend/src/components/DetailsDrawer/DetailsDrawer.styles.scss # frontend/src/components/HostMetricsDetail/HostMetricTraces/HostMetricTraces.styles.scss # frontend/src/components/HostMetricsDetail/HostMetricTraces/constants.ts # frontend/src/components/HostMetricsDetail/HostMetricsDetail.styles.scss # frontend/src/components/HostMetricsDetail/HostMetricsDetails.tsx # frontend/src/components/HostMetricsDetail/HostMetricsLogs/NoLogsContainer.tsx # frontend/src/components/HostMetricsDetail/HostMetricsLogs/constants.ts # frontend/src/components/LogsDownloadOptionsMenu/LogsDownloadOptionsMenu.styles.scss # frontend/src/components/WelcomeLeftContainer/index.tsx # frontend/src/container/APIKeys/APIKeys.styles.scss # frontend/src/container/APIKeys/APIKeys.test.tsx # frontend/src/container/APIKeys/APIKeys.tsx # frontend/src/container/CloudIntegrationPage/Header/Header.tsx # frontend/src/container/CloudIntegrationPage/HeroSection/HeroSection.tsx # frontend/src/container/CloudIntegrationPage/HeroSection/components/AccountActions.style.scss # frontend/src/container/CloudIntegrationPage/HeroSection/components/AccountActions.tsx # frontend/src/container/CloudIntegrationPage/HeroSection/components/AccountSettingsModal.style.scss # frontend/src/container/CloudIntegrationPage/HeroSection/components/AccountSettingsModal.tsx # frontend/src/container/CloudIntegrationPage/HeroSection/components/CloudAccountSetupModal.style.scss # frontend/src/container/CloudIntegrationPage/HeroSection/components/RemoveIntegrationAccount.tsx # frontend/src/container/CloudIntegrationPage/ServicesSection/ConfigureServiceModal.tsx # frontend/src/container/CloudIntegrationPage/ServicesSection/ServicesTabs.style.scss # frontend/src/container/CloudIntegrationPage/ServicesSection/ServicesTabs.tsx # frontend/src/container/DashboardContainer/DashboardSettings/General/AddTags/AddTags.styles.scss # frontend/src/container/DashboardContainer/DashboardSettings/General/GeneralSettings.styles.scss # frontend/src/container/FormAlertRules/ChQuerySection/ChQuerySection.tsx # frontend/src/container/FormAlertRules/UserGuide/index.tsx # frontend/src/container/InfraMonitoringHosts/HostsEmptyOrIncorrectMetrics.tsx # frontend/src/container/InfraMonitoringHosts/InfraMonitoring.styles.scss # frontend/src/container/InfraMonitoringHosts/__tests__/HostsEmptyOrIncorrectMetrics.test.tsx # frontend/src/container/InfraMonitoringK8s/Clusters/ClusterDetails/ClusterDetails.tsx # frontend/src/container/InfraMonitoringK8s/Clusters/utils.tsx # frontend/src/container/InfraMonitoringK8s/DaemonSets/DaemonSetDetails/DaemonSetDetails.tsx # frontend/src/container/InfraMonitoringK8s/DaemonSets/utils.tsx # frontend/src/container/InfraMonitoringK8s/Deployments/DeploymentDetails/DeploymentDetails.tsx # frontend/src/container/InfraMonitoringK8s/Deployments/utils.tsx # frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/EntityEvents/entityEvents.styles.scss # frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/EntityTraces/entityTraces.styles.scss # frontend/src/container/InfraMonitoringK8s/InfraMonitoringK8s.styles.scss # frontend/src/container/InfraMonitoringK8s/Jobs/JobDetails/JobDetails.tsx # frontend/src/container/InfraMonitoringK8s/Jobs/utils.tsx # frontend/src/container/InfraMonitoringK8s/K8sEmptyOrIncorrectMetrics.tsx # frontend/src/container/InfraMonitoringK8s/K8sFiltersSidePanel/K8sFiltersSidePanel.styles.scss # frontend/src/container/InfraMonitoringK8s/Namespaces/NamespaceDetails/NamespaceDetails.styles.scss # frontend/src/container/InfraMonitoringK8s/Namespaces/NamespaceDetails/NamespaceDetails.tsx # frontend/src/container/InfraMonitoringK8s/Namespaces/utils.tsx # frontend/src/container/InfraMonitoringK8s/Nodes/NodeDetails/NodeDetails.tsx # frontend/src/container/InfraMonitoringK8s/Nodes/utils.tsx # frontend/src/container/InfraMonitoringK8s/Pods/PodDetails/PodDetails.tsx # frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/StatefulSetDetails.tsx # frontend/src/container/InfraMonitoringK8s/StatefulSets/utils.tsx # frontend/src/container/InfraMonitoringK8s/Volumes/VolumeDetails/VolumeDetails.tsx # frontend/src/container/InfraMonitoringK8s/Volumes/utils.tsx # frontend/src/container/ListAlertRules/AlertsEmptyState/AlertsEmptyState.styles.scss # frontend/src/container/ListAlertRules/ListAlert.tsx # frontend/src/container/LogsContextList/styles.ts # frontend/src/container/LogsExplorerList/ColumnView/ColumnView.tsx # frontend/src/container/LogsExplorerViews/QueryStatus.tsx # frontend/src/container/MetricsApplication/Tabs/Overview/ApDex/ApDexTraces.tsx # frontend/src/container/MetricsExplorer/Explorer/RelatedMetrics.tsx # frontend/src/container/MetricsExplorer/Explorer/useGetRelatedMetricsGraphs.ts # frontend/src/container/MetricsExplorer/Summary/MetricTypeSearch.tsx # frontend/src/container/NewWidget/LeftContainer/QuerySection/QueryBuilder/ClickHouse/index.tsx # frontend/src/container/NewWidget/LeftContainer/QuerySection/QueryBuilder/ClickHouse/query.tsx # frontend/src/container/NewWidget/LeftContainer/QuerySection/QueryBuilder/clickHouse/index.tsx # frontend/src/container/NewWidget/LeftContainer/QuerySection/QueryBuilder/clickHouse/query.tsx # frontend/src/container/NewWidget/LeftContainer/QuerySection/QueryBuilder/datastore/index.tsx # frontend/src/container/NewWidget/LeftContainer/QuerySection/QueryBuilder/datastore/query.tsx # frontend/src/container/OnboardingQuestionaire/OnboardingFooter/OnboardingFooter.tsx # frontend/src/container/OnboardingQuestionaire/OnboardingHeader/OnboardingHeader.styles.scss # frontend/src/container/OnboardingQuestionaire/OnboardingHeader/OnboardingHeader.tsx # frontend/src/container/OnboardingV2Container/onboarding-configs/onboarding-config-with-links.json # frontend/src/container/QueryBuilder/QueryBuilder.tsx # frontend/src/container/QueryBuilder/components/Query/Query.tsx # frontend/src/container/RolesSettings/__tests__/utils.test.ts # frontend/src/container/ServiceTable/SkipOnBoardModal/index.tsx # frontend/src/container/TraceDetail/Missingtrace.tsx # frontend/src/container/TraceDetail/SelectedSpanDetails/config.ts # frontend/src/lib/uPlotV2/components/Tooltip/Tooltip.styles.scss # frontend/src/mocks-server/__mockdata__/apiKeys.ts # frontend/src/pages/AlertDetails/AlertHeader/AlertStatus/AlertStatus.tsx # frontend/src/pages/Integrations/IntegrationDetailPage/IntegrationDetailPage.styles.scss # frontend/src/pages/Integrations/IntegrationDetailPage/IntegrationDetailPage.tsx # frontend/src/pages/Integrations/IntegrationsList.tsx # frontend/src/pages/Integrations/utils.ts # frontend/src/types/api/integrations/aws.ts # pkg/alertmanager/o11yalertmanager/handler.go # pkg/apiserver/o11yapiserver/alertmanager.go # pkg/apiserver/o11yapiserver/cloudintegration.go # pkg/apiserver/o11yapiserver/inframonitoring.go # pkg/apiserver/o11yapiserver/llmpricingrule.go # pkg/apiserver/o11yapiserver/rawdataexport.go # pkg/apiserver/o11yapiserver/registry.go # pkg/apiserver/o11yapiserver/ruler.go # pkg/apiserver/o11yapiserver/ruler_examples.go # pkg/apiserver/o11yapiserver/ruler_examples_test.go # pkg/apiserver/o11yapiserver/rulestatehistory.go # pkg/apiserver/o11yapiserver/spanmapper.go # pkg/apiserver/o11yapiserver/tracedetail.go # pkg/authn/callbackauthn/googlecallbackauthn/authn.go # pkg/authz/openfgaauthz/provider.go # pkg/authz/openfgaschema/base.fga # pkg/authz/openfgaserver/server.go # pkg/authz/openfgaserver/server_test.go # pkg/authz/openfgaserver/sqlstore.go # pkg/http/middleware/api_key.go # pkg/http/middleware/authn.go # pkg/instrumentation/metric.go # pkg/modules/user/impluser/module.go # pkg/prometheus/clickhouseprometheus/client.go # pkg/prometheus/clickhouseprometheus/client_query_test.go # pkg/prometheus/clickhouseprometheus/provider.go # pkg/prometheus/config.go # pkg/prometheus/engine.go # pkg/prometheus/label.go # pkg/prometheus/prometheus.go # pkg/prometheus/prometheustest/provider.go # pkg/prometheus/prometheustest/utils_test.go # pkg/querier/promql_query.go # pkg/query-service/app/cloudintegrations/Readme.md # pkg/query-service/app/cloudintegrations/accountsRepo.go # pkg/query-service/app/cloudintegrations/constants.go # pkg/query-service/app/cloudintegrations/controller.go # pkg/query-service/app/cloudintegrations/models.go # pkg/query-service/app/cloudintegrations/serviceconfig_db.go # pkg/query-service/app/cloudintegrations/services/definitions/aws/eks/assets/dashboards/containerinsights.json # pkg/query-service/app/cloudintegrations/services/definitions/aws/eks/assets/dashboards/containerinsights_dot.json # pkg/query-service/app/cloudintegrations/services/definitions/aws/eks/assets/dashboards/overview.json # pkg/query-service/app/cloudintegrations/services/definitions/aws/eks/assets/dashboards/overview_dot.json # pkg/query-service/app/cloudintegrations/services/models.go # pkg/query-service/app/cloudintegrations/services/services.go # pkg/query-service/app/cloudintegrations/services/services_test.go # pkg/query-service/app/integrations/builtin_integrations/clickhouse/assets/dashboards/overview_dot.json # pkg/query-service/app/integrations/builtin_integrations/datastore/assets/dashboards/overview_dot.json # pkg/query-service/app/metricsexplorer/parser.go # pkg/query-service/app/metricsexplorer/summary.go # pkg/query-service/app/querier/querier_test.go # pkg/query-service/app/querier/v2/querier_test.go # pkg/query-service/app/summary.go # pkg/query-service/model/metrics_explorer/summary.go # pkg/query-service/rules/base_rule_test.go # pkg/query-service/rules/manager_test.go # pkg/query-service/rules/prom_rule.go # pkg/query-service/rules/prom_rule_task.go # pkg/query-service/rules/prom_rule_test.go # pkg/query-service/rules/threshold_rule_test.go # pkg/querybuilder/resourcefilter/tables.go # pkg/queryparser/queryfilterextractor/promql.go # pkg/ruler/o11yruler/handler.go # pkg/sqlmigration/088_migrate_ii_dashboards/clickhouse/overview.json # pkg/telemetrymetadata/metadata_test.go # pkg/telemetrystore/datastoretelemetrystore/telemetry.go # pkg/types/authtypes/name.go # pkg/types/authtypes/object.go # pkg/types/authtypes/selector.go # pkg/types/authtypes/typeable.go # pkg/types/authtypes/typeable_anonymous.go # pkg/types/authtypes/typeable_metaresource.go # pkg/types/authtypes/typeable_metaresources.go # pkg/types/authtypes/typeable_organization.go # pkg/types/authtypes/typeable_role.go # pkg/types/authtypes/typeable_user.go # pkg/types/authtypes/uuid.go # pkg/types/ctxtypes/auth.go # pkg/types/factor_api_key.go # pkg/types/integrationtypes/integration.go # pkg/types/roletypes/store.go # pkg/types/ruletypes/maintenance.go # pkg/types/serviceaccounttypes/service_account_role.go # pkg/types/serviceaccounttypes/store.go |
||
|
|
a4d3f10da8 | chore(codeowners): add pulse for alerts and infra monitoring pages (#11508) | ||
|
|
9f561c87db |
merge: feat/cloud-mount
# Conflicts: # .github/workflows/build-ghcr.yaml # authn.go # cmd/enterprise/server.go # ee/query-service/app/api/api.go # ee/query-service/app/server.go # go.mod # pkg/query-service/rules/managertestfactory.go |
||
|
|
d485b4edaa |
merge: ci/shared-docker-workflow
# Conflicts: # .github/workflows/build-ghcr.yaml |
||
|
|
b568f3e5cb | chore(ci): remove unused frontend build variables (#11504) | ||
|
|
d1f143f675 |
feat(web): add support for generating web settings types (#11445)
* feat(web): add support for generating settings type * feat(web): add support for generating settings type * feat(web): add support for generating settings type * refactor: rename generate settings to generate config web-settings - Rename cmd/settings.go to cmd/genconfig.go - Restructure command as `generate config web-settings` - Move schema output to docs/config/web-settings.json - Update frontend script to generate:config:web-settings - Update CI checks to match new command names - Strip Web prefix from generated JSON Schema definitions |
||
|
|
c3db819d8e |
chore: update code owners for dashboard v2 and e2e (#11412)
* chore: update code owners for dashboard and e2e * chore: update code owners order |
||
|
|
99a577786f |
ci: amd64 only + id-token write
DOKS has no arm64 droplets (hanzo-build-linux-arm64 ARC paused). Default shared workflow builds both arches and arm64 queues forever (24h timeout). Caller permissions are also the ceiling for reusable workflow — without id-token: write at top level dispatch dies as startup_failure. |
||
|
|
c86df3adcb |
feat(pnpm): migrate away from yarn (#11158)
* feat(pnpm): migrate away from yarn * fix(lodash): using uninstall dependency * fix(workflows): use pnpm as package manager * fix(pnpm-lock): keep it updated * fix(test): issue with lodash-es and our pnpm store * fix(jest): more esm conflicts * fix(pipeline-page): update snapshot test * fix(pnpm-lock): out of sync * fix(json-view): issue with typing * chore(pnpm): upgrade pnpm * chore(yarn): remove yarn |
||
|
|
0aaf556137 | Update CODEOWNERS (#11192) | ||
|
|
3d8cddf84e |
refactor: split typeable infrastructure into pkg/types/coretypes (#11105)
* refactor: move authtypes to coretypes
* refactor: migrate downstream consumers to coretypes Kind/Type/Relation
Wire all consumers of the typeable infrastructure through coretypes:
- Replace authtypes.Name/Type/Relation references with coretypes equivalents
- Switch Typeable singletons to constructor calls (authtypes.NewTypeableUser
etc.), with the embedded coretypes.Typeable populated so Kind/Type/Prefix/
Scope dispatch correctly through the embed
- Update dashboardtypes meta-resource declarations to use authtypes
constructors so they expose Tuples (authz callers need it)
- Rename Resource.Name field accesses to Resource.Kind to match the field
rename in authtypes.Resource
- Fix typeable_metaresource.go calling the plural NewTypeableMetaResources
helper — should be the singular NewTypeableMetaResource
go build ./... and go vet ./... clean (parser-generated unreachable-code
warnings are pre-existing). Authz unit tests pass.
* refactor(audittypes): unify Action with coretypes.Relation
Drop the duplicate Action enum from audittypes — the verbs (create/update/
delete) match coretypes.Relation exactly. Move PastTense onto Relation so
audit EventName derivation continues to work without a parallel hierarchy.
Also retypes AuditDef.ResourceKind from string to coretypes.Kind so audit
declarations get the same regex validation that authz already enforces.
* refactor(retentiontypes): extract TTLSetting into its own package
TTLSetting is the bun model for ClickHouse TTL settings — has nothing to do
with the Organization domain it was previously co-located with in
pkg/types/organization.go. Moved to pkg/types/retentiontypes/ alongside the
ClickHouse reader that's its sole consumer.
No schema change; the bun table tag (table:ttl_setting) is unchanged.
* chore(openapi): regenerate spec for coretypes.Relation and Resource.Kind
* chore(frontend): regenerate API client and migrate Resource.name → Resource.kind
Regenerated TypeScript API types after the AuthtypesResource field rename
and the new CoretypesRelation enum. Updated:
- frontend/scripts/generate-permissions-type.cjs to read `r.kind` from the
/api/v1/authz/resources response and emit `kind:` in the static
permissions.type.ts file.
- frontend/src/hooks/useAuthZ/{permissions.type,types,utils,useAuthZ}.tsx:
Resource.name → Resource.kind throughout.
- frontend/src/container/RolesSettings/{utils.tsx,__tests__/utils.test.ts}:
same field migration.
- frontend/src/components/createGuardedRoute/createGuardedRoute.test.tsx:
same.
- useAuthZ/utils.ts: cast string relations to CoretypesRelationDTO at the
AuthtypesTransactionDTO boundary now that relation is an enum, not a raw
string.
yarn generate:api passes (orval generation + lint + typecheck).
* refactor: migrate downstream consumers to Resource/Verb rename
* chore(openapi): regenerate spec for Resource/Verb rename
* feat(coretypes): add ListResources accessor with stable sort
* feat(cmd): add 'generate authz' subcommand for permissions type
* refactor(authz): drop runtime authz/resources endpoint
* refactor(frontend): consume static permissions.type.ts directly
* chore(frontend): regenerate Orval client without authz/resources
* ci: move authz schema check from jsci to goci
* refactor(coretypes): move Selector/Object/Transaction from authtypes
* feat(coretypes): add managed role names and permission policy
* feat(coretypes): add Registry assembling resources, types, and managed-role transactions
* refactor(authz): wire *coretypes.Registry; drop RegisterTypeable
* refactor(cmd): wire coretypes.NewRegistry into server bootstraps
* chore: regenerate openapi spec for authtypes -> coretypes type moves
* chore(frontend): regenerate API client for Authtypes -> Coretypes type moves
* refactor(coretypes): rename GettableResource to ResourceRef
* refactor(authz): collapse Registry around static data; bridge once at construction
* refactor(coretypes): tighten Registry, restore anonymous public-dashboard grant
Drops passthrough fields from coretypes.Registry; adds an O(1) lookup map
for NewResourceFromTypeAndKind; replaces stringly-typed Type compares with
Type.Equals; removes the now-redundant getUniqueTypes helper. Restores the
signoz-anonymous read grant on metaresource/public-dashboard that was
silently dropped, and removes the invalid signoz-admin/VerbCreate/TypeUser
entry that panicked at startup.
* chore: regenerate openapi spec for coretypes -> authtypes type moves
* chore(frontend): regenerate API client for Coretypes -> Authtypes type moves
* fix(authz): disambiguate kind→type by relation, preserve multi-part selectors
permissions.type.ts now lists the same kind (dashboard, role,
public-dashboard) under both metaresource and metaresources, so the prior
kind→type map silently overwrote one with the other. Resolve the type
using the requesting relation's allowed types, and slice the selector at
the first colon so multi-part selectors (e.g. id:version) round-trip
correctly. Updates useAuthZ.test.tsx to use the regenerated kind field.
* refactor(authtypes): introduce Relation wrapper over coretypes.Verb
The authz layer modeled relations as raw coretypes.Verb everywhere, which
forced authz-level concepts (action, role-binding) to share a type with
schema-level enumerations. Introduce authtypes.Relation as a thin wrapper
over coretypes.Verb so the authz APIs (CheckWithTupleCreation, ListObjects,
GetObjects, PatchObjects, NewTuples, Transaction.Relation, etc.) can grow
authz-specific affordances without leaking back into coretypes.
Also reshuffles the static coretypes data into dedicated registry_*.go files
(types, kinds, verbs, resources, managed roles) to keep the schema declarations
isolated from the value types they configure.
* refactor(authtypes): expose Relation.Enum() and regenerate openapi spec
Without an Enum() method on Relation the openapi generator emitted an
empty AuthtypesRelation schema (no allowed values). Forward the enum
from the embedded coretypes.Verb so the wire contract is faithful.
* refactor(ee/authz): drop always-nil error returns from managed-role tuple helpers
getManagedRoleGrantTuples and getManagedRoleTransactionTuples never
returned a non-nil error, which the linter (unparam) had flagged. Drop
the unused error return; callers no longer need the err check either.
* chore(frontend): regenerate API client for authtypes.Relation
* fix(authz): satisfy go-lint — keyed Relation literal, drop redundant Verb selector
* refactor(coretypes): sync Kinds slice with full registry_kind declarations
* feat(coretypes): register metaresource and metaresources for all new kinds
Adds 21 metaresource and 21 metaresources entries (covering notification-channel,
route-policy, apdex-setting, auth-domain, session, cloud-integration,
cloud-integration-service, ingestion-key, ingestion-limit, pipeline,
user-preference, org-preference, quick-filter, ttl-setting, rule,
planned-maintenance, saved-view, trace-funnel, factor-password, factor-api-key,
license) so the authz schema covers every resource Kind declared in
registry_kind. Regenerates the static frontend permissions.type.ts to match.
* feat(coretypes): populate ManagedRoleToTransactions from signozapiserver routes
Enumerates every (verb, resource) tuple each managed role holds, derived
from the AdminAccess/EditAccess/ViewAccess middleware on routes in
pkg/apiserver/signozapiserver and the legacy http_handler in
pkg/query-service/app. Admin gets 123 transactions, editor 53, viewer 25,
anonymous keeps the single public-dashboard read.
* feat(coretypes): add integration kind with full CRUD for viewer/editor/admin
Install/uninstall/list integration routes (legacy /api/v1/integrations) all
sit behind ViewAccess, so every authenticated role gets the full CRUD
surface on (metaresource, integration) and (metaresources, integration).
Regenerates the static frontend permissions.type.ts to match.
* feat(coretypes): add subscription kind alongside license, document LCRUD shape
License covers the in-product license resource (Activate/Refresh/GetActive).
Subscription is the billing lifecycle (checkout/portal/billing) served by
ee/query-service routes. Both are admin-only and modeled with a uniform
LCRUD shape; comments call out which verbs actually map to routes versus
which are placeholders for shape parity (e.g. cancellation flows through
Stripe's portal, not an in-process delete).
* feat(coretypes): model telemetryresource for logs, traces, metrics
Mirrors the telemetryresource type from ee/authz/openfgaschema/base.fga
into coretypes: a read-only Type with three Kinds (logs, traces, metrics)
matching telemetrytypes.Signal. Selector is wildcard-only for v1; future
work can narrow per-service or per-environment when the use case lands.
Every managed role (admin/editor/viewer) gets read on each signal,
matching the schema's role#assignee grant. Anonymous stays unchanged.
Regenerates the static frontend permissions.type.ts.
* feat(coretypes): add audit-logs and meter-metrics kinds under telemetryresource
Audit logs (signal=logs, source=audit) and meter metrics (signal=metrics,
source=meter) are sensitive source-qualified telemetry streams that don't
belong under the broad read-grant every role gets on regular logs/traces/
metrics. Modeled as distinct Kinds so they can be permissioned
independently. Admin-only read for now; widen on explicit ask (e.g. an
auditor flow that needs viewer access to audit-logs). Regenerates the
static frontend permissions.type.ts.
* feat(coretypes): add logs-field and traces-field kinds for stored field config
GET/POST /logs/fields and /api/v2/traces/fields manage stored, mutable
field metadata (indexed/promoted columns) over each signal. They're
configuration, not telemetry data, so they sit under metaresource rather
than telemetryresource. Viewer reads, editor/admin update; no
create/delete since POST overwrites. Plural prefix (logs-field /
traces-field) matches the signal naming.
* chore(frontend): regenerate permissions.type.ts to match generate authz output
* feat(authz): add attach permissions to fga model
* fix(tests): use role permissions instead of dashboards
* fix(authz): couple of issues with register flow
* fix(authz): public dashboard read should be anomymous
* fix(tests): integration test for public dashboard access
---------
Co-authored-by: vikrantgupta25 <vikrant@signoz.io>
|
||
|
|
3f95d35ad5 |
chore: add @therealpandey with @srikanthcvv (#11126)
#### Temporary - add @therealpandey with @srikanthcvv |
||
|
|
9e5678d6b3 |
CI: JSON QB E2E Integration Suite (#10863)
* feat: enable JSON Path index * fix: contextual path index usage * test: fix unit tests * feat: align negative operators to include other logs * fix: primitive conditions working * fix: indexed tests passing * fix: array type filtering from dynamic arrays * fix: unit tests * fix: remove not used paths from testdata * fix: unit tests * fix: comment * fix: indexed unit tests * fix: array json element comparison * feat: change filtering of dynamic arrays * fix: dynamic array tests * fix: stringified integer value input * fix: better review for test file * fix: negative operator check * ci: lint changes * chore: import tests from older pr * fix: better tests * fix: logs.py * fix: body tests ready * fix: better validations * fix: dynamically change insert stmt for body_v2 availability * test: with higher migrator version * fix: type ambiguity * fix: test * test: updated validation * fix: tons of changes * chore: remove redundent comparison * ci: tests fixed * fix: upgraded collector version * fix: qbtoexpr tests * fix: go sum * chore: upgrade collector version v0.144.3-rc.4 * fix: tests * ci: test fix * revert: remove db binaries * test: selectField tests added * fix: added safeguards in plan generation * fix: name changed to field_map * chore: changes based on review * fix: changes based on review * fix: remove unused promoted fixture * test: integration test fix attempt 1 * fix: json access plan remval of AvailableTypes * fix: invalid index usage on terminal condition * test: added indexed tests separately * test: select order by tests added * fix: update jsontypeexporter * fix: branches should tell missing array types * fix: comment removed * ci: test with updated collector * fix: issue with FuzzyMatching and API failing * test: select orderby works * fix: int64 mapping * fix: replacing JSONIndex with TelemetryFieldKeyIndex * chore: update collector to stable release * chore: update migrator version to stable release * chore: error fix and unused code * chore: go mod tidy * chore: some changes in test to improve quality * test: enhanced tests to work with backtick required key * chore: comment removal * fix: change based on review * fix: change based on review * fix: openapi ci * ci: fix go tests * fix: index needs body prefix * fix: tests * ci: polluted test fix * fix: shift test files * refactor(telemetrytypes): replace JSONDataTypeIndex with TelemetryFieldKeySkipIndex * revert: mcp related changes * feat: check query log as fixture * fix: reuse querier fixtures * chore: rename jsontypeexporter.py * chore: py-fmt * fix: minor fix * fix: py-lint * fix: changes based on review * chore: fmt |
||
|
|
17a4c164d4 |
ci: canonical docker-build (#2)
* feat: add /v1/o11y/* rewrite middleware for standard API path convention Add URL rewrite middleware that intercepts /v1/o11y/* requests and rewrites them to /api/* internally, allowing external clients to use the /<version>/<service>/<path> convention while keeping all existing internal route registrations unchanged. * chore: sync latest * ci: migrate to canonical hanzoai/.github/docker-build.yml reusable |
||
|
|
44130eb718 | ci: migrate to canonical hanzoai/.github/docker-build.yml reusable | ||
|
|
f62024ad3f |
chore: modern fmts and lints for tests/ (#11074)
* chore(frontend): remove stale e2e scaffold frontend/e2e/ held an unused settings-only test-plan scaffold from Oct 2025. Active Playwright specs live at tests/e2e/. Drop the directory, the orphan playwright.config.ts, the @playwright/test dependency, and the tsconfig references that pinned them. * chore(e2e): migrate formatter from prettier to oxfmt Swap tests/e2e/ onto oxfmt — same tool the frontend adopted in #11057. Style matches frontend/.oxfmtrc.json (tabs, tabWidth:1) so the two TS trees stay visually consistent. Drops .prettierrc.json and .prettierignore, adds the fmt/fmt:check yarn scripts, and reformats the existing specs. * chore(e2e): migrate linter from eslint to oxlint Drop eslint + @typescript-eslint plugins in favour of oxlint 1.59 + tsgolint — same toolchain the frontend adopted in #10176. The .oxlintrc.json mirrors frontend/.oxlintrc.json with plugins scoped to a Playwright TS codebase (eslint, typescript, unicorn, import, promise). Divergence: eslint-plugin-playwright is not ported. Its rules depend on ESLint APIs (context.getAncestors) that oxlint's JS plugin shim does not implement, so the five playwright/* rules are dropped in this migration. * ci(e2e): add fmtlint job Mirror integrationci.yaml's fmtlint job for e2e. Runs oxfmt --check and oxlint on tests/e2e/ under the same safe-to-e2e label gating as the existing test job. * chore(integration): migrate python tooling from black/pylint/isort/autoflake to ruff Replace the four-tool stack with ruff — same motivation as the oxfmt/oxlint swap on the TS side. One tool covers formatting (ruff format), import sorting (I), unused-import/variable cleanup (F401/F841), and the pylint rules we actually care about (E/W/F/UP/B/PL). Rule set mirrors the intent of the prior pylint config: too-many-* checks and magic-value-comparison stay disabled, dangerous-default-value (now B006) stays muted. A handful of newly-surfaced codes (B011/B024/B905/E741/ UP047/PLC0206/PLW2901) are also muted to keep this a pure tool swap — each deserves its own review before enabling. Divergence: ruff caps line-length at 320, so the prior pylint value of 400 drops to 320. Nothing in tree exceeds 320, so no lines wrap. No changes to integrationci.yaml — both fmt/lint steps still call make py-fmt / make py-lint, which now dispatch to ruff. * chore(e2e): restore playwright lint rules via oxlint jsPlugin eslint-plugin-playwright@2.x was rewritten against ESLint 8's context.sourceCode.getAncestors() API, which oxlint's JS plugin shim exposes. The 0.16.x version previously ruled out by context.getAncestors() missing is no longer a blocker. Bump to 2.10.2, re-add it as a jsPlugin, and restore the five rules dropped in the initial oxlint migration: expect-expect, no-conditional-in-test, no-page-pause, no-wait-for-timeout, prefer-web-first-assertions. Rule count: 104 → 109. * chore(frontend): remove stale e2e prompt frontend/prompts/generate-e2e-test.md is leftover from the same Oct 2025 scaffold removed in ebf735dcc. It references frontend/e2e/utils/login.util.ts, which no longer exists, and is not wired into anything. * chore(e2e): make .env.local write layout explicit The single f-string with inline \n escapes read as a wall of text after ruff's line-length allowance collapsed it onto one line. Switch to a triple-quoted f-string so the generated .env.local structure is visible in source. Byte-for-byte identical output. * chore(e2e): write .env.local one key per line Open the file with a context manager and emit each key with its own f.write call. Same output as before, but each key-value pair is a discrete statement. |
||
|
|
93f5df9185 |
tests: unify integration + e2e under shared pytest project (#11019)
* refactor(tests): hoist pytest project to tests/ root for shared fixtures
Lift pyproject.toml, uv.lock, conftest.py, and fixtures/ up from
tests/integration/ so the pytest project becomes shared infrastructure
rather than integration's private property. A sibling tests/e2e/ can
reuse the same fixture graph (containers, auth, seeding) without
duplicating plugins.
Also:
- Merge tests/integration/src/querier/util.py into tests/fixtures/querier.py
(response assertions and corrupt-metadata generators belong with the
other querier helpers).
- Use --import-mode=importlib + pythonpath=["."] in pyproject so
same-basename tests across src/*/ do not collide at the now-wider
rootdir.
- Broaden python_files to "*/src/**/**.py" so future test trees under
tests/e2e/src/ get discovered.
- Update Makefile py-* targets and integrationci.yaml to cd into tests/
and reference integration/src/... paths.
* feat(tests/e2e): import Playwright suite from signoz-e2e
Relocate the standalone signoz-e2e repository into tests/e2e/ as a
sibling of tests/integration/. The suite still points at remote
staging by default; subsequent commits wire it to the shared pytest
fixture graph so the backend can be provisioned locally.
Excluded from the import: .git, .github (CI migration deferred),
.auth, node_modules, test-results, playwright-report.
* feat(tests/e2e): pytest-driven backend bring-up, seeding, and playwright runner
Wire the Playwright suite into the shared pytest fixture graph so the
backend + its seeded state are provisioned locally instead of pointing
at remote staging.
Python side (owns lifecycle):
- tests/fixtures/dashboards.py — generic create/list/upsert_dashboard
helpers (shared infra; testdata stays per-tree).
- tests/e2e/conftest.py — e2e-scoped pytest fixtures: seed_dashboards
(idempotent upsert from tests/e2e/testdata/dashboards/*.json),
seed_alert_rules (from tests/e2e/testdata/alerts/*.json, via existing
create_alert_rule), seed_e2e_telemetry (fresh traces/logs across a
few synthetic services so /home and Services pages have data).
- tests/e2e/src/bootstrap/setup.py — test_setup depends on the fixture
graph and persists backend coordinates to tests/e2e/.signoz-backend.json;
test_teardown is the --teardown target.
- tests/e2e/src/bootstrap/run.py — test_e2e: one-command entrypoint that
brings up the backend + seeds, then subprocesses yarn test and asserts
Playwright exits 0.
- tests/conftest.py — register fixtures.dashboards plugin.
Playwright side (just reads):
- tests/e2e/global.setup.ts — loads .signoz-backend.json and injects
SIGNOZ_E2E_BASE_URL/USERNAME/PASSWORD. No-op when env is already
populated (staging mode, or pytest-driven runs where env is pre-set).
- playwright.config.ts registers globalSetup.
- package.json gains test:staging; existing scripts unchanged.
Testdata layout: tests/e2e/testdata/{dashboards,alerts,channels}/*.json
— per-tree (integration has its own tests/integration/testdata/).
* docs(tests): describe pytest-master workflow and shared fixture layout
- tests/README.md (new): top-level map of the shared pytest project,
fixture-ownership rule (shared vs per-tree), and common commands.
- tests/e2e/README.md: lead with the one-command pytest run and the
warm-backend dev loop; keep the staging fallback as option 2.
- tests/e2e/CLAUDE.md: updated commands so agent contexts reflect the
pytest-driven lifecycle.
- tests/e2e/.env.example: drop unused SIGNOZ_E2E_ENV_TYPE; note the file
is only needed for staging mode.
* fix(tests/fixtures/signoz.py): anchor Docker build context to repo root
Previously used path="../../" which resolved to the repo root only when
pytest's cwd was tests/integration/. After hoisting the pytest project
to tests/, that same relative path pointed one level above the repo
root and the build failed with:
Cannot locate specified Dockerfile: cmd/enterprise/Dockerfile.with-web.integration
Anchor the build context to an absolute path computed from __file__ so
the fixture works regardless of pytest cwd.
* feat(tests/e2e): alerts-downtime regression suite (platform-pod/issues/2095)
Import the 34-step regression suite originally developed on
platform-pod/issues/2095-frontend. Targets the alerts and planned-downtime
frontend flows after their migration to generated OpenAPI clients and
generated react-query hooks.
- specs/alerts-downtime/: SUITE.md (the stable spec), README.md (scope +
open observations from the original runs), results-schema.md (legacy
per-run artifact shape, retained for context).
- tests/alerts-downtime/alerts-downtime.spec.ts: 881-line Playwright spec
covering 6 flows — alert CRUD/toggle, alert detail 404, planned
downtime CRUD, notification channel routing, anomaly alerts.
Integration with the shared suite:
- Uses baseURL + storageState from tests/e2e/playwright.config.ts (no
separate config). page.goto calls use relative paths; SIGNOZ_E2E_*
env vars from the pytest bootstrap drive auth.
- test.describe.configure({ mode: 'serial' }) at the top of the describe:
the flows mutate shared tenant state, so parallel runs cause cross-
flow interference (documented in the original 2095 config).
- Per-run artifacts (network captures + screenshots) land in
tests/e2e/tests/alerts-downtime/run-spec-<ts>/ by default — gitignored.
Historical per-run artifacts (~7.5MB of screenshots across run-1 through
run-7) are not imported; they lived at e2e/2095/run-*/ on the original
branch and remain there if needed.
* refactor(fixtures/traces): extract insert + truncate helpers
Pull the ClickHouse insert path out of the insert_traces pytest fixture
into a plain module-level function insert_traces_to_clickhouse(conn,
traces), and move the per-table TRUNCATE loop into truncate_traces_tables
(conn, cluster). The fixture becomes a thin wrapper over both — zero
behavioural change.
Lets the HTTP seeder container (tests/fixtures/seeder/) reuse the exact
same insert + truncate code the pytest fixture uses, so the two stay in
sync as the trace schema evolves.
* feat(fixtures/seeder): HTTP seeder container for fine-grained telemetry seeding
Adds a sibling container alongside signoz/clickhouse/postgres that exposes
HTTP endpoints for direct-ClickHouse telemetry seeding, so Playwright
tests can shape per-test data without going through OTel or the SigNoz
ingestion path.
tests/fixtures/seeder/:
- Dockerfile: python:3.13-slim + the shared fixtures/ tree so the
container can import fixtures.traces and reuse the exact insert path
used by pytest.
- server.py: FastAPI app with GET /healthz, POST /telemetry/traces
(accepts a JSON list matching Traces.from_dict input; auto-tags each
inserted row with resource seeder=true), DELETE /telemetry/traces
(truncates all traces tables).
- requirements.txt: fastapi, uvicorn, clickhouse-connect, numpy plus
sqlalchemy/pytest/testcontainers because fixtures/{__init__,types,
traces}.py import them at module load.
tests/fixtures/seeder/__init__.py: pytest fixture (`seeder`, package-
scoped) that builds the image via docker-py (testcontainers DockerImage
had multi-segment dockerfile issues), starts the container on the
shared network wired to ClickHouse via env vars, and waits for
/healthz. Cache key + restore follow the dev.wrap pattern other
fixtures use for --reuse.
tests/.dockerignore: exclude .venv, caches, e2e node_modules, and test
outputs so the build context is small and deterministic.
tests/conftest.py: register fixtures.seeder as a pytest plugin.
Currently traces-only — logs + metrics follow the same pattern.
* feat(tests/e2e): surface seeder_url to Playwright via globalSetup
- bootstrap/setup.py: test_setup now depends on the seeder fixture and
writes seeder_url into .signoz-backend.json alongside base_url.
- bootstrap/run.py: test_e2e exports SIGNOZ_E2E_SEEDER_URL to the
subprocessed yarn test so Playwright specs can reach the seeder
directly in the one-command path.
- global.setup.ts: if .signoz-backend.json carries seeder_url, populate
process.env.SIGNOZ_E2E_SEEDER_URL. Remains optional — staging mode
leaves it unset.
Playwright specs that want per-test telemetry can:
await fetch(process.env.SIGNOZ_E2E_SEEDER_URL + '/telemetry/traces', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify([...])
});
and await a truncate via DELETE on teardown.
* fix(alerts-downtime): capture load-time GETs before navigation
Flow 1 registered cap.mark() AFTER page.goto() and then called
page.waitForResponse(/api/v2/rules) — but against a fast local backend
the GET /api/v2/rules response arrived during page.goto, before the
waiter could register, and the test timed out at 30s.
installCapture's page.on('response') listener runs from before the
navigation, so moving mark() above page.goto() and relying on
dumpSince's 500ms drain is enough. No lost precision.
One site only; the same pattern exists in later flows (via per-action
waitForResponse) and may surface similar races — those are left for a
follow-up once the backend-side 2095 migration lands on main (current
frontend still calls PATCH /api/v1/rules/:id which the spec's assertion
doesn't match anyway).
* refactor(fixtures/logs,metrics): extract insert + truncate helpers
Mirror the traces refactor: pull the ClickHouse insert path out of the
insert_logs / insert_metrics pytest fixtures into plain module-level
functions (insert_logs_to_clickhouse, insert_metrics_to_clickhouse) and
move the per-table TRUNCATE loops into truncate_logs_tables /
truncate_metrics_tables. The fixtures become thin wrappers — zero
behavioural change.
Sets up the seeder container to expose POST/DELETE endpoints for logs
and metrics using the exact same code paths as the pytest fixtures.
* feat(fixtures/seeder): add logs and metrics endpoints
Extend the seeder with POST/DELETE endpoints for logs and metrics,
following the same shape as the existing traces endpoints:
- POST /telemetry/logs accepts a JSON list matching Logs.from_dict;
tags each row's resources with seeder=true.
- POST /telemetry/metrics accepts a JSON list matching Metrics.from_dict;
tags resource_attrs with seeder=true (Metrics.from_dict unpacks
resource_attrs rather than a resources dict).
- DELETE /telemetry/logs, DELETE /telemetry/metrics truncate via the
shared truncate_*_tables helpers.
Requirements gain svix-ksuid because fixtures/logs.py imports KsuidMs
for log id generation.
Verified end-to-end against the warm backend: POST inserted=1 on each
signal, DELETE truncated=true on each.
* refactor(fixtures/seeder): align status codes with HTTP semantics
- POST /telemetry/{traces,logs,metrics}: return 201 Created (kept the
{inserted: N} body so callers can verify the count landed).
- DELETE /telemetry/{traces,logs,metrics}: return 204 No Content with
an empty body.
* refactor(tests/seeder): extract from fixtures/ into top-level package
Move the HTTP seeder (Dockerfile, requirements.txt, server.py) out of
tests/fixtures/seeder/ and into its own tests/seeder/ top-level package.
The pytest fixture that builds and runs the image moves to
tests/fixtures/seeder.py so it sits next to the other container fixtures.
Rationale: the seeder is a standalone containerized Python service, not a
pytest fixture. It ships a Dockerfile, its own requirements.txt, and a
server.py entrypoint — none of which belong under a package whose purpose
is shared pytest code.
Image-side changes:
- Dockerfile now copies seeder/ alongside fixtures/ and launches
seeder.server:app instead of fixtures.seeder.server:app.
- Build context stays tests/ (unchanged), so fixtures.* imports inside
server.py continue to resolve.
Fixture-side changes:
- _TESTS_ROOT computation drops one parent (parents[1] now that the file
is at tests/fixtures/seeder.py, not tests/fixtures/seeder/__init__.py).
- The dockerfile= path passed to docker-py becomes seeder/Dockerfile.
No behavior change; every consumer still imports the seeder fixture as
before and gets the same container.
* refactor(fixtures/keycloak): rename from idp.py to name the concrete tech
The container provider at fixtures/idp.py brought up a Keycloak image. Name
it for what it is so we can use fixtures/idp.py later for API-side IdP
helpers (OIDC/SAML admin flows) without an idp-vs-idputils naming collision.
- fixtures/idp.py → fixtures/keycloak.py (git rename).
- fixtures.idputils updates its one internal import to fixtures.keycloak.
- conftest.py pytest_plugins entry points at the new module.
No caller outside fixtures/ imports fixtures.idp directly, so no shim is
needed. The "idp" fixture name (how tests reference it) is unchanged.
* refactor(fixtures/gateway): drop -utils suffix
The module only held helper functions (no fixtures). Rename to match the
domain and leave a shim at the old path so integration/ import sites keep
working until they are swept in a follow-up.
* fix(fixtures/gatewayutils): silence wildcard-import in deprecation shim
The shim intentionally re-exports via `from fixtures.gateway import *`;
pylint flags the wildcard and every unused-wildcard symbol. Suppress both
in the shim only — the live module has no wildcard.
* refactor(fixtures/auth): merge authutils helpers into auth
Pull the pure-helper functions from authutils.py (create_active_user,
find_user_by_email, find_user_with_roles_by_email, assert_user_has_role,
change_user_role) into auth.py next to the fixtures they complement.
Fixtures remain on top; helpers go below. Drop the module docstring.
Replace authutils.py with a deprecation shim that re-exports from
fixtures.auth so integration/ import sites (9 files) keep working until
they are swept in a follow-up. Suppress the wildcard-import warnings in
the shim only.
* refactor(fixtures/alerts): merge alertutils helpers into alerts
Pull the pure-helper functions from alertutils.py
(collect_webhook_firing_alerts, _verify_alerts_labels,
verify_webhook_alert_expectation, update_rule_channel_name) into alerts.py
next to the fixtures they complement. Fixtures stay on top; helpers go
below.
Replace alertutils.py with a deprecation shim that re-exports from
fixtures.alerts so integration/ import sites keep working until they are
swept in a follow-up.
* refactor(fixtures/cloudintegrations): merge cloudintegrationsutils helpers
Pull the pure-helper functions from cloudintegrationsutils.py
(deprecated_simulate_agent_checkin, setup_create_account_mocks,
simulate_agent_checkin) into cloudintegrations.py next to the fixtures
they complement. Fixtures stay on top; helpers go below.
Replace cloudintegrationsutils.py with a deprecation shim that re-exports
from fixtures.cloudintegrations so integration/ import sites keep working
until they are swept in a follow-up.
* refactor(fixtures/idp): rename idputils to idp now that keycloak owns the container
With the Keycloak container provider at fixtures.keycloak, the fixtures.idp
name is free for what idputils always was — API/browser helpers for OIDC
and SAML admin flows against the IdP container.
- fixtures.idputils → fixtures.idp (git rename).
- conftest.py pytest_plugins swaps fixtures.idputils for fixtures.idp so
the create_saml_client / create_oidc_client fixtures register under the
canonical path.
Replace fixtures.idputils with a deprecation shim re-exporting from
fixtures.idp so integration/ import sites (callbackauthn) keep working
until they are swept in a follow-up.
* refactor(fixtures/reuse): rename from dev to describe what the module is
The module wraps pytest-cache resource reuse/teardown for container
fixtures; "dev" conveyed nothing about its role. Rename to fixtures.reuse
and update the 12 internal callers that imported `from fixtures import
dev, types` to use `reuse` instead.
Replace fixtures.dev with a deprecation shim so any external caller keeps
working until the follow-up sweep.
* refactor(fixtures/time,fs): split utils by responsibility
fixtures.utils only held two time parsers (parse_timestamp, parse_duration)
and one path helper (get_testdata_file_path) — a "utils" grab bag.
- Time parsers move to fixtures.time (utils.py → time.py via git rename).
- get_testdata_file_path moves into fixtures.fs where other filesystem
helpers live.
- Internal callers (alerts, logs, metrics, traces) update to the new paths.
Replace fixtures.utils with a deprecation shim that re-exports all three
functions so integration/ import sites keep working until the follow-up
sweep.
* refactor(fixtures/browser): rename from driver to match peer primitives
fixtures.driver was the Selenium WebDriver fixture — rename the module to
fixtures.browser so it sits next to fixtures.http as a named primitive.
The fixture name inside (driver) stays — that's the Selenium-canonical
term and tests reference it directly.
conftest.py pytest_plugins entry points at the new module. A deprecation
shim at fixtures.driver keeps any external caller working until the
follow-up sweep.
* refactor(tests/seeder): install deps via uv from pyproject, drop requirements.txt
The seeder's requirements.txt duplicated 7 of 10 deps from pyproject.toml
with overlapping version pins — a standing drift risk. The comment on top
of the file admitted the real problem: the seeder image already ships
pytest + testcontainers + sqlalchemy because importing fixtures.traces
walks fixtures/__init__.py and fixtures/types.py. "Don't ship test infra"
was already violated.
- Add fastapi, uvicorn[standard], and py to pyproject.toml dependencies
(the three seeder-only deps that were not yet in pyproject; `py` was a
latent gap since fixtures/types.py uses py.path.local but pytest only
pulls it in transitively).
- Switch the Dockerfile to `uv sync --frozen --no-install-project --no-dev`
so the container env matches local dev exactly (uv.lock is the single
source of truth for versions).
- Move tests/seeder/Dockerfile → tests/Dockerfile.seeder so it lives
alongside the pyproject at the root of the build context.
- Delete tests/seeder/requirements.txt.
The seeder image grows by ~40-50MB (selenium, psycopg2, wiremock now come
along from main deps); accepted as a cost of single source of truth since
the seeder is dev-only infra, not a shipped artifact.
* refactor(tests/integration): flatten src/ into bootstrap/ + tests/
Drop the redundant src/ layer in the integration tree. 'src' carries no
information — the directory IS integration test source. After flatten:
tests/integration/
bootstrap/setup.py was src/bootstrap/setup.py
tests/<suite>/*.py was src/<suite>/*.py (16 suites)
testdata/
Updates:
- Makefile: py-test-setup/py-test-teardown/py-test target paths.
- tests/README.md: layout diagram + command examples.
- tests/pyproject.toml: python_files glob now matches basenames
explicitly — "[0-9][0-9]_*.py" for NN-prefixed suite files plus
"setup.py" and "run.py" for bootstrap entrypoints. The old "*/src/.."
glob stopped matching anything here and would have caused pytest to
try collecting seeder/server.py as a test.
* refactor(tests/e2e): flatten src/ into bootstrap/
Drop the e2e/src/ wrapper — the only Python content under it was
bootstrap/, which is now a direct child of e2e/. Keeps integration and
e2e symmetric (both have bootstrap/, tests/, testdata/ as peers).
Also delete bootstrap/__init__.py on both integration and e2e sides.
With --import-mode=importlib, pytest walks up from each .py file to find
the highest __init__.py-containing dir and uses that as the package root.
Without integration/__init__.py or e2e/__init__.py above bootstrap/, both
setup.py files resolved to the same dotted name `bootstrap.setup`, causing
a sys.modules collision that silently dropped test_telemetry_databases_exist
from integration's bootstrap. With no __init__.py anywhere, pytest treats
each setup.py as a standalone module via spec_from_file_location and both
are collected cleanly.
Updates tests/README.md, tests/e2e/README.md, and tests/e2e/CLAUDE.md path
references from e2e/src/bootstrap/ to e2e/bootstrap/.
* refactor(tests/e2e): drop specs/ + strip // spec: back-pointers
specs/ held markdown test plans that mirrored tests/ 1:1 as pre-code
scratch. Once a test exists, the plan is stale the moment the test
diverges — they're AI-planner output, not source of truth. Keep the
workflow alive by .gitignore-ing specs/ (the planner agent can still
write locally) but stop shipping stale plans in the repo.
Strip the `// spec: specs/...` and `// seed: tests/seed.spec.ts` header
comments from 5 .spec.ts files. The spec pointer is dead; the seed
pointer was convention-only — Playwright collects regardless.
* docs(contributing/tests): move e2e/integration guides out of test dirs
Pull the e2e contributor guide out of tests/e2e/CLAUDE.md (which read
like a full agent-workflow reference doc) and into
docs/contributing/tests/e2e.md alongside the existing development / go
guides.
- Delete tests/e2e/CLAUDE.md; its content (layout, commands, role tags,
locator priority, Playwright agent workflow) lives in the new e2e.md
with references to the now-.gitignore'd specs/ dir removed.
- Add docs/contributing/tests/integration.md — short guide covering
layout, runner commands, filename conventions, and the flow for
adding a new suite (there was no contributor doc for this before).
- Trim tests/e2e/README.md to quick-start + commands; link out to the
full guide. Readers who just want to run tests get the 5 commands
they need; anything deeper is one hop away.
* chore(tests/e2e): drop examples/example-test-plan.md
Init-agents boilerplate. Fresh planner agents don't need a checked-in
template; they can write to the .gitignore'd specs/ scratch dir.
tests/integration/.qodo/ was also removed (untracked, empty; .qodo is
already in the root .gitignore).
* refactor(tests/seeder): use fixtures.logger.setup_logger
Drop the one-off logging.basicConfig + logging.getLogger("seeder") in
favor of the shared setup_logger helper that every fixtures/*.py already
uses. Keeps log format consistent across pytest runs and the seeder
container.
fixtures.logger ships into the image via the existing COPY fixtures step
in Dockerfile.seeder — no build change needed.
* fix(tests/e2e): correct e2e_dir path after src/ flatten
After phase 2 (flatten tests/e2e/src/ into tests/e2e/), the run.py file
sits one level closer to the e2e root. parents[2] now resolves to tests/
instead of tests/e2e/, so yarn test would subprocess from the wrong cwd.
parents[1] is the correct index now.
* fix(tests/e2e): correct endpoint-file path in setup.py after src/ flatten
Same class of stale-path bug as the run.py fix: after the e2e/src/
flatten, setup.py sits one level closer to the e2e root. parents[2] now
lands at tests/ instead of tests/e2e/, so .signoz-backend.json would be
written to tests/.signoz-backend.json and the Playwright global.setup.ts
(which expects tests/e2e/.signoz-backend.json) wouldn't find it.
parents[1] is correct.
* refactor(tests/e2e): drop pre-seed fixtures; each spec owns its data
The seeder (tests/seeder/) was built so specs can POST telemetry
per-test. Global pre-seeding via tests/e2e/conftest.py (seed_dashboards,
seed_alert_rules, seed_e2e_telemetry) is the exact anti-pattern that
setup obsoletes — shared state across specs, order-dependent runs, no
reset between tests.
- Delete tests/e2e/conftest.py (3 fixtures, all pre-seed).
- Delete tests/e2e/testdata/dashboards/apm-metrics.json — its only
consumer was seed_dashboards. tests/e2e/testdata/ now empty and gone.
- Drop seed_dashboards, seed_alert_rules, seed_e2e_telemetry params
from bootstrap/setup.py::test_setup and bootstrap/run.py::test_e2e.
test_teardown never depended on them.
- Refresh the module docstrings on both bootstrap tests to reflect the
new model (backend + seeder up; specs seed themselves).
- Update tests/README.md and docs/contributing/tests/e2e.md: remove the
testdata/ + conftest.py references, document the per-spec seeding
rule (telemetry via seeder endpoints, dashboards/alerts via SigNoz
REST API from the spec).
Known breakage: tests/e2e/tests/dashboards/dashboards-list.spec.ts
expects at least one dashboard to exist. With seed_dashboards gone, it
will fail until that spec is updated to create its own dashboard via
the SigNoz API in test.beforeAll. Followup.
* refactor(tests/e2e): relocate auth helper into fixtures/; expose authedPage
Rename tests/e2e/utils/login.util.ts → tests/e2e/fixtures/auth.ts and
drop the (now-empty) utils/ dir. "Fixtures" is the unit of per-test
shared setup on both the Python and TS sides of this project — naming
them consistently across trees makes the parallel obvious.
fixtures/auth.ts now exports three things:
- `test` — Playwright test extended with an authedPage fixture. New
specs can request `authedPage` as a param and skip the
`beforeEach(() => ensureLoggedIn(page))` boilerplate entirely.
- `expect` — re-exported from @playwright/test so callers have one
import.
- `ensureLoggedIn(page)` — the underlying helper, still exported for
specs that want per-call control.
Update the 4 specs that imported from utils/login.util to point at the
new path; no behavior change in those specs (they keep calling
ensureLoggedIn in beforeEach). Refactoring them to use authedPage can
happen spec-by-spec later.
Also update the path example in .cursorrules so AI-generated snippets
reach for the new import path.
* refactor(tests/e2e): emit .env.local instead of .signoz-backend.json
The old flow (pytest writes JSON → global.setup.ts loads it → exports
env vars) was doing what dotenv already does. Collapse to the native
pattern:
- bootstrap/setup.py writes tests/e2e/.env.local with the four coords
(BASE_URL, USERNAME, PASSWORD, SEEDER_URL). File header marks it as
generated.
- playwright.config.ts loads .env first, then .env.local with
override=true. User-provided defaults stay in .env; generated values
win when present.
- Delete tests/e2e/global.setup.ts (36 lines gone) and its globalSetup
reference in playwright.config.ts.
Subprocess-injected env (run.py shelling out to yarn test) still wins
because dotenv doesn't overwrite already-set process.env keys.
Rename the test-only override env var SIGNOZ_E2E_ENDPOINT_FILE →
SIGNOZ_E2E_ENV_FILE for accuracy. Update .env.example, .gitignore (drop
.signoz-backend.json, keep .env.local with its explanatory comment),
tests/README.md, docs/contributing/tests/e2e.md.
* refactor(tests/e2e/alerts-downtime): drop custom network + screenshot capture
The spec wrapped every /api/ response in a bespoke installCapture(), wrote
hand-named JSON files per call (01_step1.1_GET_rules.json, ...), and took
step-by-step screenshots — all going into run-spec-<ts>/ next to the spec
(gitignored).
Playwright already records equivalent data via `trace` (network bodies,
screenshots per step, DOM snapshots, console — viewable via
`playwright show-trace`). The capture infra was duplicating that for the
one-shot 2095 regression audit; no downstream consumer reads the JSON or
PNG artifacts now.
- Remove installCapture, shot, RUN_DIR/NET_DIR/SHOT_DIR, fs/path imports.
- Strip cap.mark()/cap.dumpSince()/shot() calls throughout the 7 flows.
- Collapse the block-scopes that only existed to bound mark variables.
- Drop the "Artifacts" paragraph from the file's top-of-file comment.
- Remove the `tests/alerts-downtime/run-spec-*/` entry from .gitignore.
Spec drops from 885 lines to 736 (≈17% smaller). All 7 flows + their
assertions are unchanged. For debug access, rely on
`trace: 'on-first-retry'` (already set in playwright.config.ts) + `yarn
show-trace`.
* refactor(tests/e2e): move alerts-downtime.spec.ts into alerts/
The spec lives mostly in the alerts domain (6 of 7 flows), with the
planned-downtime CRUD (Flow 4) and cascade-delete (Flow 5) as
cross-feature collateral. The standalone alerts-downtime/ dir was
compound-named, breaking the one-feature-per-dir pattern every other
dir under tests/ follows, and duplicating the spec's own filename.
Move to tests/alerts/alerts-downtime.spec.ts. Empty alerts-downtime/
dir removed.
* refactor(tests/e2e): consolidate Playwright output under artifacts/
All Playwright outputs now land under a single tests/e2e/artifacts/ dir
so CI can archive it in one command (tar / zip / upload-artifact). Each
piece was writing to its own sibling of tests/e2e/ before.
playwright.config.ts:
- outputDir: 'artifacts/test-results' — per-test traces, screenshots,
videos (was default test-results/).
- HTML reporter → 'artifacts/html-report' (was default
playwright-report/); open: 'never' so CI doesn't spawn a browser on
report generation.
- JSON reporter → 'artifacts/results.json' (was
'test-results/results.json').
package.json: `yarn report` now points playwright show-report at the new
HTML folder.
Ignore updates — replace the two old paths with /artifacts/ in
tests/e2e/.gitignore, tests/e2e/.prettierignore, and tests/.dockerignore
(seeder image build context).
.cursorrules: update the `cat test-results/results.json` example to the
new path so AI-generated snippets reach for the right file.
Delete the empty test-results/ and playwright-report/ dirs that prior
runs left behind.
* refactor(tests/e2e): one artifacts/ subdir per reporter
Within artifacts/, give each reporter its own named subdir so the layout
tells you what wrote what:
artifacts/
html/ # HTML reporter (was artifacts/html-report)
json/results.json # JSON reporter (was artifacts/results.json)
test-results/ # outputDir — per-test traces/screenshots/videos
`yarn report` and the .cursorrules cat example point at the new paths.
* refactor(tests/e2e): drop SIGNOZ_USER_ROLE env filter and @admin/@editor/@viewer tags
The filter claimed to be role-based but only grep'd by tag — the actual
browser session is always admin (bootstrap creates one admin, auth.setup.ts
saves one storageState, every project uses it). Tagging tests `@viewer`
didn't mean they ran as a viewer; it just meant they'd be in the subset
selected when SIGNOZ_USER_ROLE=Viewer. Superset semantics (admin sees
everything) meant the filter was at best a narrower test selection and
at worst a misleading assertion of role coverage.
Gone:
- getRoleGrepPattern() + grep: line in playwright.config.ts.
- The dedicated setup project's grep override (no filter to override).
- SIGNOZ_USER_ROLE entries in .env.example, README, docs/contributing.
- The "Role-Based Testing" section + all role-tagging guidance and
example snippets in .cursorrules.
- All `{ tag: '@viewer' | '@editor' | '@admin' }` annotations on the 90
affected test sites across 5 spec files (single-line and multi-line
forms). ~90 annotations gone.
For ad-hoc selection, `yarn test --grep <pattern>` still works on
Playwright's normal grep (test titles/paths).
Real role-based coverage (separate users + storageStates per role) is a
different problem — not pretending this was it.
* chore(tests/e2e): drop .cursorrules
* refactor(tests/e2e): move auth from project-level storageState to per-suite fixture
Replaced auth.setup.ts + globally-mounted storageState with a test-scoped
authedPage fixture in tests/e2e/fixtures/auth.ts. Each suite controls its
own identity via `test.use({ user: ... })`; specs that need to run
unauthenticated just request the stock `page` fixture instead.
fixtures/auth.ts:
- Declares `user` as a test option, defaulting to ADMIN (creds from
.env.local / .env).
- authedPage resolves to a Page whose context has storageState mounted
for that user. First request per (user, worker) triggers one login
and writes a per-user storageState file under .auth/; subsequent
requests reuse it via a Promise-valued cache.
- Exposes `User` type and `ADMIN` constant so future suites can declare
additional users (EDITOR, VIEWER) as credentials become available.
playwright.config.ts:
- Drop authFile constant, `setup` project, storageState + dependencies
on each browser project.
tests/auth.setup.ts:
- Deleted. Login logic now lives inside fixtures/auth.ts's login() helper,
called on demand by the fixture rather than upfront for the whole run.
Spec migration (6 files):
- Import `test, expect` from ../fixtures/auth (or ../../fixtures/auth)
instead of @playwright/test.
- Drop `ensureLoggedIn` imports and `await ensureLoggedIn(page)` calls.
- Swap `{ page }` → `{ authedPage: page }` in test and beforeEach
destructures (local var stays `page` via aliasing so test bodies need
no further changes).
Cost: N logins per run, where N = unique users × workers (= 1 × 2–4
today, vs the old 1 globally). Tradeoff for explicit per-suite control.
Specs that need unauth later just use `async ({ page }) => ...` — the
fixture isn't invoked, so no login fires.
291 tests still list (previously 292: the old auth.setup.ts counted as
one fake "test"; it's gone now).
* refactor(tests/e2e): cache auth storageState in memory, drop .auth/ dir
The fixture was writing each user's storageState to .auth/<user>.json and
then handing Playwright the file path. But Playwright's
browser.newContext({ storageState }) accepts the object form too —
ctx.storageState() without a path arg returns the cookies+origins
inline.
Keeping the cache in memory means no filesystem roundtrip per login, no
.auth/ dir to maintain, no stale JSON persisting across runs, and no
gitignore entry for it. Each worker's Map holds one Promise<StorageState>
per unique user, resolved on first login and reused thereafter.
Drop the .auth/ entry from tests/e2e/.gitignore; delete the (now unused)
on-disk .auth/ dir.
* chore(tests/e2e): drop seed.spec.ts
* chore(tests/e2e): drop unused README.md and .mcp.json
* refactor(tests/e2e): move existing specs to legacy/ pending fresh rewrite
Park the 5 current spec files under tests/e2e/legacy/ while fresh specs
get written in tests/e2e/tests/ against the new conventions (TC-NN
titles, authedPage fixture, minimal direct-fetch). Playwright's testDir
stays pointed at ./tests — `yarn test` now finds 0 tests until the
first fresh spec lands. legacy/ is preserved for reference but not
collected by default.
Add a .gitkeep under tests/ so the empty dir survives in git between
the move and the first new spec.
Running legacy on demand:
npx playwright test --config tests/e2e/playwright.config.ts \
--project chromium legacy/<spec>.ts
(or temporarily point testDir at ./legacy in the config). No yarn
script wired — legacy is expected to rot as fresh specs replace it.
* refactor(tests): drop -utils deprecation shims; import from canonical modules
The shims we introduced during the phase-3 merges (authutils, alertutils,
cloudintegrationsutils, idputils, gatewayutils) and the phase-4 primitive
renames (dev, utils, driver) have done their job — integration/ tests can
now import directly from the real modules.
Rewrite every shim-import in tests/integration/tests/:
fixtures.authutils → fixtures.auth
fixtures.alertutils → fixtures.alerts
fixtures.cloudintegrationsutils → fixtures.cloudintegrations
fixtures.idputils → fixtures.idp
fixtures.gatewayutils → fixtures.gateway
fixtures.utils (get_testdata_file_path) → fixtures.fs
Delete all 8 shim files:
fixtures/{authutils,alertutils,cloudintegrationsutils,idputils,
gatewayutils,dev,utils,driver}.py
Nothing in active code (integration tests, e2e fixtures, bootstrap, seeder)
imported fixtures.dev or fixtures.driver, so those had no callers to
sweep — just delete.
500 tests still collect.
* fix(tests/seeder): add python3-dev so psycopg2 can compile in the image
Consolidating seeder deps into pyproject.toml pulled in psycopg2, which
needs Python dev headers (Python.h) to build from source. The apt layer
had gcc + libpq-dev but was missing python3-dev, so \`uv sync --frozen
--no-install-project --no-dev\` failed with "gcc failed with exit code 1"
during the seeder image build.
Add python3-dev to the apt install line; image size bump ~50MB for dev
headers. Alternative would have been swapping psycopg2 for
psycopg2-binary in pyproject.toml, but that'd affect the whole test
project for one Dockerfile concern — wrong scope.
* feat(tests/e2e): re-author 2095 alerts + downtime regression
Three fresh specs split by resource replace the 736-line
legacy monolith at tests/e2e/legacy/alerts/alerts-downtime.spec.ts:
- alerts.spec.ts: rule list CRUD, labels round-trip, test-notification
pre-state, details/history/AlertNotFound, anomaly (EE-gated, skip on
community)
- downtime.spec.ts: planned-downtime CRUD round-trip
- cascade-delete.spec.ts: 409 paths on rule/downtime delete when linked
UI-first: Playwright traces capture the BE conversations, so direct
page.request calls are reserved for seeding where the query-builder
setup is incidental to the test, API-contract probes, and cleanup.
* refactor(tests/e2e): group alerts specs under tests/alerts/
* feat(tests/fixtures/auth): apply_license fixture + wire into e2e bootstrap
- Adds a package-scoped apply_license fixture that stubs the Zeus
/v2/licenses/me mock and POSTs /api/v3/licenses so the BE flips to
ENTERPRISE. The fixture also PUTs org_onboarding=true because the
license enables the onboarding flag which would otherwise hijack
every post-login navigation to a questionnaire.
- Wires apply_license into e2e/bootstrap/setup.py::test_setup and
::test_teardown alongside create_user_admin.
- Existing add_license helper stays as-is for integration tests.
- Login fixture now waits for the URL to leave /login instead of a
pre-license "Hello there" welcome string (the post-login landing
page varies with license state).
- TC-07 anomaly test no longer skips (license enables the flag) and
drops the legacy test-notification API contract probe that needs
seeded metric data (covered by the integration suite).
* chore: cleanup
* chore: remove claude files
* chore(tests/fixtures): drop unused dashboards.py
* chore(tests/e2e): rename playwright outputDir to artifacts/results
* chore(tests/e2e): drop legacy specs, trim alerts.spec.ts to one smoke test
Deletes tests/e2e/legacy/ (five old 2095-replay specs) and the two
sibling alerts suite files (downtime, cascade-delete). alerts.spec.ts
is reduced to a single TC-01 smoke test that loads /alerts and asserts
the tabs render — a fresh minimum to build on.
* docs(contributing): new integration.md + e2e.md at top level
Promotes the two test-contributor docs from docs/contributing/tests/
to docs/contributing/ and rewrites them in the long-form Q&A format
of docs/contributing/go/integration.md (prerequisites → setup →
framework → writing → running → configuring → remember).
Reflects the current state: shared fixtures package at tests/fixtures/,
flat integration suites under tests/integration/tests/, e2e specs
grouped by resource under tests/e2e/tests/<feature>/, apply_license
fixture in the bootstrap, authedPage Playwright fixture, and the
artifacts/{html,json,results} output layout.
* docs(contributing): relocate integration.md + e2e.md to tests/
Moves docs/contributing/go/integration.md -> docs/contributing/tests/integration.md
and docs/contributing/e2e.md -> docs/contributing/tests/e2e.md so the test-
contributor docs live under contributing/tests/. The previous top-level
promotion at docs/contributing/integration.md is removed; go/readme.md
drops the dangling integration link.
* docs(contributing/tests): update integration.md to current repo layout
* ci(tests): fix integrationci paths + add e2eci workflow
integrationci:
- Matrix path was integration/src/<suite> (old layout); current layout
is integration/tests/<suite>. Renames the matrix key src -> suite and
fixes the pytest path accordingly.
- Adds auditquerier and rawexportdata to the matrix (new suites).
- Drops bootstrap from the matrix — it's no longer a test suite, just
the pytest lifecycle entry.
e2eci (new, replaces the broken frontend/-based run-e2e.yaml):
- Label-gated trigger mirroring integrationci: requires safe-to-test +
safe-to-e2e. Runs on pull_request / pull_request_target.
- Installs Python (uv) and Node (yarn), syncs tests/ deps, installs
Playwright browsers for the matrix project.
- Brings the stack up via e2e/bootstrap/setup.py::test_setup --with-web
(build signoz-with-web container once), runs playwright against it,
tears down in an always-run step.
- Uploads the HTML report + per-test traces as artifacts.
- Matrix starts with chromium only (firefox / webkit can follow).
* ci(tests/e2e): upload entire artifacts/ dir, 5-day retention
* fix(tests/fixtures): apply black formatting to truncate helpers
* fix(tests/pyproject): ignore node_modules and py module in pylint
* ci(tests): drop auditquerier from integrationci matrix for now
* refactor(tests): drop __file__.parents[N] path tricks; use pytestconfig.rootpath
The pytest rootdir is already tests/, so anywhere we were computing
_REPO_ROOT / _TESTS_ROOT / e2e-dir from Path(__file__).resolve().parents[N]
can just use pytestconfig.rootpath (or .parent for the repo root).
- fixtures/signoz.py: DockerImage path → pytestconfig.rootpath.parent
- fixtures/seeder.py: docker-py build path → pytestconfig.rootpath
- e2e/bootstrap/setup.py: .env.local path → pytestconfig.rootpath / e2e
- e2e/bootstrap/run.py: yarn-test cwd → pytestconfig.rootpath / e2e
* chore(tests/e2e): drop bootstrap/run.py
The run.py entrypoint was just setup.py + subprocess('yarn test'); CI
splits those steps anyway (separate provision / test / teardown for
clean artifact capture) and locally the two-step flow is equivalent.
Removing the duplicate entrypoint; docs updated accordingly.
* cleanup(tests): simplify review pass
- fixtures/fs.py: testdata path resolved to tests/testdata after the
fixture move; integration tests with data-driven parametrize (e.g.
alerts/02_basic_alert_conditions.py) were all failing with
FileNotFoundError. Walk to tests/integration/testdata now.
- fixtures/auth.py: extract _login helper so apply_license stops
duplicating the GET /sessions/context + POST /sessions/email_password
pair. Add a retry loop on POST /api/v3/licenses so a BE that isn't
quite ready at bring-up time doesn't fail the fixture.
- seeder/server.py: use FastAPI lifespan to open+close the ClickHouse
client instead of a lazy module-level global; collapse the verbose
module docstring.
- fixtures/seeder.py + e2e/bootstrap/setup.py: trim docstrings/comments
that narrated WHAT the code does — per-repo convention keeps only
non-obvious WHY.
- .github/workflows/integrationci.yaml: gate the Chrome + chromedriver
install on matrix.suite == 'callbackauthn' (the only suite that uses
Selenium). Saves ~30s × 50 jobs on every PR run.
|
||
|
|
484b22c12a | chore(codeowner): add @therealpandey as codeowner (#11055) | ||
|
|
52992c0e80 | chore(switch): switch for some time to @therealpandey (#11017) | ||
|
|
d677973d56 |
test(integration): add test cases for new user APIs (#10837)
* test(integration): add user_v2 tests * test(integration): fix fmt * test(integration): disable delete mode from tests * test(integration): add response.text when the assertion fails * test(integration): some renaming |
||
|
|
13249b5e69 |
feat(sqlstore): enable wal mode by default (#10822)
* chore(sqlstore): run integration tests on wal and immediate * chore(sqlstore): remove the txlock changes * chore(sqlstore): make wal the default mode |
||
|
|
bad80399a6 |
feat(serviceaccount): integrate service account (#10681)
* feat(serviceaccount): integrate service account * feat(serviceaccount): integrate service account with better types * feat(serviceaccount): fix lint and testing changes * feat(serviceaccount): update integration tests * feat(serviceaccount): fix formatting * feat(serviceaccount): fix openapi spec * feat(serviceaccount): update txlock to immediate to avoid busy snapshot errors * feat(serviceaccount): add restrictions for factor_api_key * feat(serviceaccount): add restrictions for factor_api_key * feat: enabled service account and deprecated API Keys (#10715) * feat: enabled service account and deprecated API Keys * feat: deprecated API Keys * feat: service account spec updates and role management changes * feat: updated the error component for roles management * feat: updated test case * feat: updated the error component and added retries * feat: refactored code and added retry to happend 3 times total * feat: fixed feedbacks and added test case * feat: refactored code and removed retry * feat: updated the test cases --------- Co-authored-by: SagarRajput-7 <162284829+SagarRajput-7@users.noreply.github.com> |
||
|
|
bb4e7df68b |
chore: add rule state history module (#10488)
* chore: add rule state history module * chore: run generate * chore: generate * Fix timeline default limit and escape exists key (#10490) Co-authored-by: Cursor Agent <cursoragent@cursor.com> * chore: remove unused AddRuleStateHistory and add comments * chore: regenerate * chore: update names and move functions * chore: remove return * chore: update .github/CODEOWNERS for history * chore: update condition builder * chore: lint --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> |
||
|
|
ea3f0b47b7 | fix: add pnpm-lock.yaml + update CI workflows (yarn → pnpm) | ||
|
|
b51a41ab4e | ci: enable multi-arch builds (amd64 + arm64 native runners) | ||
|
|
f7ef801bf1 |
ci: migrate Docker build to shared reusable workflow
Add multi-stage root Dockerfile (frontend + Go build + alpine runtime) so the shared workflow can build everything in one docker build. Replace the old build-ghcr.yaml (pre-build outside Docker + thin COPY image) with a single call to hanzoai/.github/.github/workflows/docker-build.yml@main. amd64-only until arm64 runner is restored. |
||
|
|
2ae8d521a6 |
ci: add multi-env Docker image tagging for test/dev branches
Replace rebrand/hanzo-o11y branch trigger with test and dev. Existing metadata-action tags (type=ref,event=branch) produce :test and :dev image tags automatically. |
||
|
|
24760d7031 |
fix: update frontend yarn.lock for frozen-lockfile CI compatibility
yarn.lock was out of date after package.json changes in rebrand commits. CI builds with --frozen-lockfile were failing. Also remove deprecated build-community.yaml and build-enterprise.yaml workflows. |
||
|
|
dfe2a6a9e5 |
fix(tests): fix flaky rootuser integration tests (#10660)
* fix(tests): fix flaky rootuser integration tests setupCompleted becomes true before the root user is actually created because the reconciliation runs in an async goroutine. Add a second polling phase that waits for /api/v1/user to return 200, confirming the root user exists and the impersonation provider can resolve. * fix(ci): fail py-fmt check when formatter changes files Add git diff --exit-code after make py-fmt so CI fails if any files are not properly formatted, instead of silently passing. Also includes black formatting fix for 01_rootuser.py. * refactor(tests): remove redundant unauthenticated request test test_unauthenticated_request_succeeds is redundant now that test_root_user_created already polls /api/v1/user without auth and waits for 200. |
||
|
|
ca9cbd92e4 |
feat(identn): implement an impersonation identn (#10641)
* feat(identn): implement an impersonation identn * fix: prevent nil pointer error * feat: dry org code by implementing getbyidorname * feat: add integration tests for root user and impersonation * fix: fix lint |
||
|
|
2db83b453d |
refactor: merge roletypes into authtypes (#10614)
* refactor: merge roletypes into authtypes * refactor: merge roletypes into authtypes * refactor: update openapi spec * feat: split CI * fix: fix tsc of frontend |
||
|
|
aa05a7bf14 | chore(identn): add me as codeowner for identn (#10612) | ||
|
|
cab4a56694 |
chore: add myself as codeowner for CI and go.mod (#10597)
Clarified CODEOWNERS comments and updated owner assignments. |
||
|
|
78041fe457 | chore: send slack notification on dequeue only and not merge (#10596) | ||
|
|
9689b847f0 |
chore: add slack notification on dequeue from merge queue (#10580)
* chore: add slack notification on merge queue failure * chore: break type * chore: update yaml * chore: update yaml * chore: update yaml * chore: update yaml * chore: update yaml * chore: update yaml * chore: update yaml * chore: resolve comments |
||
|
|
76354e07ef |
rebrand: purge posthog, clickhouse, signoz from frontend
- posthog-js → @hanzo/insights, all variable names posthog → insights - POSTHOG_KEY → INSIGHTS_KEY across env, vite config, CI workflow - clickhouse → datastore: types, enums, components, directories (386 occurrences) - ChQuerySection → DsQuerySection directory and component rename - signoz → o11y/hanzo in all onboarding docs, URLs, brand text - X-SIGNOZ-QUERY-ID → X-O11Y-QUERY-ID header |
||
|
|
4b4ef5ce58 |
fix: edit mode variables not persisting value (#10576)
* fix: edit mode variables not persisting value * chore: move into hook * chore: add tests * chore: fix tests * chore: move functions |
||
|
|
d4c37deda9 |
fix(ci): bump node to 22, go to 1.25, fix community binary name
- Frontend requires Node >= 22.0.0 - go.mod requires go >= 1.25.0 - Community Dockerfile expects o11y-community binary, not signoz |
||
|
|
44a947bd32 | ci: add GHCR build workflow for o11y Docker images |