Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,83 @@ jobs:
- name: Publish
working-directory: npm
run: npm publish --provenance --access public

build-wheels:
name: Build wheel (${{ matrix.target }})
needs: release
runs-on: ${{ matrix.os }}
if: startsWith(github.ref, 'refs/tags/v')
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
manylinux: '2_28'
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
manylinux: '2_28'
- target: x86_64-unknown-linux-musl
os: ubuntu-latest
manylinux: musllinux_1_2
- target: aarch64-unknown-linux-musl
os: ubuntu-latest
manylinux: musllinux_1_2
- target: x86_64-apple-darwin
os: macos-latest
manylinux: 'off'
- target: aarch64-apple-darwin
os: macos-latest
manylinux: 'off'

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Align Cargo version with tag
run: |
VERSION="${GITHUB_REF_NAME#v}"
# Force the wheel version to match the release tag in case the in-repo
# Cargo.toml was not bumped before tagging. Mirrors the npm step above.
sed -i.bak -E "0,/^version = \"[^\"]*\"$/s//version = \"${VERSION}\"/" \
crates/clickhousectl/Cargo.toml
rm crates/clickhousectl/Cargo.toml.bak

- name: Build wheel
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
with:
target: ${{ matrix.target }}
manylinux: ${{ matrix.manylinux }}
working-directory: pypi
args: --release --out dist

- name: Upload wheel artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: wheel-${{ matrix.target }}
path: pypi/dist/*.whl

publish-pypi:
name: Publish to PyPI
needs: build-wheels
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
# `id-token: write` is required for PyPI OIDC trusted publishing. The
# publisher action picks up OIDC automatically when no token input is
# provided.
permissions:
id-token: write
contents: read
steps:
- name: Download wheel artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: wheels
pattern: wheel-*
merge-multiple: true

- name: Publish
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
with:
packages-dir: wheels
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
/npm/package-lock.json
/npm/*.tgz
/npm/README.md
/pypi/target/
/pypi/dist/
.env
/.env
/.env.local
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ cargo add -p clickhouse-cloud-api url
- If the user references a GitHub issue (e.g. "work on issue 3"), use `gh issue view 3` to get the details, then create a branch like `issue-3-short-description`.
- Update `README.md` and any relevant documentation as part of the change — PRs should include doc updates for new or changed functionality.
- Commit to the branch, push, and create a PR with `gh pr create`.
- Releases are done by tagging `main` (e.g. `git tag v0.1.4 && git push origin v0.1.4`), which triggers the GitHub Actions release workflow. Bump all of these to the same version in lockstep: `crates/clickhousectl/Cargo.toml` (`version` and the `clickhouse-cloud-api` dep version), `crates/clickhouse-cloud-api/Cargo.toml`, and `npm/package.json`. The workflow also re-aligns `npm/package.json` to the tag at publish time, but bump it in the repo too so the source-of-truth matches. Release-time secrets: `CARGO_REGISTRY_TOKEN` for crates.io; npm uses OIDC trusted publishing (configured one-time on npmjs.com against this repo, `release.yml`, and the `publish-npm` job).
- Releases are done by tagging `main` (e.g. `git tag v0.1.4 && git push origin v0.1.4`), which triggers the GitHub Actions release workflow. Bump all of these to the same version in lockstep: `crates/clickhousectl/Cargo.toml` (`version` and the `clickhouse-cloud-api` dep version), `crates/clickhouse-cloud-api/Cargo.toml`, and `npm/package.json`. The workflow also re-aligns `npm/package.json` to the tag at publish time, but bump it in the repo too so the source-of-truth matches. `pypi/pyproject.toml` does *not* need a manual bump — maturin pulls the wheel version from `crates/clickhousectl/Cargo.toml` (via `dynamic = ["version"]`), and the `build-wheels` job also re-aligns the Cargo version to the tag at publish time. Release-time secrets: `CARGO_REGISTRY_TOKEN` for crates.io; npm uses OIDC trusted publishing (configured one-time on npmjs.com against this repo, `release.yml`, and the `publish-npm` job); PyPI uses OIDC trusted publishing (configured one-time on pypi.org against this repo, `release.yml`, and the `publish-pypi` job).

## Testing locally

Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ npm install -g clickhousectl

This installs an npm wrapper package that downloads the matching prebuilt binary from `builds.clickhouse.com` at install time. Both `clickhousectl` and `chctl` are exposed as commands. If you use `npm install --ignore-scripts`, the download is skipped — fall back to one of the other install paths.

### pip

```bash
pip install clickhousectl
# or
pipx install clickhousectl
# or
uv tool install clickhousectl
```

This installs a prebuilt wheel containing the matching `clickhousectl` binary. Linux (glibc and musl, x86_64 and aarch64) and macOS (Intel and Apple Silicon) wheels are published to PyPI.

### From crates.io

Builds from source:
Expand Down
19 changes: 19 additions & 0 deletions pypi/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[build-system]
requires = ["maturin>=1.7,<2.0"]
build-backend = "maturin"

[project]
name = "clickhousectl"
dynamic = ["version", "description", "license", "readme", "authors", "urls"]
requires-python = ">=3.9"
keywords = ["clickhouse", "cli", "database", "cloud"]
classifiers = [
"Development Status :: 4 - Beta",
"Environment :: Console",
"Topic :: Database",
]

[tool.maturin]
bindings = "bin"
manifest-path = "../crates/clickhousectl/Cargo.toml"
strip = true