From 1ee8afeec3c2c7e3087df6f7b586c27601758fe8 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Jul 2026 21:06:06 +0000 Subject: [PATCH] feat(cube-cli): add data-model enable-branch / disable-branch commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expose the per-branch staging-environment toggle (Settings → Staging Environments in the UI) through the CLI, so keeping a shared branch's staging environment always active can be scripted from CI: cube data-model enable-branch DEPLOYMENT_ID BRANCH cube data-model disable-branch DEPLOYMENT_ID BRANCH Both call the new `PUT /build/api/v1/deployments/{id}/branches/staging-environment` endpoint with `{ branchName, enabled }`, mirroring how `embed enable-dashboard` / `disable-dashboard` drive their boolean endpoint. `data-model branches` now reports the state as an ENABLED column. Its previous DEFAULT / CURRENT columns read `isDefault` / `isCurrent`, which the branches endpoint does not return, so they always rendered empty; they are replaced with PARENT and ENABLED, which it does return. Docs: CLI reference (command table + Git-workflow section), the new endpoint in the Control Plane API reference, and a pointer from the staging-environments section of the deployment-environments page. --- .../admin/deployment/environments.mdx | 12 +++- docs-mintlify/reference/cli.mdx | 16 ++++- docs-mintlify/reference/control-plane-api.mdx | 63 +++++++++++++++++++ rust/cube-cli/README.md | 2 +- rust/cube-cli/src/commands/data_model.rs | 62 +++++++++++++++++- 5 files changed, 149 insertions(+), 6 deletions(-) diff --git a/docs-mintlify/admin/deployment/environments.mdx b/docs-mintlify/admin/deployment/environments.mdx index 2efbcceb9e519..ecf9eafa68a72 100644 --- a/docs-mintlify/admin/deployment/environments.mdx +++ b/docs-mintlify/admin/deployment/environments.mdx @@ -52,6 +52,14 @@ regardless of user activity. +The same toggle is available in the [CLI][ref-cli] and the [Control Plane +API][ref-control-plane-api-staging], so it can be scripted, e.g. from CI: + +```bash +cube data-model enable-branch DEPLOYMENT_ID BRANCH_NAME +cube data-model disable-branch DEPLOYMENT_ID BRANCH_NAME +``` + ### Resources and costs Staging environments run on Shared deployments, incurring [relevant @@ -115,4 +123,6 @@ credentials**][ref-credentials]. [ref-overview]: /admin/connect-to-data/visualization-tools [ref-credentials]: /admin/connect-to-data/visualization-tools [ref-version]: /admin/deployment#cube-version -[ref-version-channel]: /admin/deployment#update-channels \ No newline at end of file +[ref-version-channel]: /admin/deployment#update-channels +[ref-cli]: /reference/cli +[ref-control-plane-api-staging]: /reference/control-plane-api#buildapiv1deploymentsdeployment_idbranchesstaging-environment \ No newline at end of file diff --git a/docs-mintlify/reference/cli.mdx b/docs-mintlify/reference/cli.mdx index 30113c5cb6cb9..79580dd27ed43 100644 --- a/docs-mintlify/reference/cli.mdx +++ b/docs-mintlify/reference/cli.mdx @@ -151,7 +151,7 @@ Run `cube --help` for the full options of any command. | `logs` | Tail deployment pod logs (`--pod`, `-c/--container`, `--source production\|dev`) | | `regions` | List available deployment regions | | `github` (`gh`) | GitHub integration: `status`, `installations`, `repos`, `branches`, `connect` | -| `data-model` | Data model files and Git workflow: `list`, `get`, `put`, `delete`, `rename`, `file-hashes`, `branches`, `create-branch`, `dev-mode`, `commit`, `pull`, `merge`, `merge-to-default` | +| `data-model` | Data model files and Git workflow: `list`, `get`, `put`, `delete`, `rename`, `file-hashes`, `branches`, `create-branch`, `enable-branch`/`disable-branch`, `dev-mode`, `commit`, `pull`, `merge`, `merge-to-default` | | `environments` | Deployment environments and environment tokens | | `variables` | Deployment environment variables | | `folders`, `workbooks`, `reports`, `workspace` | Workspace content management | @@ -178,6 +178,19 @@ cube data-model merge-to-default DEPLOYMENT_ID --branch my-branch -m "add orders `merge-to-default` merges into the deploy branch and rebuilds production. +`enable-branch` keeps a shared branch's [staging environment][ref-staging-env] +always active, so it stays queryable without anyone viewing the branch in the +UI — useful for running tests against a branch from CI. `disable-branch` reverts +to the default, where the environment is only active while viewed. +`cube data-model branches DEPLOYMENT_ID` shows the current state per branch, and +`cube environments list DEPLOYMENT_ID --type staging` lists the enabled ones with +their API credentials. + +```bash +cube data-model enable-branch DEPLOYMENT_ID my-branch +cube data-model disable-branch DEPLOYMENT_ID my-branch +``` + ## Environment variables | Variable | Description | @@ -200,3 +213,4 @@ or explicitly with `CUBE_NO_TELEMETRY=1` (or the legacy `CUBEJS_TELEMETRY=false` [ref-api-keys]: /admin/account-billing/api-keys [ref-rest-api]: /reference/core-data-apis/rest-api/index +[ref-staging-env]: /admin/deployment/environments#staging-environments diff --git a/docs-mintlify/reference/control-plane-api.mdx b/docs-mintlify/reference/control-plane-api.mdx index 3b02a5264086f..66b9683849104 100644 --- a/docs-mintlify/reference/control-plane-api.mdx +++ b/docs-mintlify/reference/control-plane-api.mdx @@ -212,6 +212,67 @@ Example response: ``` +### `/build/api/v1/deployments/{deployment_id}/branches/staging-environment` + +Send a `PUT` request to enable or disable a branch, i.e. to control whether its +[staging environment][ref-environments-staging] stays always active. Disabled +(the default), a staging environment is only active while the branch is viewed +in the Cube UI; enabled, it remains active and accessible regardless of user +activity, and it is reported by +[`/api/v1/deployments/{deployment_id}/environments`](#apiv1deploymentsdeployment_idenvironments) +as a `staging` environment. + +Only shared branches can be enabled — personal development branches and the +production branch are rejected. + + + +Note the `/build` prefix: data model and branch endpoints are served by the +build API. + + + +Path parameters: + +| Parameter | Description | +| --- | --- | +| `deployment_id` | The deployment ID | + +Body parameters: + +| Parameter | Description | Required | +| --- | --- | --- | +| `enabled` | `true` enables the branch, `false` disables it | Yes | +| `branchName` | Name of the branch to update | One of `branchName` or `branchId` | +| `branchId` | ID of the branch to update, as returned by `GET /build/api/v1/deployments/{deployment_id}/branches` | One of `branchName` or `branchId` | + +Example request: + +```bash +curl -X PUT \ + -H "Authorization: Bearer YOUR_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{"branchName": "staging", "enabled": true}' \ + "https://YOUR_CUBE_CLOUD_HOST/build/api/v1/deployments/123/branches/staging-environment" +``` + +Example response: + +```json +{ + "data": { + "id": 456, + "name": "staging", + "parentBranch": "main", + "lastHash": "9f2c1ab", + "isStagingEnvironmentEnabled": true + } +} +``` + +The same operation is available in the [CLI][ref-cli] as +`cube data-model enable-branch` / `cube data-model disable-branch`. + ### `/api/v1/audit-logs/export` Send a `GET` request to export [audit log][ref-audit-log] events as a CSV @@ -262,6 +323,8 @@ curl \ [ref-metadata-api]: /reference/core-data-apis/rest-api/reference#metadata-api [ref-deployments]: /admin/deployment [ref-environments]: /admin/deployment/environments +[ref-environments-staging]: /admin/deployment/environments#staging-environments +[ref-cli]: /reference/cli [ref-api-keys]: /admin/account-billing/api-keys [ref-security-context]: /docs/data-modeling/access-control/context [ref-audit-log]: /admin/monitoring/audit-log \ No newline at end of file diff --git a/rust/cube-cli/README.md b/rust/cube-cli/README.md index b5cefd81e612f..1a010a36e3a6f 100644 --- a/rust/cube-cli/README.md +++ b/rust/cube-cli/README.md @@ -132,7 +132,7 @@ Every endpoint of the Console Server public API is covered: | `regions` | list available deployment regions | | `logs` | tail deployment pod logs (`--pod`, `-c/--container`; defaults to the Cube API container) | | `github` (`gh`) | status, installations, repos, branches, connect (import a repo into a deployment + first build) | -| `data-model` (`dm`) | list, get, put, delete, rename files; branches, create-branch, dev-mode, exit-dev-mode, commit, pull. File writes only land on a **dev-mode branch**: `dev-mode ` forks a personal `dev-…` branch and prints its name — pass that via `--branch` (or omit `--branch` to use your active dev-mode branch); puts to any other branch are rejected by the API | +| `data-model` (`dm`) | list, get, put, delete, rename files; branches, create-branch, enable-branch, disable-branch, dev-mode, exit-dev-mode, commit, pull. File writes only land on a **dev-mode branch**: `dev-mode ` forks a personal `dev-…` branch and prints its name — pass that via `--branch` (or omit `--branch` to use your active dev-mode branch); puts to any other branch are rejected by the API. `enable-branch` / `disable-branch` toggle whether a shared branch's staging environment stays always active (vs. only while viewed in the UI); `branches` reports it as `ENABLED` and `environments list --type staging` lists the enabled ones | | `environments` | list, tokens, create-token (incl. `--meta-sync`) | | `variables` | list, set (`KEY=VALUE` upserts) | | `folders` | list, create, update, delete, ancestors | diff --git a/rust/cube-cli/src/commands/data_model.rs b/rust/cube-cli/src/commands/data_model.rs index 17784ccf60885..c89fb522c119b 100644 --- a/rust/cube-cli/src/commands/data_model.rs +++ b/rust/cube-cli/src/commands/data_model.rs @@ -4,7 +4,7 @@ use anyhow::{Context as _, Result}; use clap::Subcommand; use serde_json::json; -use crate::client::Query; +use crate::client::{Client, Query}; use crate::{output, util, Ctx}; /// Manage a deployment's data model files (schema). @@ -96,6 +96,21 @@ enum Cmd { #[arg(long)] dev_mode: bool, }, + /// Enable a branch: keep its staging environment always active + EnableBranch { + /// Deployment id + deployment: i64, + /// Branch to enable (a shared branch — not a personal dev branch) + branch: String, + }, + /// Disable a branch: its staging environment is active only while the + /// branch is viewed in Cube Cloud + DisableBranch { + /// Deployment id + deployment: i64, + /// Branch to disable + branch: String, + }, /// Enter dev mode on a branch (prints the personal dev-mode branch that /// file writes must target) DevMode { @@ -221,6 +236,41 @@ fn write_body( util::body(body) } +/// Enabling a branch keeps its staging environment always active and accessible +/// at `/dev-mode//cubejs-api/v1`; disabled (the default) +/// it is only active while someone views the branch in Cube Cloud. Enabled +/// branches are the ones `cube environments list --type staging` reports. Only +/// shared branches qualify — personal dev branches are served as your own +/// development environment, and the deploy branch is production. +async fn set_branch_enabled( + api: &Client, + ctx: &Ctx, + deployment: i64, + branch: &str, + enabled: bool, +) -> Result<()> { + let body = json!({ "branchName": branch, "enabled": enabled }); + let res = api + .put( + &format!("/build/api/v1/deployments/{deployment}/branches/staging-environment"), + Some(&body), + ) + .await?; + if ctx.json { + output::print_json(&res); + } else if enabled { + output::success(&format!( + "Enabled branch {branch}; its staging environment stays active \ + (see `cube environments list {deployment} --type staging`)" + )); + } else { + output::success(&format!( + "Disabled branch {branch}; its staging environment is active only while viewed" + )); + } + Ok(()) +} + fn read_content(file: Option, content: Option) -> Result { if let Some(path) = file { return std::fs::read_to_string(&path).with_context(|| format!("failed to read {path}")); @@ -351,8 +401,8 @@ pub async fn command(args: Args, ctx: &Ctx) -> Result<()> { &res, &[ ("NAME", "name"), - ("DEFAULT", "isDefault"), - ("CURRENT", "isCurrent"), + ("PARENT", "parentBranch"), + ("ENABLED", "isStagingEnvironmentEnabled"), ], ); } @@ -384,6 +434,12 @@ pub async fn command(args: Args, ctx: &Ctx) -> Result<()> { } } } + Cmd::EnableBranch { deployment, branch } => { + set_branch_enabled(&api, ctx, deployment, &branch, true).await?; + } + Cmd::DisableBranch { deployment, branch } => { + set_branch_enabled(&api, ctx, deployment, &branch, false).await?; + } Cmd::DevMode { deployment, branch } => { let body = json!({ "branchName": branch }); let res = api