feat(cube-cli): GitHub import, upload deploy, install/self-update, telemetry#11291
Conversation
Drop the ai-engineer command group (AI Engineer settings) from the CLI: delete the commands/ai_engineer module, its dispatch in main.rs, and the README coverage row. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 22s —— View job Code ReviewVerdict: LGTM — clean, mechanical removal. ✅ Details
Findings
Nits: none. |
Add a github command group (alias gh) covering the new GitHub integration public REST API: - github status — link/install state + browser URLs - github installations — the user's GitHub App installations - github repos <installation> — repositories visible to an installation - github branches <owner/repo> --installation <id> — repo branches - github connect <deployment> <owner/repo> --installation <id> [--branch] — build-served import: clones the repo into the deployment's git storage and triggers the first build Also make the device-flow token poll resilient to transient network failures: a dropped connection mid-poll now keeps polling until the device code expires instead of aborting the login. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 1m 4s —— View job Code ReviewVerdict: LGTM — the ai-engineer removal is clean, and the new Details
Scope Two commits on this branch:
Housekeeping
Nits
|
Cube Cloud answers unknown API routes with 200 + the SPA HTML. Detect an HTML body on a successful response and fail with "endpoint is not available on this tenant" instead of treating the page as a JSON string, which rendered as a misleading empty table. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 1m 10s —— View job Code ReviewVerdict: LGTM — the ai-engineer removal, the new Details
Scope Three commits on this branch:
The PR title/description still describe only the ai-engineer removal, so a reader looking only at the description will miss the github feature and the client fix. Consider expanding the body (or splitting) so reviewers know to look at all three.
The retry-on-transport-error is the right call — a server redeploy mid-login shouldn't nuke the device-code flow. Bounded by
Nice UX fix. Two thoughts:
Housekeeping
Nits
|
Align the github installations/repos/branches table columns with the field names the API actually returns (installationId/login, name/ htmlUrl, name/isDefault), verified against staging. Restore the default SIGPIPE disposition on unix so piping output (e.g. `cube github repos ... | head`) exits quietly instead of panicking with a broken-pipe backtrace. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 1m 4s —— View job Code ReviewVerdict: LGTM on the new commit ( Details
What's new in Two independent fixes:
Prior findings — status against current tip Still open (not blocking):
Housekeeping
|
The connect endpoint takes the repository as `name` (the owner is implied by the installation), so send installationId/name/branch and accept either a plain repo name or owner/repo on the command line. Verified end-to-end against staging: connect clones the repo into the deployment's git storage, and the typed error paths (already connected, deployment not found) surface cleanly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 45s —— View job Code Review — commit
|
Add `deployments advance-step` and `deployments reset-step` for the
new dedicated onboarding endpoints (POST /creation-step/advance with
{creationStep}, POST /creation-step/reset) now that creationStep is
stripped from the generic update input.
Give `data-model commit` a --branch flag (sent as branchName) so a
non-dev-mode branch can be committed, matching the other branch-aware
data-model commands.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 59s —— View job Code Review — commit
|
Reimplements the legacy `cubejs deploy` on the public API as `cube deploy`: hash local files (sha1), diff against GET data-model/file-hashes, upload only changed files through the transactional multipart endpoints (upload/start, upload/file, upload/finish), and finish with a manifest that prunes deleted files (--keep-missing opts out) and triggers a single build. Adds `deployments build-status` (normalized build/dev-mode status with compile-error text), `data-model file-hashes`, `deployments advance-step`/`reset-step` for the new onboarding endpoints, and `data-model commit --branch`. The HTTP client gains a multipart POST with the same 401 auto-refresh retry as JSON requests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 1m 16s —— View job Code Review — commit
|
Manage API keys for programmatic access: list, create (secret returned once), get, delete/revoke. API keys are accepted as the Bearer credential across all public APIs; `cube login --api-key` stores one as a context. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 51s —— View job Code Review — commit
|
Distribution and self-update: - install/install.sh (Linux/macOS) and install/install.ps1 (Windows) download the latest release asset for the detected platform and install it onto PATH; CUBE_INSTALL_DIR and CUBE_VERSION override location/tag. - Every run spawns a background check against the GitHub releases API and prints an update notice (stderr, interactive terminals only) after the command output; CUBE_NO_UPDATE_CHECK=1 disables it. Skipped for `completion` (shell-eval'd) and `update` itself. - `cube update` downloads the latest release, extracts the binary, and atomically replaces the running executable (rename-aside strategy that also works on Windows, with rollback on failure and stale-.old cleanup on the next run). `cube update --check` only reports. - reqwest now uses rustls-tls-native-roots so SSL_CERT_FILE and OS-installed CAs are honored (TLS-inspecting corporate proxies) — still rustls, still static-musl-friendly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 1m 51s —— View job Code Review — commit
|
Adds telemetry mirroring the legacy cubejs CLI's track() from @cubejs-backend/shared: events POST to track.cube.dev/track as a JSON array with the same field names (event, cliVersion, clientTimestamp, id, platform/arch in Node vocabulary, anonymousId, sentFrom, sentAt) so they land in the existing pipeline. anonymousId is a SHA-256 of the OS machine id (dbus/systemd id, IOPlatformUUID, MachineGuid — same sources as the legacy machine-id module), hostname fallback. Emitted events: one 'Cube CLI Command' per invocation (command group + success flag), 'Error' with the error text on failure, and the legacy names 'Cube Cloud CLI Authenticate' on login and 'Cube Cloud CLI Deploy'/'Deploy Success' around cube deploy. Flush is bounded (2s, silent failure) and runs after command output; completion is exempt. Disabled in CI (CI env, legacy parity) and via CUBE_NO_TELEMETRY=1 or CUBEJS_TELEMETRY=false. CUBE_TELEMETRY_URL overrides the sink for testing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 2m 7s —— View job Code Review — commit
|
Cube Cloud API keys authenticate as `Authorization: Api-Key <key>` rather than Bearer. The client now picks the scheme per credential: three-segment JWTs (OAuth access tokens, legacy deploy JWTs) send Bearer, opaque keys send Api-Key; CUBE_AUTH_SCHEME=bearer|api-key overrides the heuristic. `cube deploy` gains -m/--message, forwarded as commitMessage on upload/finish. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 1m 6s —— View job Code Review — commit
|
`cube logs <deployment> [--pod] [--container]` tails the deployment's pod logs via GET /api/v1/deployments/:id/logs (same source as the UI logs page; cube-store pods excluded server-side). Renders as `date [pod] message` lines, raw with --json. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 50s —— View job Code Review — commit
|
The server now defaults to the cubejs-server (Cube API) container; document the known containers in --help and add the -c short form. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 40s —— View job Code Review — commit
|
…orker) Forward the logs endpoint's new ?source= param: production (default, pod-based) or dev (dev-mode worker logs; --pod/--container ignored). Verified on staging: source=dev surfaced the real crash-loop error of a deployment whose production pods never scheduled. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 47s —— View job Code Review — commit
|
Shortens the install one-liners: curl -fsSL https://raw.githubusercontent.com/cube-js/cube/master/install-cli.sh | sh irm https://raw.githubusercontent.com/cube-js/cube/master/install-cli.ps1 | iex Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdcyqFwUF9BbWLeX4uERnk
|
Claude finished @paveltiunov's task in 42s —— View job Code Review — commit
|
Check List
Description of Changes Made
Follow-up batch to #11289 for the Cube CLI (
rust/cube-cli). Everything below was verified end-to-end against Cube Cloud staging.New commands
cube github(gh) — the GitHub import flow:status,installations,repos,branches, andconnect(clones a repo into the deployment's git storage and triggers the first build;installationId/name/branchcontract).cube deploy— the legacycubejs deployreimplemented on the public API: SHA-1 hashes local files, diffs againstGET …/data-model/file-hashes, uploads only changed files through the transactional multipart endpoints (upload/start→upload/file→upload/finish), prunes deleted files (--keep-missingopts out), sets a-m/--messagecommit message, and triggers a single build. Verified idempotent (unchanged tree → 0 uploads).cube deployments build-status— normalized build/dev-mode status incl. compile-error text;cube deployments advance-step/reset-step— the new onboarding endpoints;cube data-model file-hashes;cube data-model commit --branch.cube api-keys— list/create/get/delete (for the upcoming public API-key CRUD).cube update— self-update: downloads the latest release asset for the platform and atomically swaps the running binary (rename-aside, Windows-safe, rollback on failure). Every run also checks for a newer release in the background and prints a notice on interactive terminals (CUBE_NO_UPDATE_CHECK=1opts out).Install scripts (
install/):install.sh(Linux/macOS) andinstall.ps1(Windows) download the latest release binary for the detected platform and put it onPATH(CUBE_INSTALL_DIR,CUBE_VERSIONoverrides).Telemetry: anonymous usage events wire-compatible with the legacy
cubejsCLI pipeline (track.cube.dev): oneCube CLI Commandevent per invocation plus the legacyCube Cloud CLI Authenticate/Deploy/Deploy Success/Errornames; anonymous id is a SHA-256 of the OS machine id. Disabled in CI or viaCUBE_NO_TELEMETRY=1/CUBEJS_TELEMETRY=false.Auth: API keys are sent as
Authorization: Api-Key …— the client picks the scheme per credential (JWT →Bearer, opaque key →Api-Key;CUBE_AUTH_SCHEMEoverrides). Verified against staging with an admin API key across base-served, build-served, and scoped endpoints.Robustness fixes found while testing: device-login polling survives transient connection resets; 200-with-HTML responses (unknown route → SPA fallback) produce a clear "endpoint not available on this tenant" error; TLS uses
rustls-tls-native-rootssoSSL_CERT_FILE/OS CAs work behind TLS-inspecting proxies (still rustls, still static-musl); SIGPIPE restored on unix so piped output doesn't panic; github tables use the real API field names.Removed: the
ai-engineercommand group.🤖 Generated with Claude Code
Generated by Claude Code