{"id":42499829,"url":"https://github.com/grafana/grafana-cube-datasource","last_synced_at":"2026-05-01T13:02:34.490Z","repository":{"id":335086112,"uuid":"1135944708","full_name":"grafana/grafana-cube-datasource","owner":"grafana","description":"A Grafana data source plugin that brings semantic layer analytics via Cube. Define metrics once, use them consistently across all dashboards.","archived":false,"fork":false,"pushed_at":"2026-04-27T12:37:03.000Z","size":3073,"stargazers_count":15,"open_issues_count":40,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-27T14:24:35.556Z","etag":null,"topics":["analytics","cube","datasource","grafana","grafana-plugin","semantic-layer"],"latest_commit_sha":null,"homepage":"https://grafana.com/grafana/plugins/grafana-cube-datasource/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/grafana.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-01-16T20:20:39.000Z","updated_at":"2026-04-27T12:37:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/grafana/grafana-cube-datasource","commit_stats":null,"previous_names":["grafana/grafana-cube-datasource"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/grafana/grafana-cube-datasource","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafana%2Fgrafana-cube-datasource","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafana%2Fgrafana-cube-datasource/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafana%2Fgrafana-cube-datasource/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafana%2Fgrafana-cube-datasource/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/grafana","download_url":"https://codeload.github.com/grafana/grafana-cube-datasource/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafana%2Fgrafana-cube-datasource/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32497815,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","cube","datasource","grafana","grafana-plugin","semantic-layer"],"created_at":"2026-01-28T13:03:42.212Z","updated_at":"2026-05-01T13:02:34.484Z","avatar_url":"https://github.com/grafana.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cube Datasource Plugin for Grafana\n\n[![Marketplace](https://img.shields.io/badge/dynamic/json?logo=grafana\u0026query=$.version\u0026url=https://grafana.com/api/plugins/grafana-cube-datasource\u0026label=Marketplace\u0026prefix=v\u0026color=F47A20)](https://grafana.com/grafana/plugins/grafana-cube-datasource/)\n[![Grafana](https://img.shields.io/badge/dynamic/json?logo=grafana\u0026query=$.grafanaDependency\u0026url=https://grafana.com/api/plugins/grafana-cube-datasource\u0026label=Grafana\u0026color=F47A20)](https://grafana.com/grafana/plugins/grafana-cube-datasource/)\n[![Downloads](https://img.shields.io/badge/dynamic/json?logo=grafana\u0026query=$.downloads\u0026url=https://grafana.com/api/plugins/grafana-cube-datasource\u0026label=Downloads\u0026color=F47A20)](https://grafana.com/grafana/plugins/grafana-cube-datasource/)\n[![License](https://img.shields.io/github/license/grafana/grafana-cube-datasource)](LICENSE)\n\n\u003e **Experimental**: This plugin is experimental. Features may be incomplete or have known limitations, and you should expect some rough edges. See [Experimental Status](#experimental-status) for details.\n\nConnect Grafana to [Cube](https://cube.dev/) for semantic layer analytics. Query measures and dimensions, apply filters, and visualize your data—without writing SQL.\n\n![BI Dashboard with Cross-Panel Filtering](src/img/screenshot-bi-dashboard.png)\n\n**[Try it live on play.grafana.org →](https://play.grafana.org/d/territory-navigator)**\n\n## Why Use This Plugin?\n\nThis plugin brings a **true semantic layer** to Grafana for the first time. By connecting to Cube, you get:\n\n- **No more writing SQL** — Query your data using pre-defined measures and dimensions\n- **No more writing JOINs** — Cube handles the complexity of joining tables for you\n- **Single source of truth** — Business metrics are defined once in Cube and used consistently across all dashboards\n- **Lower barrier to entry** — Non-technical users can build dashboards without SQL knowledge\n- **Scalable complexity** — Start simple, but analytics queries can grow as sophisticated as you need\n- **More maintainable dashboards** — Panels require far less code when using semantic definitions\n- **Cross-panel filtering** — Use AdHoc filters to drill down across Table and Bar Chart panels, enabling data exploration for dashboard viewers\n\n## Features\n\n### Query Builder\n\nThe visual query builder supports:\n\n| Feature | Description |\n|---------|-------------|\n| **Dimensions** | Select one or more dimensions to group your data |\n| **Measures** | Select one or more measures to aggregate |\n| **Limit** | Control the number of rows returned (defaults to 10,000; maximum 50,000). See [Cube's row limit documentation](https://cube.dev/docs/product/apis-integrations/core-data-apis/queries#row-limit) for details. |\n| **Filters** | Filter your query before aggregation |\n| **Order** | Sort results by any selected dimension or measure |\n\n![Query Editor](src/img/screenshot-query-editor.png)\n\n### Filtering\n\nThe visual query builder supports:\n\n- **Filter members**: Dimensions only\n- **Operators**: `equals` and `notEquals`, each accepting multiple values\n- **Multiple filters**: Combine with AND (intersection)\n\n#### Advanced Filtering (via Panel JSON)\n\nThe full [Cube filter syntax](https://cube.dev/docs/product/apis-integrations/rest-api/query-format#filters-format) is supported when editing queries via the panel JSON editor, including:\n\n- **All Cube filter operators**: `contains`, `gt`, `gte`, `lt`, `lte`, `set`, `notSet`, `inDateRange`, and more\n- **Measure filters**: Filter on any measure, not just dimensions\n- **AND/OR filter groups**: Combine filters with logical AND/OR for complex conditions (e.g. \"status = completed OR payment_method = credit_card\")\n\nQueries using these features display in the read-only JSON viewer (see below). The visual builder includes a hint with a link to the [Cube filter docs](https://cube.dev/docs/product/apis-integrations/rest-api/query-format#filters-format) for reference.\n\n### JSON Query Viewer\n\nWhen a query uses features that the visual builder cannot represent (such as time dimensions configured in the panel JSON), the editor automatically switches to a **read-only JSON viewer**. This shows:\n\n- An info banner explaining which features triggered JSON mode\n- The full query as syntax-highlighted JSON\n- A compiled SQL preview\n\nThis ensures no query configuration is hidden — users always see exactly what is configured, even for advanced queries. To edit these queries, use the **dashboard JSON editor** or **panel JSON editor**.\n\n### Dashboard Variables\n\n#### AdHoc Filters\n\nClicking a value in a **Table** or **Bar Chart** panel creates or updates an AdHoc dashboard variable scoped to the Cube datasource. This enables powerful cross-panel filtering and data exploration.\n\nAdHoc filters can also be edited directly in the dashboard UI to add additional filter members, operators, and values. The same operator limitations apply (`=` and `!=` only).\n\n**How filters combine:**\n- Multiple AdHoc filters combine with AND (intersection)\n- AdHoc filters combine with per-panel filters using AND (intersection)\n\n#### Time Range Filtering\n\nTo filter all panels by the dashboard time picker:\n\n1. Create a dashboard variable with identifier `cubeTimeDimension`\n2. Set its value to the time dimension field you want to filter by (e.g., `order_date`)\n3. The dashboard's `$__from` and `$__to` variables will automatically apply to all panels\n\n## Known Limitations\n\nThis plugin is experimental. Current limitations include:\n\n| Limitation | Details |\n|------------|---------|\n| **Cube Cloud authentication** | Authentication does not yet work with Cube Cloud. Self-hosted Cube (dev and production mode) works correctly. |\n| **Technical field names** | Dimension and measure names currently use full technical identifiers (e.g., `orders.customer_name`) rather than human-readable labels. This is due to a dependency on how Grafana implements AdHoc filters. |\n| **Visual builder filter operators** | The visual builder only supports `equals` and `notEquals`. All Cube operators are available via panel JSON. |\n| **Visual builder filter members** | The visual builder only supports dimension filters. Measure filters are available via panel JSON. |\n| **Cross-panel filtering** | Depends on Grafana AdHoc filters. Currently works with Table and Bar Chart panels only |\n\n## Experimental Status\n\n\u003e **Not for production use.** This plugin is experimental and is not meant to be used in production or critical environments.\n\nThis plugin is marked as **experimental**, meaning:\n\n- Features may be incomplete or have known limitations\n- Backward compatibility is not guaranteed between versions\n- The data model, configuration, or UI might change, potentially breaking dashboards\n- The risks are unknown and potentially high\n- Support is limited to GitHub issues; no SLA is provided\n\n**Do not use this plugin in production environments.** It is intended for:\n- Testing and evaluation\n- Development environments\n- Providing early feedback\n- Validating use cases before production readiness\n\nTrack the [CHANGELOG](CHANGELOG.md) for breaking changes and stability updates.\n\n---\n\n## About Cube\n\nCube is a semantic layer that sits between your data warehouse and your applications. It provides a consistent API for querying data, handles caching, security, and pre-aggregations. This Grafana plugin enables you to leverage Cube's powerful data modeling capabilities directly in your Grafana dashboards.\n\n---\n\n# Development\n\n## Getting started\n\n### Setup\n\n1. Install dependencies\n\n   ```bash\n   npm install\n   ```\n\n2. Update [Grafana plugin SDK for Go](https://grafana.com/developers/plugin-tools/key-concepts/backend-plugins/grafana-plugin-sdk-for-go) dependency to the latest minor version:\n\n   ```bash\n   go get -u github.com/grafana/grafana-plugin-sdk-go\n   go mod tidy\n   ```\n\n### Cube SDK parity guidance\n\nThis plugin backend is written in Go, but Cube protocol semantics are primarily\ndefined by Cube's JavaScript SDK (`@cubejs-client/core`) and Cube REST docs.\n\nWhen changing protocol-level behavior (for example `/v1/load` handling, retry\nbehavior, timeout/cancellation semantics, status/error mapping, progress fields):\n\n- Check Cube JS SDK behavior first (local path: `../cube/packages/cubejs-client-core/src/index.ts`)\n- Check Cube REST docs (local path: `../cube/docs/pages/product/apis-integrations/rest-api.mdx`)\n- Mirror SDK behavior by default unless there is a clear Grafana/backend reason to diverge\n- If intentionally diverging, document rationale and user impact in the PR and add tests\n  that explicitly cover the divergence\n\n### Development Workflow (Recommended)\n\nFor the best development experience with automatic reloading of both frontend and backend changes:\n\n**Terminal 1 - Frontend Development:**\n\n```bash\nnpm run dev\n```\n\n**Terminal 2 - Backend Development with Auto-reload:**\n\n```bash\nDEVELOPMENT=true docker compose up --build\n```\n\nThis setup provides:\n\n- **Frontend hot-reloading**: Changes to TypeScript/React code automatically refresh the browser\n- **Backend auto-rebuilding**: Changes to Go code automatically rebuild and reload the plugin\n- **Built-in debugging**: Delve debugger available on port 2345\n\nThe docker-compose setup includes Cube and Postgres with sample data, starting:\n\n- Postgres with JaffleShop sample data pre-loaded\n- Cube connected to Postgres\n- Grafana with the plugin loaded\n\nOnce running, you can:\n\n1. **Access Grafana** at: http://localhost:3000\n\n   - Login with username: `admin`, password: `admin`\n   - The Cube datasource is automatically provisioned and ready to use\n   - A PostgreSQL datasource is also provisioned for direct database access\n   - Sample dashboards are pre-loaded for testing\n\n2. **Test the Cube API directly** (authentication is not required):\n   ```console\n   curl -G --data-urlencode 'query={\"dimensions\":[\"order_details.customers_first_name\"],\"measures\":[\"order_details.payments_total_amount\",\"order_details.count\"]}' http://localhost:4000/cubejs-api/v1/load | jq '.data[0]'\n   ```\n\n### Individual Build Commands\n\nFor production builds or manual development:\n\n**Backend builds:**\n\n```bash\n# Build for all platforms\nmage -v\n\n# Build for M4 Mac (ARM64 Linux)\nmage -v build:linuxARM64\n\n# List all available Mage targets\nmage -l\n```\n\n**Frontend builds:**\n\n```bash\n# Production build\nnpm run build\n\n# Alternative Docker setup (without auto-reload)\nnpm run server\n```\n\n**Testing:**\n\n```bash\n# Run unit tests with file watching\nnpm run test\n\n# Run unit tests once (for CI)\nnpm run test:ci\n\n# Run E2E tests (using Playwright)\n# First, spin up a Grafana instance to test against:\nnpm run server\n# Optionally specify Grafana version (recommended dev target):\nGRAFANA_VERSION=12.3.3 npm run server\n# Validate minimum supported version compatibility:\nGRAFANA_VERSION=12.2.5 npm run server\n# Then run the E2E tests:\nnpm run e2e\n```\n\n**Code Quality:**\n\n```bash\n# Run linter\nnpm run lint\n\n# Auto-fix linting issues\nnpm run lint:fix\n```\n\n## CI/CD and Distribution\n\nThis plugin uses Grafana's standardized CI/CD workflows for automated building, testing, and publishing.\n\n## Automated Build Pipeline\n\nThe CI pipeline automatically:\n\n- **Builds and tests** the plugin on every push and PR\n- **Creates signed ZIP files** for all supported platforms\n- **Uploads artifacts** to GitHub Actions and GCS storage\n- **Runs E2E tests** using Playwright\n\n### Key Developer Questions\n\n**Q: Does the CI pipeline produce a signed plugin ZIP?**  \nA: Yes, the CI automatically builds and signs ZIP files for all platforms (universal + per-architecture for the Go backend).\n\n**Q: Where are the ZIP files uploaded?**  \nA: ZIP files are uploaded to:\n\n- GitHub Actions artifacts (for PRs and development)\n- GCS storage (for release artifacts)\n\n**Q: How can I use these ZIPs on Grafana Cloud?**  \nA: For Grafana Cloud deployment, use the **\"Plugins - CD\"** workflow in the Actions tab to publish to dev/ops/prod environments.\n\n## Releasing\n\nThis repository uses a **two-step release process**:\n\n1. **GitHub Release** (via `release.yml`) — Created automatically when you push a version tag\n2. **Catalog Publishing** (via `publish.yaml`) — Manual workflow to publish to Grafana Cloud environments\n\n### Why Two Separate Workflows?\n\nWe want GitHub releases with downloadable artifacts to be available **as soon as a version is tagged**, regardless of whether it's published to the Grafana catalog. This allows:\n\n- QA and testers to download and verify the plugin before catalog publishing\n- Transparency about what version exists, even if only deployed to dev/ops\n- A clear audit trail of all released versions\n\nThe standard `plugin-ci-workflows` only creates GitHub releases when publishing to prod. Our custom `release.yml` fills this gap by creating releases on any tag push.\n\n### Creating a Release\n\nSince `main` is protected, releases are a two-step process:\n\n**Step 1: Version bump PR**\n\n```bash\n# Create a release branch\ngit checkout -b release/v1.2.3\n\n# Bump version (updates package.json and package-lock.json)\nnpm version patch --no-git-tag-version  # or minor/major\n\n# Commit the version bump\ngit add package.json package-lock.json\ngit commit -m \"chore: release v1.2.3\"\n\n# Push and create PR\ngit push -u origin release/v1.2.3\n```\n\nWait for CI to pass, then merge the PR.\n\n**Step 2: Tag the release**\n\n```bash\n# After merging, pull main and create the tag\ngit checkout main \u0026\u0026 git pull\ngit tag v1.2.3\ngit push origin v1.2.3\n```\n\nThe tag push triggers the `release.yml` workflow, which creates a GitHub release with signed plugin artifacts. You can then publish to the catalog whenever you're ready.\n\n## Publishing Workflow\n\nTo publish the plugin to the Grafana catalog:\n\n1. Go to **Actions** → **\"Plugins - CD\"** → **\"Run workflow\"**\n2. Choose target environment: `dev`, `ops`, `prod-canary`, or `prod`\n3. The workflow will build, sign, and publish automatically\n\n### Testing Feature Branches\n\nYou can deploy any branch (not just `main`) to test changes before merging:\n\n**Why:** This lets you test your feature in a real Grafana Cloud environment before merging to `main`, catching integration issues early.\n\n**How:**\n\n- Set **branch** to your feature/PR branch name (e.g., `feature/new-query-builder`)\n- Set **environment** to `dev` (safe testing environment)\n- Plugin version becomes `x.y.z+COMMIT_SHA` (e.g., `1.2.3+a1b2c3d4`)\n\n**Result:** Your exact commit gets deployed to Grafana Cloud dev with a unique version identifier, allowing safe testing without affecting other developers or environments.\n\n## For External Contributors \u0026 Open Source Community\n\n**This section is for developers outside Grafana Labs** who want to fork this repository and distribute their own version independently.\n\n### CI/CD for External Developers\n\nThe GitHub Actions workflows in this repository (`push.yaml` and `publish.yaml`) are designed for Grafana's internal infrastructure and **will not work** for external contributors.\n\nIf you're forking this repo, you should:\n\n1. **Revert to the previous CI workflows** that come with a newly bootstrapped plugin - these contain the basic build, test, and packaging logic without Grafana-specific deployment steps\n2. **Use manual plugin signing** for distribution to your own Grafana instances\n\n### Manual Plugin Signing\n\nFor private distribution or local development:\n\n```bash\nnpm install -g @grafana/sign-plugin\nnpx @grafana/sign-plugin --rootUrls https://your-grafana-instance.com\n```\n\nThis allows you to sign and distribute your fork without going through Grafana's official plugin catalog or internal infrastructure.\n\n## Learn more\n\nBelow you can find source code for existing app plugins and other related documentation.\n\n- [Basic data source plugin example](https://github.com/grafana/grafana-plugin-examples/tree/master/examples/datasource-basic#readme)\n- [`plugin.json` documentation](https://grafana.com/developers/plugin-tools/reference/plugin-json)\n- [How to sign a plugin?](https://grafana.com/developers/plugin-tools/publish-a-plugin/sign-a-plugin)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrafana%2Fgrafana-cube-datasource","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrafana%2Fgrafana-cube-datasource","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrafana%2Fgrafana-cube-datasource/lists"}