earshot 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ target/
2
+ __pycache__/
3
+ *.so
4
+ *.egg-info/
5
+ dist/
@@ -0,0 +1,287 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "autocfg"
7
+ version = "1.5.0"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
10
+
11
+ [[package]]
12
+ name = "cfg-if"
13
+ version = "1.0.4"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
16
+
17
+ [[package]]
18
+ name = "earshot"
19
+ version = "1.0.0"
20
+ source = "registry+https://github.com/rust-lang/crates.io-index"
21
+ checksum = "d393a8f23619412e0502df1b94cd148e34855a50a4143d365cc6336cc338b4f4"
22
+ dependencies = [
23
+ "libm",
24
+ ]
25
+
26
+ [[package]]
27
+ name = "earshot-python"
28
+ version = "0.1.0"
29
+ dependencies = [
30
+ "earshot",
31
+ "ndarray",
32
+ "numpy",
33
+ "pyo3",
34
+ ]
35
+
36
+ [[package]]
37
+ name = "heck"
38
+ version = "0.5.0"
39
+ source = "registry+https://github.com/rust-lang/crates.io-index"
40
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
41
+
42
+ [[package]]
43
+ name = "indoc"
44
+ version = "2.0.7"
45
+ source = "registry+https://github.com/rust-lang/crates.io-index"
46
+ checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
47
+ dependencies = [
48
+ "rustversion",
49
+ ]
50
+
51
+ [[package]]
52
+ name = "libc"
53
+ version = "0.2.184"
54
+ source = "registry+https://github.com/rust-lang/crates.io-index"
55
+ checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
56
+
57
+ [[package]]
58
+ name = "libm"
59
+ version = "0.2.16"
60
+ source = "registry+https://github.com/rust-lang/crates.io-index"
61
+ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
62
+
63
+ [[package]]
64
+ name = "matrixmultiply"
65
+ version = "0.3.10"
66
+ source = "registry+https://github.com/rust-lang/crates.io-index"
67
+ checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08"
68
+ dependencies = [
69
+ "autocfg",
70
+ "rawpointer",
71
+ ]
72
+
73
+ [[package]]
74
+ name = "memoffset"
75
+ version = "0.9.1"
76
+ source = "registry+https://github.com/rust-lang/crates.io-index"
77
+ checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
78
+ dependencies = [
79
+ "autocfg",
80
+ ]
81
+
82
+ [[package]]
83
+ name = "ndarray"
84
+ version = "0.16.1"
85
+ source = "registry+https://github.com/rust-lang/crates.io-index"
86
+ checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841"
87
+ dependencies = [
88
+ "matrixmultiply",
89
+ "num-complex",
90
+ "num-integer",
91
+ "num-traits",
92
+ "portable-atomic",
93
+ "portable-atomic-util",
94
+ "rawpointer",
95
+ ]
96
+
97
+ [[package]]
98
+ name = "num-complex"
99
+ version = "0.4.6"
100
+ source = "registry+https://github.com/rust-lang/crates.io-index"
101
+ checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
102
+ dependencies = [
103
+ "num-traits",
104
+ ]
105
+
106
+ [[package]]
107
+ name = "num-integer"
108
+ version = "0.1.46"
109
+ source = "registry+https://github.com/rust-lang/crates.io-index"
110
+ checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
111
+ dependencies = [
112
+ "num-traits",
113
+ ]
114
+
115
+ [[package]]
116
+ name = "num-traits"
117
+ version = "0.2.19"
118
+ source = "registry+https://github.com/rust-lang/crates.io-index"
119
+ checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
120
+ dependencies = [
121
+ "autocfg",
122
+ ]
123
+
124
+ [[package]]
125
+ name = "numpy"
126
+ version = "0.24.0"
127
+ source = "registry+https://github.com/rust-lang/crates.io-index"
128
+ checksum = "a7cfbf3f0feededcaa4d289fe3079b03659e85c5b5a177f4ba6fb01ab4fb3e39"
129
+ dependencies = [
130
+ "libc",
131
+ "ndarray",
132
+ "num-complex",
133
+ "num-integer",
134
+ "num-traits",
135
+ "pyo3",
136
+ "pyo3-build-config",
137
+ "rustc-hash",
138
+ ]
139
+
140
+ [[package]]
141
+ name = "once_cell"
142
+ version = "1.21.4"
143
+ source = "registry+https://github.com/rust-lang/crates.io-index"
144
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
145
+
146
+ [[package]]
147
+ name = "portable-atomic"
148
+ version = "1.13.1"
149
+ source = "registry+https://github.com/rust-lang/crates.io-index"
150
+ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
151
+
152
+ [[package]]
153
+ name = "portable-atomic-util"
154
+ version = "0.2.6"
155
+ source = "registry+https://github.com/rust-lang/crates.io-index"
156
+ checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3"
157
+ dependencies = [
158
+ "portable-atomic",
159
+ ]
160
+
161
+ [[package]]
162
+ name = "proc-macro2"
163
+ version = "1.0.106"
164
+ source = "registry+https://github.com/rust-lang/crates.io-index"
165
+ checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
166
+ dependencies = [
167
+ "unicode-ident",
168
+ ]
169
+
170
+ [[package]]
171
+ name = "pyo3"
172
+ version = "0.24.2"
173
+ source = "registry+https://github.com/rust-lang/crates.io-index"
174
+ checksum = "e5203598f366b11a02b13aa20cab591229ff0a89fd121a308a5df751d5fc9219"
175
+ dependencies = [
176
+ "cfg-if",
177
+ "indoc",
178
+ "libc",
179
+ "memoffset",
180
+ "once_cell",
181
+ "portable-atomic",
182
+ "pyo3-build-config",
183
+ "pyo3-ffi",
184
+ "pyo3-macros",
185
+ "unindent",
186
+ ]
187
+
188
+ [[package]]
189
+ name = "pyo3-build-config"
190
+ version = "0.24.2"
191
+ source = "registry+https://github.com/rust-lang/crates.io-index"
192
+ checksum = "99636d423fa2ca130fa5acde3059308006d46f98caac629418e53f7ebb1e9999"
193
+ dependencies = [
194
+ "once_cell",
195
+ "target-lexicon",
196
+ ]
197
+
198
+ [[package]]
199
+ name = "pyo3-ffi"
200
+ version = "0.24.2"
201
+ source = "registry+https://github.com/rust-lang/crates.io-index"
202
+ checksum = "78f9cf92ba9c409279bc3305b5409d90db2d2c22392d443a87df3a1adad59e33"
203
+ dependencies = [
204
+ "libc",
205
+ "pyo3-build-config",
206
+ ]
207
+
208
+ [[package]]
209
+ name = "pyo3-macros"
210
+ version = "0.24.2"
211
+ source = "registry+https://github.com/rust-lang/crates.io-index"
212
+ checksum = "0b999cb1a6ce21f9a6b147dcf1be9ffedf02e0043aec74dc390f3007047cecd9"
213
+ dependencies = [
214
+ "proc-macro2",
215
+ "pyo3-macros-backend",
216
+ "quote",
217
+ "syn",
218
+ ]
219
+
220
+ [[package]]
221
+ name = "pyo3-macros-backend"
222
+ version = "0.24.2"
223
+ source = "registry+https://github.com/rust-lang/crates.io-index"
224
+ checksum = "822ece1c7e1012745607d5cf0bcb2874769f0f7cb34c4cde03b9358eb9ef911a"
225
+ dependencies = [
226
+ "heck",
227
+ "proc-macro2",
228
+ "pyo3-build-config",
229
+ "quote",
230
+ "syn",
231
+ ]
232
+
233
+ [[package]]
234
+ name = "quote"
235
+ version = "1.0.45"
236
+ source = "registry+https://github.com/rust-lang/crates.io-index"
237
+ checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
238
+ dependencies = [
239
+ "proc-macro2",
240
+ ]
241
+
242
+ [[package]]
243
+ name = "rawpointer"
244
+ version = "0.2.1"
245
+ source = "registry+https://github.com/rust-lang/crates.io-index"
246
+ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
247
+
248
+ [[package]]
249
+ name = "rustc-hash"
250
+ version = "2.1.2"
251
+ source = "registry+https://github.com/rust-lang/crates.io-index"
252
+ checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
253
+
254
+ [[package]]
255
+ name = "rustversion"
256
+ version = "1.0.22"
257
+ source = "registry+https://github.com/rust-lang/crates.io-index"
258
+ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
259
+
260
+ [[package]]
261
+ name = "syn"
262
+ version = "2.0.117"
263
+ source = "registry+https://github.com/rust-lang/crates.io-index"
264
+ checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
265
+ dependencies = [
266
+ "proc-macro2",
267
+ "quote",
268
+ "unicode-ident",
269
+ ]
270
+
271
+ [[package]]
272
+ name = "target-lexicon"
273
+ version = "0.13.5"
274
+ source = "registry+https://github.com/rust-lang/crates.io-index"
275
+ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
276
+
277
+ [[package]]
278
+ name = "unicode-ident"
279
+ version = "1.0.24"
280
+ source = "registry+https://github.com/rust-lang/crates.io-index"
281
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
282
+
283
+ [[package]]
284
+ name = "unindent"
285
+ version = "0.2.4"
286
+ source = "registry+https://github.com/rust-lang/crates.io-index"
287
+ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
@@ -0,0 +1,15 @@
1
+ [package]
2
+ name = "earshot-python"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+ readme = "README.md"
6
+
7
+ [lib]
8
+ name = "earshot_python"
9
+ crate-type = ["cdylib"]
10
+
11
+ [dependencies]
12
+ pyo3 = { version = "0.24", features = ["extension-module", "abi3-py38"] }
13
+ numpy = "0.24"
14
+ earshot = "1.0"
15
+ ndarray = "0.16"
earshot-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,65 @@
1
+ Metadata-Version: 2.4
2
+ Name: earshot
3
+ Version: 0.1.0
4
+ Requires-Dist: numpy>=1.20
5
+ Requires-Dist: scipy>=1.7
6
+ Summary: Python bindings for earshot - fast VAD in Rust
7
+ License: MIT OR Apache-2.0
8
+ Requires-Python: >=3.8
9
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
10
+
11
+ # earshot-python
12
+
13
+ Python bindings for [earshot](https://github.com/pykeio/earshot) - fast VAD in Rust.
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pip install earshot
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ```python
24
+ import earshot
25
+ import numpy as np
26
+
27
+ audio = np.load("audio.npy")
28
+ segments = earshot.detect(audio, sr=16000)
29
+
30
+ for start, end in segments:
31
+ print(f"Speech: {start:.2f}s - {end:.2f}s")
32
+ ```
33
+
34
+ ## Development
35
+
36
+ ### Building from Source
37
+
38
+ ```bash
39
+ # Clone the repository
40
+ git clone https://codeberg.org/yourusername/earshot-python
41
+ cd earshot-python
42
+
43
+ # Install in development mode
44
+ pip install -e .
45
+
46
+ # Or build wheels
47
+ maturin build --release
48
+ ```
49
+
50
+ ### Releasing
51
+
52
+ This project uses a manual release process. See [RELEASE.md](RELEASE.md) for detailed instructions.
53
+
54
+ Quick release:
55
+ ```bash
56
+ ./release.sh --test # TestPyPI first
57
+ ./release.sh # Production PyPI
58
+ ```
59
+
60
+ Requirements:
61
+ - Rust toolchain
62
+ - Docker Desktop
63
+ - PyPI API token in `~/.pypirc`
64
+ ```
65
+
@@ -0,0 +1,54 @@
1
+ # earshot-python
2
+
3
+ Python bindings for [earshot](https://github.com/pykeio/earshot) - fast VAD in Rust.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install earshot
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```python
14
+ import earshot
15
+ import numpy as np
16
+
17
+ audio = np.load("audio.npy")
18
+ segments = earshot.detect(audio, sr=16000)
19
+
20
+ for start, end in segments:
21
+ print(f"Speech: {start:.2f}s - {end:.2f}s")
22
+ ```
23
+
24
+ ## Development
25
+
26
+ ### Building from Source
27
+
28
+ ```bash
29
+ # Clone the repository
30
+ git clone https://codeberg.org/yourusername/earshot-python
31
+ cd earshot-python
32
+
33
+ # Install in development mode
34
+ pip install -e .
35
+
36
+ # Or build wheels
37
+ maturin build --release
38
+ ```
39
+
40
+ ### Releasing
41
+
42
+ This project uses a manual release process. See [RELEASE.md](RELEASE.md) for detailed instructions.
43
+
44
+ Quick release:
45
+ ```bash
46
+ ./release.sh --test # TestPyPI first
47
+ ./release.sh # Production PyPI
48
+ ```
49
+
50
+ Requirements:
51
+ - Rust toolchain
52
+ - Docker Desktop
53
+ - PyPI API token in `~/.pypirc`
54
+ ```
@@ -0,0 +1,281 @@
1
+ # Release Guide for earshot-python
2
+
3
+ This document describes how to build and publish wheels for the `earshot` package to PyPI.
4
+
5
+ ## Overview
6
+
7
+ Since this project uses Codeberg (not GitHub) for hosting, we use a **manual release process** instead of automated CI/CD. The release is performed from your local machine using the provided scripts.
8
+
9
+ ### Platform Support
10
+
11
+ | Platform | Architecture | Method | Status |
12
+ |----------|-------------|--------|--------|
13
+ | Linux | x86_64 | Docker (manylinux2014) | ✅ Supported |
14
+ | Linux | ARM64 | Docker (manylinux2014) | ✅ Supported |
15
+ | macOS | ARM64 | Native (your machine) | ✅ Supported |
16
+ | macOS | x86_64 | Cross-compile | ✅ Supported |
17
+ | Windows | x86_64/ARM64 | Not available | ❌ Not built (source install works) |
18
+
19
+ **Note:** Windows users can install from the source distribution, which will compile the Rust extension locally (requires Rust toolchain).
20
+
21
+ ## Prerequisites
22
+
23
+ ### Required Software
24
+
25
+ 1. **Rust toolchain** (latest stable)
26
+ ```bash
27
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
28
+ rustup target add x86_64-apple-darwin aarch64-apple-darwin
29
+ ```
30
+
31
+ 2. **Python packages**
32
+ ```bash
33
+ pip install maturin twine
34
+ ```
35
+
36
+ 3. **Docker Desktop** with:
37
+ - Linux/amd64 support (enabled by default)
38
+ - Linux/arm64 support (enable in Settings → Features → "Use containerd for pulling and storing images")
39
+
40
+ 4. **PyPI credentials** in `~/.pypirc`:
41
+ ```ini
42
+ [pypi]
43
+ username = __token__
44
+ password = pypi-your-api-token-here
45
+
46
+ [testpypi]
47
+ username = __token__
48
+ password = pypi-your-test-token-here
49
+ ```
50
+
51
+ Get your token from: https://pypi.org/manage/account/#api-tokens
52
+
53
+ ## Quick Start
54
+
55
+ ### Standard Release
56
+
57
+ ```bash
58
+ ./release.sh
59
+ ```
60
+
61
+ This interactive script will:
62
+ 1. Check prerequisites
63
+ 2. Optionally bump the version
64
+ 3. Build wheels for all platforms
65
+ 4. Validate with `twine check`
66
+ 5. Upload to PyPI
67
+
68
+ ### Test Release (TestPyPI)
69
+
70
+ ```bash
71
+ ./release.sh --test
72
+ ```
73
+
74
+ Uploads to TestPyPI first to verify everything works:
75
+ - Install with: `pip install --index-url https://test.pypi.org/simple/ earshot`
76
+
77
+ ### Dry Run (Build only, no upload)
78
+
79
+ ```bash
80
+ ./release.sh --dry-run
81
+ ```
82
+
83
+ Builds all wheels but doesn't upload - useful for testing the build process.
84
+
85
+ ### Re-upload (skip build)
86
+
87
+ ```bash
88
+ ./release.sh --skip-build
89
+ ```
90
+
91
+ If you already have wheels in `dist/` and want to re-upload them.
92
+
93
+ ## Version Management
94
+
95
+ ### Bump Version Interactively
96
+
97
+ During `release.sh`, you'll be prompted to bump the version. Options:
98
+ - `p` or `patch`: 0.1.0 → 0.1.1
99
+ - `m` or `minor`: 0.1.0 → 0.2.0
100
+ - `M` or `major`: 0.1.0 → 1.0.0
101
+ - `s` or `set`: Enter custom version
102
+ - `n` or `no`: Keep current version
103
+
104
+ ### Bump Version Manually
105
+
106
+ ```bash
107
+ # Patch release (bug fixes)
108
+ python scripts/bump_version.py patch
109
+
110
+ # Minor release (new features)
111
+ python scripts/bump_version.py minor
112
+
113
+ # Major release (breaking changes)
114
+ python scripts/bump_version.py major
115
+
116
+ # Set explicit version
117
+ python scripts/bump_version.py --version 1.2.3
118
+ ```
119
+
120
+ This updates both `Cargo.toml` and `pyproject.toml` in sync.
121
+
122
+ ## Build Process Details
123
+
124
+ ### What's Built
125
+
126
+ 1. **Source Distribution** (`.tar.gz`)
127
+ - Contains Rust source and Python files
128
+ - Installable on any platform with Rust toolchain
129
+
130
+ 2. **Linux Wheels** (`.whl`)
131
+ - Built in Docker containers for manylinux2014 compliance
132
+ - Works on most Linux distributions (glibc 2.17+)
133
+ - Two architectures: x86_64 and ARM64 (aarch64)
134
+
135
+ 3. **macOS Wheels** (`.whl`)
136
+ - Built natively on your Apple Silicon Mac
137
+ - Universal2 not needed due to abi3 (single wheel per arch)
138
+ - Two architectures: x86_64 (Intel) and ARM64 (Apple Silicon)
139
+
140
+ ### ABI3 Advantage
141
+
142
+ The `abi3-py38` feature in `Cargo.toml` means:
143
+ - **One wheel per platform** covers Python 3.8 through 3.12+
144
+ - **Smaller total release size**
145
+ - **Faster build times**
146
+
147
+ Without abi3, you'd need 4-5 wheels per platform (one per Python version).
148
+
149
+ ## Troubleshooting
150
+
151
+ ### Docker Issues
152
+
153
+ **Problem:** "Cannot connect to Docker daemon"
154
+ ```bash
155
+ # Solution: Start Docker Desktop
156
+ open -a Docker
157
+ ```
158
+
159
+ **Problem:** "Linux ARM64 build fails"
160
+ ```bash
161
+ # Solution: Enable containerd in Docker Desktop
162
+ # Settings → Features → "Use containerd for pulling and storing images"
163
+ ```
164
+
165
+ ### Build Issues
166
+
167
+ **Problem:** "Rust target not found"
168
+ ```bash
169
+ # Solution: Add missing target
170
+ rustup target add x86_64-unknown-linux-gnu # Not needed for Docker builds
171
+ rustup target add x86_64-apple-darwin
172
+ rustup target add aarch64-apple-darwin
173
+ ```
174
+
175
+ **Problem:** "missing dependencies: numpy, scipy"
176
+ ```bash
177
+ # Solution: The wheels don't bundle numpy/scipy
178
+ # These are declared as dependencies in pyproject.toml
179
+ # pip will install them automatically when users install earshot
180
+ ```
181
+
182
+ ### Upload Issues
183
+
184
+ **Problem:** "Invalid API token"
185
+ ```bash
186
+ # Solution: Check your .pypirc
187
+ cat ~/.pypirc
188
+ # Ensure token includes 'pypi-' prefix
189
+ ```
190
+
191
+ **Problem:** "File already exists" on re-upload
192
+ ```bash
193
+ # PyPI doesn't allow overwriting files
194
+ # Solution: Bump version or use TestPyPI
195
+ ./release.sh --test
196
+ ```
197
+
198
+ ## Manual Steps (without script)
199
+
200
+ If you prefer not to use the script, here's the manual process:
201
+
202
+ ```bash
203
+ # 1. Clean
204
+ rm -rf dist target/wheels
205
+
206
+ # 2. Bump version (edit Cargo.toml and pyproject.toml manually)
207
+ # version = "0.1.0" → "0.1.1"
208
+
209
+ # 3. Build sdist
210
+ maturin sdist -o dist
211
+
212
+ # 4. Build Linux x86_64
213
+ docker run --rm -v $(pwd):/io ghcr.io/pyo3/maturin build --release --manylinux 2014
214
+
215
+ # 5. Build Linux ARM64 (if Docker supports it)
216
+ docker run --rm --platform linux/arm64 -v $(pwd):/io ghcr.io/pyo3/maturin build --release --manylinux 2014 --target aarch64-unknown-linux-gnu
217
+
218
+ # 6. Build macOS ARM64
219
+ maturin build --release --target aarch64-apple-darwin
220
+
221
+ # 7. Build macOS x86_64
222
+ maturin build --release --target x86_64-apple-darwin
223
+
224
+ # 8. Check
225
+ twine check dist/*
226
+
227
+ # 9. Upload to TestPyPI first
228
+ twine upload --repository testpypi dist/*
229
+
230
+ # 10. Upload to PyPI
231
+ twine upload dist/*
232
+
233
+ # 11. Tag release
234
+ git add Cargo.toml pyproject.toml
235
+ git commit -m "Release v0.1.1"
236
+ git tag v0.1.1
237
+ git push origin main
238
+ git push origin v0.1.1
239
+ ```
240
+
241
+ ## Post-Release Checklist
242
+
243
+ After releasing:
244
+
245
+ - [ ] Verify package on PyPI: https://pypi.org/project/earshot/
246
+ - [ ] Test install: `pip install earshot --upgrade`
247
+ - [ ] Push git commit and tag to Codeberg
248
+ - [ ] Verify wheels are available for your platform: `pip debug --verbose | grep compatible`
249
+ - [ ] Optional: Create release notes on Codeberg
250
+
251
+ ## Release Schedule Recommendations
252
+
253
+ **Patch releases (0.1.0 → 0.1.1):**
254
+ - Bug fixes only
255
+ - Can release anytime
256
+ - Users upgrade automatically with `pip install -U earshot`
257
+
258
+ **Minor releases (0.1.0 → 0.2.0):**
259
+ - New features, backward compatible
260
+ - Consider announcing on Codeberg
261
+
262
+ **Major releases (0.1.0 → 1.0.0):**
263
+ - Breaking changes
264
+ - Provide migration guide
265
+ - Consider deprecation warnings in previous release
266
+
267
+ ## Security Notes
268
+
269
+ - **Never commit `.pypirc`** - Keep it in your home directory only
270
+ - **Use API tokens, not passwords** - Scoped to specific projects
271
+ - **Rotate tokens regularly** - Delete and recreate on PyPI periodically
272
+ - **Use TestPyPI first** - Always test before production release
273
+ - **Verify checksums** - The script runs `twine check` automatically
274
+
275
+ ## Questions?
276
+
277
+ If you encounter issues:
278
+ 1. Check this troubleshooting section
279
+ 2. Review maturin docs: https://maturin.rs/
280
+ 3. Review PyPI publishing guide: https://packaging.python.org/
281
+ 4. Open an issue on Codeberg