Publish to pypi
Seto Elkahfi committed
Apr 21, 2026 at 18:13 UTC
b78a23059562630171553391d58465547a21a697
6 files changed
+339
.github/workflows/release-pypi.yml
new
+195
@@ -0,0 +1,195 @@
1
+name: PyPI Release
2
+
3
+on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+ workflow_dispatch:
8
+ inputs:
9
+ tag:
10
+ description: "Release tag (e.g. v0.1.1)"
11
+ required: true
12
+
13
+permissions:
14
+ id-token: write
15
+ contents: read
16
+
17
+env:
18
+ CARGO_TERM_COLOR: always
19
+
20
+jobs:
21
+ build-wheels:
22
+ name: Build PyPI wheels
23
+ runs-on: ${{ matrix.build.OS }}
24
+ strategy:
25
+ fail-fast: false
26
+ matrix:
27
+ build:
28
+ - {
29
+ NAME: linux-x64-glibc,
30
+ OS: ubuntu-latest,
31
+ TARGET: x86_64-unknown-linux-gnu,
32
+ MANYLINUX: "2014",
33
+ }
34
+ - {
35
+ NAME: linux-arm64-glibc,
36
+ OS: ubuntu-24.04-arm,
37
+ TARGET: aarch64-unknown-linux-gnu,
38
+ MANYLINUX: "2014",
39
+ }
40
+ - {
41
+ NAME: win32-x64-msvc,
42
+ OS: windows-2022,
43
+ TARGET: x86_64-pc-windows-msvc,
44
+ }
45
+ - {
46
+ NAME: win32-arm64-msvc,
47
+ OS: windows-2022,
48
+ TARGET: aarch64-pc-windows-msvc,
49
+ }
50
+ - {
51
+ NAME: darwin-x64,
52
+ OS: macos-latest,
53
+ TARGET: x86_64-apple-darwin,
54
+ }
55
+ - {
56
+ NAME: darwin-arm64,
57
+ OS: macos-latest,
58
+ TARGET: aarch64-apple-darwin,
59
+ }
60
+ steps:
61
+ - name: Checkout
62
+ uses: actions/checkout@v4
63
+ with:
64
+ ref: ${{ github.event.inputs.tag || github.ref }}
65
+
66
+ - name: Set the release version
67
+ shell: bash
68
+ run: |
69
+ if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
70
+ release_version="${GITHUB_REF_NAME#v}"
71
+ else
72
+ release_version="${{ github.event.inputs.tag }}"
73
+ release_version="${release_version#v}"
74
+ fi
75
+ echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
76
+
77
+ - name: Read Rust toolchain
78
+ shell: bash
79
+ run: |
80
+ rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
81
+ if [ -z "$rust_toolchain" ]; then
82
+ echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
83
+ exit 1
84
+ fi
85
+ echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
86
+
87
+ - name: Install Rust toolchain
88
+ uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
89
+ with:
90
+ toolchain: ${{ env.RUST_TOOLCHAIN }}
91
+
92
+ - name: Install Rust target
93
+ shell: bash
94
+ run: |
95
+ rustup target add ${{ matrix.build.TARGET }} --toolchain ${{ env.RUST_TOOLCHAIN }}
96
+ rustup target list --installed
97
+
98
+ - name: Build wheel
99
+ uses: PyO3/maturin-action@v1
100
+ with:
101
+ target: ${{ matrix.build.TARGET }}
102
+ manylinux: ${{ matrix.build.MANYLINUX || 'off' }}
103
+ working-directory: pypi
104
+ args: --release --locked --compatibility pypi --out dist
105
+ before-script-linux: yum install -y perl-core
106
+
107
+ - name: Upload wheel artifact
108
+ uses: actions/upload-artifact@v4
109
+ with:
110
+ name: wheels-${{ matrix.build.NAME }}
111
+ path: pypi/dist/*
112
+
113
+ build-sdist:
114
+ name: Build source distribution
115
+ runs-on: ubuntu-latest
116
+ steps:
117
+ - name: Checkout
118
+ uses: actions/checkout@v4
119
+ with:
120
+ ref: ${{ github.event.inputs.tag || github.ref }}
121
+
122
+ - name: Read Rust toolchain
123
+ shell: bash
124
+ run: |
125
+ rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
126
+ if [ -z "$rust_toolchain" ]; then
127
+ echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
128
+ exit 1
129
+ fi
130
+ echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
131
+
132
+ - name: Install Rust toolchain
133
+ uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
134
+ with:
135
+ toolchain: ${{ env.RUST_TOOLCHAIN }}
136
+
137
+ - name: Build sdist
138
+ uses: PyO3/maturin-action@v1
139
+ with:
140
+ command: sdist
141
+ working-directory: pypi
142
+ args: --out dist
143
+
144
+ - name: Upload sdist artifact
145
+ uses: actions/upload-artifact@v4
146
+ with:
147
+ name: sdist
148
+ path: pypi/dist/*
149
+
150
+ publish-pypi:
151
+ name: Publish to PyPI
152
+ runs-on: ubuntu-latest
153
+ needs:
154
+ - build-wheels
155
+ - build-sdist
156
+ steps:
157
+ - name: Checkout
158
+ uses: actions/checkout@v4
159
+ with:
160
+ ref: ${{ github.event.inputs.tag || github.ref }}
161
+
162
+ - name: Set the release version
163
+ shell: bash
164
+ run: |
165
+ if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
166
+ release_version="${GITHUB_REF_NAME#v}"
167
+ else
168
+ release_version="${{ github.event.inputs.tag }}"
169
+ release_version="${release_version#v}"
170
+ fi
171
+ echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
172
+
173
+ - name: Download distribution artifacts
174
+ uses: actions/download-artifact@v4
175
+ with:
176
+ pattern: "*"
177
+ path: dist
178
+ merge-multiple: true
179
+
180
+ - name: Check whether release already exists on PyPI
181
+ id: pypi-check
182
+ shell: bash
183
+ run: |
184
+ if curl -fsS "https://pypi.org/pypi/onde-cli/${RELEASE_VERSION}/json" >/dev/null 2>&1; then
185
+ echo "onde-cli ${RELEASE_VERSION} already exists on PyPI, skipping publish"
186
+ echo "exists=true" >> "$GITHUB_OUTPUT"
187
+ else
188
+ echo "exists=false" >> "$GITHUB_OUTPUT"
189
+ fi
190
+
191
+ - name: Publish distribution
192
+ if: steps.pypi-check.outputs.exists != 'true'
193
+ uses: pypa/gh-action-pypi-publish@release/v1
194
+ with:
195
+ skip-existing: true
.gitignore
+1
@@ -1 +1,2 @@
1
/target
2
+/pypi/dist
Cargo.lock
+1
@@ -1774,6 +1774,7 @@ dependencies = [
1774
name = "smbcloud-gresiq-sdk"
1775
version = "0.3.34"
1776
dependencies = [
1777
+ "anyhow",
1778
"log",
1779
"reqwest",
1780
"serde",
pypi/README.md
new
+101
@@ -0,0 +1,101 @@
1
+<p align="center">
2
+ <img src="https://raw.githubusercontent.com/ondeinference/onde/main/assets/onde-inference-logo.svg" alt="Onde Inference" width="96">
3
+</p>
4
+
5
+<h1 align="center">onde-cli</h1>
6
+
7
+<p align="center">
8
+ <strong>Terminal UI for <a href="https://ondeinference.com">Onde Inference</a> — sign up, sign in, and manage your account from the command line.</strong>
9
+</p>
10
+
11
+<p align="center">
12
+ <a href="https://ondeinference.com"><img src="https://img.shields.io/badge/ondeinference.com-235843?style=flat-square&labelColor=17211D" alt="Website"></a>
13
+ <a href="https://pypi.org/project/onde-cli/"><img src="https://img.shields.io/pypi/v/onde-cli?style=flat-square&labelColor=17211D&color=235843" alt="PyPI"></a>
14
+ <a href="https://crates.io/crates/onde-cli"><img src="https://img.shields.io/crates/v/onde-cli?style=flat-square&labelColor=17211D&color=235843" alt="Crates.io"></a>
15
+ <a href="https://github.com/ondeinference/onde-cli/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT%20%2F%20Apache--2.0-235843?style=flat-square&labelColor=17211D" alt="License"></a>
16
+</p>
17
+
18
+---
19
+
20
+## Install
21
+
22
+```sh
23
+pip install onde-cli
24
+```
25
+
26
+This installs the native `onde` executable for your platform directly — no compiler, no runtime dependencies, no Node.js.
27
+
28
+## Usage
29
+
30
+```sh
31
+onde
32
+```
33
+
34
+Opens a terminal UI. Create an account or sign in to your Onde Inference account.
35
+
36
+## Keys
37
+
38
+| Key | Action |
39
+|----------|-----------------------|
40
+| `Tab` | Move between fields |
41
+| `Enter` | Submit / sign out |
42
+| `Ctrl+L` | Go to sign in |
43
+| `Ctrl+N` | Go to new account |
44
+| `Ctrl+C` | Quit |
45
+
46
+## Other Installation Methods
47
+
48
+### Cargo
49
+
50
+```sh
51
+cargo install onde-cli
52
+```
53
+
54
+### From source
55
+
56
+```sh
57
+git clone https://github.com/ondeinference/onde-cli
58
+cd onde-cli
59
+cargo build --release
60
+./target/release/onde
61
+```
62
+
63
+## Platform Support
64
+
65
+Pre-built native binaries are shipped for:
66
+
67
+| Platform | Architecture |
68
+|---------------|---------------|
69
+| macOS | arm64, x64 |
70
+| Linux (glibc) | arm64, x64 |
71
+| Windows | arm64, x64 |
72
+
73
+## Debug
74
+
75
+Logs are written to `~/.cache/onde/debug.log`. Nothing is written to the terminal output.
76
+
77
+## Related
78
+
79
+- [Swift SDK](https://github.com/ondeinference/onde-swift)
80
+- [Flutter SDK](https://pub.dev/packages/onde_inference)
81
+- [React Native SDK](https://www.npmjs.com/package/@ondeinference/react-native)
82
+- [Onde Rust crate](https://crates.io/crates/onde)
83
+
84
+## Source & Issues
85
+
86
+This is a native binary distributed via PyPI. The source code lives at
87
+[github.com/ondeinference/onde-cli](https://github.com/ondeinference/onde-cli).
88
+Please report bugs and feature requests there.
89
+
90
+## License
91
+
92
+Dual-licensed under **MIT** and **Apache 2.0**.
93
+
94
+- [MIT License](https://github.com/ondeinference/onde-cli/blob/main/LICENSE-MIT)
95
+- [Apache License 2.0](https://github.com/ondeinference/onde-cli/blob/main/LICENSE-APACHE)
96
+
97
+---
98
+
99
+<p align="center">
100
+ <sub>© 2026 <a href="https://ondeinference.com">Onde Inference</a></sub>
101
+</p>
\ No newline at end of file
pypi/pyproject.toml
new
+39
@@ -0,0 +1,39 @@
1
+[build-system]
2
+requires = ["maturin>=1.7,<2.0"]
3
+build-backend = "maturin"
4
+
5
+[project]
6
+name = "onde-cli"
7
+description = "Terminal UI for signing up, signing in, and managing your Onde Inference account."
8
+readme = "README.md"
9
+requires-python = ">=3.8"
10
+dynamic = ["version"]
11
+license = { text = "MIT OR Apache-2.0" }
12
+authors = [{ name = "Seto Elkahfi", email = "hej@setoelkahfi.se" }]
13
+keywords = ["onde", "cli", "tui", "inference", "llm", "on-device"]
14
+classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Environment :: Console",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "License :: OSI Approved :: Apache Software License",
20
+ "Operating System :: MacOS",
21
+ "Operating System :: Microsoft :: Windows",
22
+ "Operating System :: POSIX :: Linux",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Rust",
25
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
26
+ "Topic :: Software Development :: Libraries",
27
+ "Topic :: Utilities",
28
+]
29
+
30
+[project.urls]
31
+Homepage = "https://ondeinference.com"
32
+Documentation = "https://ondeinference.com"
33
+Repository = "https://github.com/ondeinference/onde-cli"
34
+Issues = "https://github.com/ondeinference/onde-cli/issues"
35
+
36
+[tool.maturin]
37
+manifest-path = "../Cargo.toml"
38
+bindings = "bin"
39
+strip = true
rust-toolchain.toml
new
+2
@@ -0,0 +1,2 @@
1
+[toolchain]
2
+channel = "stable"