Skip to content

fix(cube-cli): Link the MSVC runtime statically on Windows - #12395

Open
MikeNitsenko wants to merge 3 commits into
masterfrom
claude/gallant-wu-671c55
Open

MikeNitsenko wants to merge 3 commits into
masterfrom
claude/gallant-wu-671c55

Conversation

@MikeNitsenko

@MikeNitsenko MikeNitsenko commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Check List

  • Tests have been run in packages where changes have been made if available
  • Linter has been run for changed code
  • Tests for the changes have been added if not covered yet
  • Docs have been added / updated if required

Description of Changes Made

On a fresh Windows Server 2019 machine, cube.exe installed with install-cli.ps1 doesn't start: cube --version prints nothing and exits with -1073741515 (0xC0000135, STATUS_DLL_NOT_FOUND). The x86_64-pc-windows-msvc build links the C runtime dynamically, so it needs VCRUNTIME140.dll from the Visual C++ redistributable, which a stock Windows Server doesn't have.

  • Static CRT. rust/cube-cli/.cargo/config.toml sets -C target-feature=+crt-static for x86_64-pc-windows-msvc. Both the CI build (cube-cli.yml) and the release build (publish.yml) run cargo from rust/cube-cli, so both pick it up, and so do local Windows builds.
  • No RUSTFLAGS in CI. actions-rust-lang/setup-rust-toolchain sets RUSTFLAGS=-D warnings by default, and a RUSTFLAGS env var overrides target.<triple>.rustflags from the config file. Both cube-cli jobs now pass rustflags: "", as the other Rust jobs in this repo do. The lint job's cargo clippy -- -D warnings still denies warnings.
  • Regression check. GitHub's Windows runners have the VC++ runtime installed, so running the binary there can't catch this. The Windows CI job now runs dumpbin /dependents on the release cube.exe and fails if it imports vcruntime*/msvcp*. On the first commit of this PR (the check alone), it failed as expected, listing VCRUNTIME140.dll: failed run.
  • Installer. install-cli.ps1 used to print Installed to … with an empty version when the binary couldn't run. It now runs the downloaded cube.exe --version before copying it over an existing install, checks $LASTEXITCODE, and throws with the exit code in decimal and hex (throw, not exit, so an irm | iex session isn't closed).

Testing

  • Windows CI: with the fix, the Windows job passes. dumpbin lists only OS DLLs (kernel32, advapi32, bcrypt, ws2_32, …): no VCRUNTIME140.dll, and the api-ms-win-crt-* imports are gone too. The Windows tests ran against the static CRT build, and every other target is green.
  • install-cli.ps1: ran the changed lines under pwsh with a binary that exits non-zero (throws with the exit code and leaves the existing cube.exe in place) and one that prints a version (prints Installed <version> to …). -1073741515 formats as 0xC0000135.
  • actionlint (same version as the Lint CI Workflows job) passes on the changed workflows.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the pr:community Contribution from Cube.js community members. label Oct 23, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the rust Pull requests that update Rust code label Oct 23, 2026
@MikeNitsenko
MikeNitsenko marked this pull request as ready for review October 23, 2026 12:27
@claude

claude Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @MikeNitsenko's task in 1m 12s —— View job


Looks good to merge. 0 high, 0 medium, 1 low.

Review details
  • Read diff and changed files
  • Check publish.yml / docs for related bits
  • Review threads
  • Post review

Findings

  • Low install-cli.ps1:35: the --version check runs only after Copy-Item has overwritten $Dir\cube.exe. If an upgrade brings a binary that won't start, the install throws, but the user's working CLI has already been replaced. Running the check against $Tmp\cube.exe before the copy avoids this (inline comment).

Checked, no issues

  • Static CRT config. rust/cube-cli/.cargo/config.toml is picked up by both builds. cube-cli.yml sets working-directory: rust/cube-cli as a job default, and the publish.yml Build step sets it on the step. Both pass --target, so the flag reaches only target artifacts, not host build scripts.
  • rustflags: "". This matches the other Rust jobs in publish.yml (lines 34, 124, 213, …). Clippy in the lint job still runs with -D warnings.
  • dumpbin guard. The step still fails when something goes wrong. If vswhere finds nothing, & $null is a terminating error. If dumpbin fails, for example on a wrong path, it exits non-zero, and the pwsh wrapper's exit $LASTEXITCODE fails the step. -match is case-insensitive and filters the output array, so any VCRUNTIME140.dll/MSVCP140.dll line fails the check. The api-ms-win-crt-*/ucrtbase imports correctly aren't flagged, since the UCRT ships with Windows 10 and Server 2016 or later.
  • Installer exit code. When VCRUNTIME140.dll is missing, the process does start and then exits with 0xC0000135, so $LASTEXITCODE catches it. '{0:X8}' -f -1073741515 gives C0000135. Using throw instead of exit keeps an irm | iex session open.
  • Comments. Each is 3 lines or fewer, and each would stop a later edit from bringing the bug back (for example, a RUSTFLAGS env var silently overriding the config).
  • Docs. No docs change is needed. docs-mintlify/reference/cli.mdx never says the VC++ redistributable is required, so this is a bug fix that makes the CLI do what the docs already say.
  • Not flagged: the release job in publish.yml has no dumpbin guard of its own. A future job-level RUSTFLAGS there (like the one the cubestore job sets at line 696) would quietly reintroduce the dynamic CRT. The PR CI check only covers cube-cli.yml. Optional: copy the check step into the release job.

Review threads

The listing returned no prior threads from me (0 resolved, 0 re-affirmed). I posted 1 new inline comment.

Comment thread install-cli.ps1 Outdated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@claude

claude Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @MikeNitsenko's task in 41s —— View job


No issues found. The previous round's low finding (the version check ran after the copy) is fixed: 0 high, 0 medium, 0 low.

Review details
  • Read the diff, the full changed files, and the previous review
  • Re-checked install-cli.ps1 after the latest commit
  • Handled review threads
  • Posted the review

Re-check of the latest commit

  • Previous finding fixed. In install-cli.ps1:33-41, the installer now runs $Tmp\cube.exe --version and checks $LASTEXITCODE before Copy-Item, so a binary that won't start no longer replaces a working install. The error message says $Dir was left unchanged, and that's now true.
  • Other ways the new binary can fail. If tar fails silently and cube.exe is missing, or the image isn't a valid Win32 app, & $Extracted raises a terminating error under $ErrorActionPreference = "Stop". That error is also thrown before the copy, and the finally still cleans up $Tmp. If a user sets $PSNativeCommandUseErrorActionPreference, PowerShell throws its own error before the custom throw runs. The install is still left untouched.

Unchanged from last round, no issues

  • Build config. rust/cube-cli/.cargo/config.toml is picked up by both the CI and release builds. rustflags: "" matches the other Rust jobs, and the lint job still runs clippy with -D warnings.
  • dumpbin guard. A missing vswhere/dumpbin result or a non-zero dumpbin exit still fails the step. -match 'vcruntime|msvcp' correctly ignores the api-ms-win-crt-* UCRT imports.
  • Comments. Each is 3 lines or fewer and guards against reintroducing the bug.
  • Docs. No docs change is needed. This is a bug fix, and docs-mintlify/reference/cli.mdx never says the VC++ redistributable is required.
  • Not flagged (optional): the release job in publish.yml has no dumpbin guard of its own, so a future job-level RUSTFLAGS there would go unnoticed.

Review threads

The listing returned 0 unresolved threads from me, so I resolved none and re-affirmed none. The previous round's thread no longer appears in the unresolved list. I posted no new inline comments.

MikeNitsenko added a commit that referenced this pull request Oct 23, 2026
…12397)

## Summary

Adds a step-by-step PowerShell section to the [Kerberos
page](https://docs.cube.dev/reference/core-data-apis/dax-api/kerberos)
for Microsoft Entra Domain Services. From a Windows Server machine
joined to the managed domain, it creates the keytab account, registers
the SPN, generates the keytab with `ktpass /pass +rndPass`, and uploads
it with `cube variables set` (the same env var the Settings → Power BI
upload writes).

Fixes to the existing text, found while testing:
- The generic `ktpass` example now passes `/mapuser CUBE\account`. A
bare name fails with `DsCrackNames returned 0x2` when the account has no
display name (e.g., created with `New-ADUser`).
- `ktpass` resets the account's password, so each deployment needs its
own keytab account; the generic prompt text no longer implies the
existing password.
- Windows Server is required: `ktpass` isn't part of RSAT on Windows 10.
- `method=kerberos` / `method=ntlm` log lines only appear with
`CUBEJS_LOG_LEVEL=trace`.

## Test plan

- [x] Ran every step end to end on a Windows Server 2019 VM joined to an
Entra Domain Services managed domain (RC4 disabled), against a GCP
deployment; Power BI Desktop on a domain-joined client connected with
Kerberos.
- [x] `yarn broken-links` reports no new broken links (3 pre-existing
ones in `api-reference/introduction.mdx` and `docs.json` reproduce
without this change).
- [x] Rendered the page with `mintlify dev`: 6 steps, all code blocks
intact.

## Merge note

Safe to merge before the CLI release. Until #12395 ships,
the Windows `cube.exe` needs the VC++ runtime, which stock Windows
Server doesn't have; the CLI step has a short note with the two commands
that install it.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:community Contribution from Cube.js community members. rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant