Phase 1 + Phase 2 (npm scope) for issue #188: cargo-binstall + npm distribution#189
Merged
Conversation
- Release workflow now produces clickhousectl-{target}-v{version}.tar.gz
archives containing a directory of the same name with the binary
inside, matching the cargo-binstall naming convention. Smoke test and
install.sh updated to consume the new archive layout.
- Add publish-crates job to release.yml that publishes both crates on
tag (requires CARGO_REGISTRY_TOKEN secret).
- Add description / license / repository / keywords / categories /
[package.metadata.binstall] to clickhousectl. Correct cloud-api
license MIT -> Apache-2.0 to match the repo LICENSE.
- README: document cargo binstall, cargo install, and the new archive
naming for direct downloads.
Issue: #188
Adds an npm/ wrapper package that downloads the matching prebuilt clickhousectl binary from the GitHub release at install time, and a publish-npm job in release.yml that publishes it to npm using OIDC trusted publishing (no long-lived NPM_TOKEN). Single-package postinstall layout (vs. dist's subpackage approach) — simpler to reason about and decoupled from any future cargo-dist migration. Exposes both `clickhousectl` and `chctl` bin commands. publish-crates is now idempotent for clickhouse-cloud-api: it skips the publish step when the version is already on crates.io, so the API client can lag behind clickhousectl version bumps. Phase 2 brew / shell / PS installers and the full cargo-dist migration are intentionally deferred — npm-only is the scope of this commit. One-time setup the maintainer still needs to do for the next tag: - Squat the `clickhousectl` name on crates.io (cargo publish) and npm (manual seed publish with a granular token). - Configure the npm trusted publisher on npmjs.com pointing at ClickHouse/clickhousectl + release.yml + publish-npm. - Add CARGO_REGISTRY_TOKEN repo secret. Issue: #188
chmod +x on the shim file matches how npm will land it on install, and makes `./bin/cli.js` directly invokable when developing locally. Plus ignore the npm/vendor, package-lock, *.tgz, and node_modules paths produced when packing or running install.js by hand.
Lets us trigger workflow_dispatch on a branch to validate the build matrix, static-linking check, smoke tests, and archive format without risking a junk GitHub Release named after the branch. publish-crates and publish-npm already had this guard; release didn't.
10 tasks
iskakaushik
approved these changes
May 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes part of #188.
Adds two installation paths for
clickhousectlso the obviouscargo binstallandnpm install -gincantations work after the next tag. Brew, the shell installer, full cargo-dist migration, and PyPI (Phase 3) are intentionally not in this PR — they will follow.Summary
Phase 1 — cargo-binstall + crates.io readiness
release.ymlbuilds now produceclickhousectl-{target}-v{version}.tar.gzarchives, each containing a single directory of the same name with theclickhousectlbinary inside (the cargo-binstall naming convention). Smoke-test job andinstall.shupdated to consume the new layout.publish-cratesjob tags-trigger publishes both crates to crates.io. It is idempotent forclickhouse-cloud-api(skips when the version is already on crates.io) so the API client can lag behindclickhousectlversion bumps.crates/clickhousectl/Cargo.tomlgainsdescription,license = "Apache-2.0",repository,homepage,keywords,categories, and an explicit[package.metadata.binstall]block.crates/clickhouse-cloud-api/Cargo.tomllicense correctedMIT→Apache-2.0to match the repo LICENSE; same metadata fields added.cargo binstall,cargo install clickhousectl, and direct-download sections.Phase 2 (npm scope only)
npm/wrapper package:bin/cli.jsshim execs the binary thatinstall.jsdownloads from the matching GitHub release at install time (single-package postinstall layout — simpler than dist's subpackage approach and decoupled from any future cargo-dist migration). Exposes bothclickhousectlandchctlbin commands.publish-npmjob inrelease.yml: usesid-token: writefor npm OIDC trusted publishing, runsnpm publish --provenance --access public, and deliberately does not setNODE_AUTH_TOKEN(per npm docs, even an empty value short-circuits the OIDC flow).actions/setup-node@v6.4.0by SHA to match the zizmor hardening style.One-time manual setup before the next tag
CARGO_REGISTRY_TOKENrepo secret for crates.io publishes.clickhousectlon crates.io (first publish viacargo publishlocally) and on npm (seed publish with a granular token).ClickHouse/clickhousectl+release.yml+ thepublish-npmjob; revoke the granular npm token once OIDC is wired.Test plan
Most of this is workflow / packaging plumbing that only runs on a tag push, so the meaningful tests are:
cargo metadataandcargo build --workspacesucceed with the new manifests.cargo publish --dry-run -p clickhouse-cloud-apipackages cleanly.npm pack --dry-runinnpm/produces a tarball with the expected 4 files.node --checkpasses forinstall.jsandbin/cli.js.release.ymlYAML parses; job graph isbuild → smoke-test → release → {publish-crates, publish-npm}.clickhousectl-{target}-v{version}.tar.gz,cargo binstall clickhousectlresolves from crates.io,npm install -g clickhousectlinstalls the binary on macOS + Linux.🤖 Generated with Claude Code