From 68cb673550da90f94a37b5d786c8d68740e071f4 Mon Sep 17 00:00:00 2001 From: CJ Pais Date: Mon, 22 Jun 2026 21:11:44 +0800 Subject: [PATCH 1/3] release: 0.0.4 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- bindings/python/pyproject.toml | 6 +++--- bindings/python/src/transcribe_cpp/__init__.py | 2 +- bindings/rust/transcribe-cpp/Cargo.toml | 4 ++-- .../Sources/TranscribeCpp/TranscribeCpp.swift | 2 +- bindings/typescript/package-lock.json | 14 +++++++------- bindings/typescript/package.json | 12 ++++++------ include/transcribe.h | 2 +- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7ab1d9d9..d5bc656e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -315,7 +315,7 @@ dependencies = [ [[package]] name = "transcribe-cpp" -version = "0.0.3" +version = "0.0.4" dependencies = [ "hound", "log", @@ -325,7 +325,7 @@ dependencies = [ [[package]] name = "transcribe-cpp-sys" -version = "0.0.3" +version = "0.0.4" dependencies = [ "cmake", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 6ed65208..f04ddec2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ [package] name = "transcribe-cpp-sys" -version = "0.0.3" +version = "0.0.4" edition = "2021" rust-version = "1.74" description = "Native FFI bindings for transcribe.cpp, a C/C++ speech-to-text library built on ggml" diff --git a/bindings/python/pyproject.toml b/bindings/python/pyproject.toml index 4df9f276..312b32f2 100644 --- a/bindings/python/pyproject.toml +++ b/bindings/python/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "transcribe-cpp" -version = "0.0.3" +version = "0.0.4" description = "Python bindings for transcribe.cpp" readme = "README.md" # 3.8 is EOL (2024-10); 3.9 is the floor. The binding is ctypes-only, so there @@ -34,13 +34,13 @@ classifiers = [ # packaging fix still resolves); the import-time version/header-hash check in # _library.py is the runtime backstop. check_version_sync.py gates this pin # against include/transcribe.h. -dependencies = ["transcribe-cpp-native==0.0.3.*"] +dependencies = ["transcribe-cpp-native==0.0.4.*"] [project.optional-dependencies] # Opt-in accelerator providers — ADDITIVE: they install alongside the default # provider and the best one wins at runtime. Same base-version pin contract # as the hard dependency (gated by check_version_sync.py). -cu12 = ["transcribe-cpp-native-cu12==0.0.3.*"] +cu12 = ["transcribe-cpp-native-cu12==0.0.4.*"] # Test-only deps. Run with: uv run --extra test pytest (from bindings/python). # numpy is here so the numpy PCM-input tests run in every lane instead of # silently skipping wherever numpy happens to be absent. diff --git a/bindings/python/src/transcribe_cpp/__init__.py b/bindings/python/src/transcribe_cpp/__init__.py index a12e5058..949cd0ad 100644 --- a/bindings/python/src/transcribe_cpp/__init__.py +++ b/bindings/python/src/transcribe_cpp/__init__.py @@ -46,7 +46,7 @@ raise_for_status, ) -__version__ = "0.0.3" +__version__ = "0.0.4" # String-enum types, exported so callers (and type checkers) can name them. Backend = Literal["auto", "cpu", "metal", "vulkan", "cpu_accel", "cuda"] diff --git a/bindings/rust/transcribe-cpp/Cargo.toml b/bindings/rust/transcribe-cpp/Cargo.toml index 41e34dab..44e4d717 100644 --- a/bindings/rust/transcribe-cpp/Cargo.toml +++ b/bindings/rust/transcribe-cpp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "transcribe-cpp" -version = "0.0.3" +version = "0.0.4" edition = "2021" rust-version = "1.74" description = "Rust bindings for transcribe.cpp, a C/C++ speech-to-text library built on ggml" @@ -36,7 +36,7 @@ dynamic-backends = ["shared", "transcribe-cpp-sys/dynamic-backends"] # `transcribe-cpp --no-default-features`, silently re-enabling Metal. The backend # features below forward explicitly, so the default (`metal`) still reaches sys # via `metal = ["transcribe-cpp-sys/metal"]`. -transcribe-cpp-sys = { version = "0.0.3", path = "../../..", default-features = false } +transcribe-cpp-sys = { version = "0.0.4", path = "../../..", default-features = false } thiserror = "2" log = "0.4" diff --git a/bindings/swift/Sources/TranscribeCpp/TranscribeCpp.swift b/bindings/swift/Sources/TranscribeCpp/TranscribeCpp.swift index 5bf9117a..a833d486 100644 --- a/bindings/swift/Sources/TranscribeCpp/TranscribeCpp.swift +++ b/bindings/swift/Sources/TranscribeCpp/TranscribeCpp.swift @@ -17,7 +17,7 @@ public enum Transcribe { /// Version this binding was built against. Pinned here for the pre-1.0 /// base-version load gate; the version-sync milestone will generate it from /// `include/transcribe.h` (the single source of truth) rather than hardcode. - public static let compiledVersion = "0.0.3" + public static let compiledVersion = "0.0.4" /// `MAJOR.MINOR.PATCH` of the linked native library. public static func version() -> String { String(cString: transcribe_version()) } diff --git a/bindings/typescript/package-lock.json b/bindings/typescript/package-lock.json index a6efc688..62783255 100644 --- a/bindings/typescript/package-lock.json +++ b/bindings/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "transcribe-cpp", - "version": "0.0.3", + "version": "0.0.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "transcribe-cpp", - "version": "0.0.3", + "version": "0.0.4", "license": "MIT", "dependencies": { "koffi": "^3.0.2" @@ -19,11 +19,11 @@ "node": ">=22" }, "optionalDependencies": { - "@transcribe-cpp/darwin-arm64-metal": "0.0.3", - "@transcribe-cpp/darwin-x64-cpu": "0.0.3", - "@transcribe-cpp/linux-arm64-cpu-vulkan": "0.0.3", - "@transcribe-cpp/linux-x64-cpu-vulkan": "0.0.3", - "@transcribe-cpp/win32-x64-cpu-vulkan": "0.0.3" + "@transcribe-cpp/darwin-arm64-metal": "0.0.4", + "@transcribe-cpp/darwin-x64-cpu": "0.0.4", + "@transcribe-cpp/linux-arm64-cpu-vulkan": "0.0.4", + "@transcribe-cpp/linux-x64-cpu-vulkan": "0.0.4", + "@transcribe-cpp/win32-x64-cpu-vulkan": "0.0.4" } }, "node_modules/@koromix/koffi-darwin-arm64": { diff --git a/bindings/typescript/package.json b/bindings/typescript/package.json index d17fa8b8..6828be61 100644 --- a/bindings/typescript/package.json +++ b/bindings/typescript/package.json @@ -1,6 +1,6 @@ { "name": "transcribe-cpp", - "version": "0.0.3", + "version": "0.0.4", "description": "TypeScript/Node.js bindings for transcribe.cpp — a C/C++ speech-to-text library built on ggml", "type": "module", "exports": { @@ -38,11 +38,11 @@ "koffi": "^3.0.2" }, "optionalDependencies": { - "@transcribe-cpp/darwin-arm64-metal": "0.0.3", - "@transcribe-cpp/darwin-x64-cpu": "0.0.3", - "@transcribe-cpp/linux-x64-cpu-vulkan": "0.0.3", - "@transcribe-cpp/linux-arm64-cpu-vulkan": "0.0.3", - "@transcribe-cpp/win32-x64-cpu-vulkan": "0.0.3" + "@transcribe-cpp/darwin-arm64-metal": "0.0.4", + "@transcribe-cpp/darwin-x64-cpu": "0.0.4", + "@transcribe-cpp/linux-x64-cpu-vulkan": "0.0.4", + "@transcribe-cpp/linux-arm64-cpu-vulkan": "0.0.4", + "@transcribe-cpp/win32-x64-cpu-vulkan": "0.0.4" }, "devDependencies": { "@types/node": "^22.0.0", diff --git a/include/transcribe.h b/include/transcribe.h index 55f91547..61fcaec1 100644 --- a/include/transcribe.h +++ b/include/transcribe.h @@ -157,7 +157,7 @@ */ #define TRANSCRIBE_VERSION_MAJOR 0 #define TRANSCRIBE_VERSION_MINOR 0 -#define TRANSCRIBE_VERSION_PATCH 3 +#define TRANSCRIBE_VERSION_PATCH 4 #define TRANSCRIBE_VERSION_STRINGIZE_(x) #x #define TRANSCRIBE_VERSION_STRINGIZE(x) TRANSCRIBE_VERSION_STRINGIZE_(x) From e5f1a11cbbe9461b5e31ac294a44cae1c2fa5501 Mon Sep 17 00:00:00 2001 From: CJ Pais Date: Mon, 22 Jun 2026 21:14:32 +0800 Subject: [PATCH 2/3] docs: add RELEASING.md release quickstart --- RELEASING.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 RELEASING.md diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 00000000..8a316c72 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,41 @@ +# Releasing transcribe.cpp + +The version is authored once in `include/transcribe.h` +(`TRANSCRIBE_VERSION_{MAJOR,MINOR,PATCH}`) and duplicated across ~14 files. +`scripts/release/prepare.py` writes all of them and regenerates the FFI; +`prepare.py --check` verifies the whole tree is consistent. A git tag matching +`v[0-9]*` is the **only** trigger for the release pipeline (`publish.yml`), and +the tag run does not re-run the drift gates — so **only ever tag a commit that +has gone green through branch CI on `main`.** + +## Cutting a release (e.g. `0.0.x`) + +```bash +# 1. Branch and write the bump everywhere (header, Cargo/npm/py manifests, +# both lockfiles, Swift, and the regenerated FFI) in one command. +git switch -c release-0.0.x +uv run --no-project scripts/release/prepare.py 0.0.x + +# 2. Verify the tree is release-consistent. Only the version-bump files should +# show as modified; --check must not introduce anything else. +uv run --no-project scripts/release/prepare.py --check +git status --porcelain + +# 3. Commit the bump and push the branch. +git commit -am "release: 0.0.x" +git push -u origin release-0.0.x + +# 4. Open a PR. Wait for ALL branch CI green +# (rust-ci, python-bindings, typescript-ci, swift-ci, native-ci), then merge. +# Branch CI is the real gate — the tag run does NOT re-check it. + +# 5. (optional) Dry run before tagging: full build + TestPyPI, no prod registries. +gh workflow run publish.yml -f version=0.0.x + +# 6. After the PR merges, tag the merged commit on main and push the tag. +# Pulling main puts HEAD on the merge commit, so you tag exactly what CI +# proved. The tag string MUST equal the prepared version. The push publishes. +git checkout main && git fetch origin && git pull +git tag -a v0.0.x -m "transcribe.cpp v0.0.x" +git push origin v0.0.x +``` From c0f3865248bf8cd40136fa6e80a1a5c1b304c30f Mon Sep 17 00:00:00 2001 From: CJ Pais Date: Mon, 22 Jun 2026 21:19:03 +0800 Subject: [PATCH 3/3] rust format --- bindings/rust/transcribe-cpp/tests/device_select.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/bindings/rust/transcribe-cpp/tests/device_select.rs b/bindings/rust/transcribe-cpp/tests/device_select.rs index 009d5e7e..8460acae 100644 --- a/bindings/rust/transcribe-cpp/tests/device_select.rs +++ b/bindings/rust/transcribe-cpp/tests/device_select.rs @@ -11,8 +11,7 @@ fn loaded_model_reports_an_enumerated_device() { // A model loaded with default options resolves a device. That Device has no // registry index (transcribe_model_get_device does not expose one), and it // correlates back to a device from devices() by name (+ device_id when set). - let Some((model_path, _)) = - common::smoke_fixtures("loaded_model_reports_an_enumerated_device") + let Some((model_path, _)) = common::smoke_fixtures("loaded_model_reports_an_enumerated_device") else { return; }; @@ -25,9 +24,9 @@ fn loaded_model_reports_an_enumerated_device() { // It must match one of the enumerated devices by name, and by device_id // when the model device reports one. let all = devices(); - let matched = all.iter().any(|d| { - d.name == dev.name && (dev.device_id.is_none() || d.device_id == dev.device_id) - }); + let matched = all + .iter() + .any(|d| d.name == dev.name && (dev.device_id.is_none() || d.device_id == dev.device_id)); assert!( matched, "model device {dev:?} not found among enumerated devices {all:?}" @@ -37,8 +36,7 @@ fn loaded_model_reports_an_enumerated_device() { #[test] fn negative_gpu_device_is_invalid_argument() { // gpu_device must be >= 0; -1 is rejected before any device lookup. - let Some((model_path, _)) = - common::smoke_fixtures("negative_gpu_device_is_invalid_argument") + let Some((model_path, _)) = common::smoke_fixtures("negative_gpu_device_is_invalid_argument") else { return; };