Add versioning workflow, GUI/VAD updates, and Roo /push command

This commit is contained in:
Laan Tungir
2026-03-26 16:17:13 -04:00
parent 9996466363
commit eeb322d3f6
6 changed files with 284 additions and 3 deletions
+7
View File
@@ -0,0 +1,7 @@
---
description: "Run increment_and_push.sh with a strong commit message"
---
Run `./increment_and_push.sh` and supply a good git commit message. For example:
`./increment_and_push.sh "Fixed the bug with nip05 implementation"`
+20
View File
@@ -70,6 +70,26 @@ pactl list short sources
Then set `audio_device=` in `./config.ini` to the source you want.
## Versioning workflow
This project uses semantic git tags (`vMAJOR.MINOR.PATCH`) plus header macros in [`src/version.h`](src/version.h).
Use [`increment_and_push.sh`](increment_and_push.sh) to increment version, update [`VOICE_LINUX_VERSION`](src/version.h:4), commit, tag, and push:
```bash
# patch bump (default)
./increment_and_push.sh "Fix VAD trigger behavior"
# minor bump
./increment_and_push.sh -m "Add new GUI debug indicators"
# major bump
./increment_and_push.sh -M "Breaking config change"
# release mode (also runs bash ./build.sh and creates tarball)
./increment_and_push.sh -r -m "Release minor update"
```
## Notes
- This implementation targets **X11** (not native Wayland).
+243
View File
@@ -0,0 +1,243 @@
#!/usr/bin/env bash
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_status() { echo -e "${BLUE}[INFO]${NC} $1" >&2; }
print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" >&2; }
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" >&2; }
print_error() { echo -e "${RED}[ERROR]${NC} $1" >&2; }
COMMIT_MESSAGE=""
RELEASE_MODE=false
VERSION_INCREMENT_TYPE="patch" # patch | minor | major
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
VERSION_FILE="$ROOT_DIR/src/version.h"
show_usage() {
cat <<'EOF'
voice_linux increment and push script
USAGE:
./increment_and_push.sh [OPTIONS] "commit message"
OPTIONS:
-p, --patch Increment patch version (default)
-m, --minor Increment minor version
-M, --major Increment major version
-r, --release Build and create a source tarball after tagging
-h, --help Show this help
EXAMPLES:
./increment_and_push.sh "Fix VAD trigger logic"
./increment_and_push.sh -m "Add live debug indicators"
./increment_and_push.sh -M "Breaking config format update"
./increment_and_push.sh -r -m "Release minor update"
EOF
}
check_git_repo() {
if ! git -C "$ROOT_DIR" rev-parse --git-dir >/dev/null 2>&1; then
print_error "Not in a git repository: $ROOT_DIR"
exit 1
fi
}
require_clean_worktree() {
if ! git -C "$ROOT_DIR" diff --quiet || ! git -C "$ROOT_DIR" diff --cached --quiet; then
print_error "Working tree is not clean. Commit or stash changes before running this script."
exit 1
fi
}
latest_version_tag() {
git -C "$ROOT_DIR" tag -l 'v*.*.*' | sort -V | tail -n 1
}
read_header_version() {
if [[ ! -f "$VERSION_FILE" ]]; then
echo "v0.1.0"
return
fi
local v
v=$(grep -E '^#define[[:space:]]+VOICE_LINUX_VERSION[[:space:]]+"v[0-9]+\.[0-9]+\.[0-9]+"' "$VERSION_FILE" | sed -E 's/.*"(v[0-9]+\.[0-9]+\.[0-9]+)".*/\1/' || true)
if [[ -z "$v" ]]; then
echo "v0.1.0"
else
echo "$v"
fi
}
parse_semver() {
local v="$1"
if [[ "$v" =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
echo "${BASH_REMATCH[1]} ${BASH_REMATCH[2]} ${BASH_REMATCH[3]}"
else
print_error "Invalid version: $v"
exit 1
fi
}
increment_version() {
local current="$1"
local kind="$2"
read -r major minor patch < <(parse_semver "$current")
case "$kind" in
major)
major=$((major + 1))
minor=0
patch=0
;;
minor)
minor=$((minor + 1))
patch=0
;;
patch)
patch=$((patch + 1))
;;
*)
print_error "Unknown increment type: $kind"
exit 1
;;
esac
echo "v${major}.${minor}.${patch}"
}
update_version_header() {
local new_version="$1"
read -r major minor patch < <(parse_semver "$new_version")
if [[ ! -f "$VERSION_FILE" ]]; then
print_error "Missing $VERSION_FILE"
exit 1
fi
sed -i -E "s|^#define[[:space:]]+VOICE_LINUX_VERSION[[:space:]]+\"v[0-9]+\.[0-9]+\.[0-9]+\"|#define VOICE_LINUX_VERSION \"${new_version}\"|" "$VERSION_FILE"
sed -i -E "s|^#define[[:space:]]+VOICE_LINUX_VERSION_MAJOR[[:space:]]+[0-9]+|#define VOICE_LINUX_VERSION_MAJOR ${major}|" "$VERSION_FILE"
sed -i -E "s|^#define[[:space:]]+VOICE_LINUX_VERSION_MINOR[[:space:]]+[0-9]+|#define VOICE_LINUX_VERSION_MINOR ${minor}|" "$VERSION_FILE"
sed -i -E "s|^#define[[:space:]]+VOICE_LINUX_VERSION_PATCH[[:space:]]+[0-9]+|#define VOICE_LINUX_VERSION_PATCH ${patch}|" "$VERSION_FILE"
print_success "Updated $VERSION_FILE to $new_version"
}
create_or_replace_tag() {
local tag="$1"
if git -C "$ROOT_DIR" rev-parse "$tag" >/dev/null 2>&1; then
print_warning "Tag $tag exists, replacing locally"
git -C "$ROOT_DIR" tag -d "$tag" >/dev/null
fi
git -C "$ROOT_DIR" tag "$tag"
print_success "Created tag: $tag"
}
git_commit_push_and_tag() {
local version="$1"
local message="$2"
git -C "$ROOT_DIR" add "$VERSION_FILE"
git -C "$ROOT_DIR" commit -m "$version - $message" >/dev/null
print_success "Committed: $version - $message"
create_or_replace_tag "$version"
git -C "$ROOT_DIR" push
print_success "Pushed branch"
if git -C "$ROOT_DIR" push origin "$version"; then
print_success "Pushed tag: $version"
else
print_warning "Tag push failed, trying force push"
git -C "$ROOT_DIR" push --force origin "$version"
print_success "Force-pushed tag: $version"
fi
}
build_and_package_release() {
local version="$1"
print_status "Running release build with bash ./build.sh"
(cd "$ROOT_DIR" && bash ./build.sh)
local tarball="voice_linux-${version#v}.tar.gz"
print_status "Creating source tarball: $tarball"
(cd "$ROOT_DIR" && tar -czf "$tarball" \
--exclude='.git' \
--exclude='.git/*' \
--exclude='vendor/whisper.cpp/build/*' \
--exclude='*.o' \
--exclude='voice_linux' \
--exclude='voice_linux_gui' \
--exclude='*.tar.gz' \
.)
print_success "Created tarball: $tarball"
}
while [[ $# -gt 0 ]]; do
case "$1" in
-p|--patch)
VERSION_INCREMENT_TYPE="patch"
shift
;;
-m|--minor)
VERSION_INCREMENT_TYPE="minor"
shift
;;
-M|--major)
VERSION_INCREMENT_TYPE="major"
shift
;;
-r|--release)
RELEASE_MODE=true
shift
;;
-h|--help)
show_usage
exit 0
;;
*)
if [[ -z "$COMMIT_MESSAGE" ]]; then
COMMIT_MESSAGE="$1"
else
COMMIT_MESSAGE="$COMMIT_MESSAGE $1"
fi
shift
;;
esac
done
if [[ -z "$COMMIT_MESSAGE" ]]; then
print_error "Commit message is required"
echo ""
show_usage
exit 1
fi
print_status "voice_linux increment and push"
check_git_repo
require_clean_worktree
LATEST_TAG="$(latest_version_tag || true)"
if [[ -z "$LATEST_TAG" ]]; then
LATEST_TAG="$(read_header_version)"
print_warning "No git version tags found, using header version: $LATEST_TAG"
fi
NEW_VERSION="$(increment_version "$LATEST_TAG" "$VERSION_INCREMENT_TYPE")"
print_status "Current: $LATEST_TAG"
print_status "Next: $NEW_VERSION"
update_version_header "$NEW_VERSION"
git_commit_push_and_tag "$NEW_VERSION" "$COMMIT_MESSAGE"
if [[ "$RELEASE_MODE" == true ]]; then
build_and_package_release "$NEW_VERSION"
fi
print_success "Done: $NEW_VERSION"
+3 -2
View File
@@ -2,6 +2,7 @@
#include "config.h"
#include "transcribe.h"
#include "typer.h"
#include "version.h"
#include <gtk/gtk.h>
@@ -424,8 +425,8 @@ static void on_app_activate(GtkApplication *app, gpointer user_data) {
gtk_container_add(GTK_CONTAINER(s->window), outer);
char info[1024];
snprintf(info, sizeof(info), "Device: %s\nModel: %s\nLanguage: %s\nGPU: %s",
s->cfg.audio_device, s->cfg.model_path, s->cfg.language, s->use_gpu ? "on" : "off");
snprintf(info, sizeof(info), "Version: %s\nDevice: %s\nModel: %s\nLanguage: %s\nGPU: %s",
VOICE_LINUX_VERSION, s->cfg.audio_device, s->cfg.model_path, s->cfg.language, s->use_gpu ? "on" : "off");
GtkWidget *info_label = gtk_label_new(info);
gtk_label_set_xalign(GTK_LABEL(info_label), 0.0f);
gtk_box_pack_start(GTK_BOX(outer), info_label, FALSE, FALSE, 0);
+2 -1
View File
@@ -3,6 +3,7 @@
#include "hotkey.h"
#include "transcribe.h"
#include "typer.h"
#include "version.h"
#include <stdio.h>
#include <stdlib.h>
@@ -112,7 +113,7 @@ int main(int argc, char **argv) {
return 1;
}
fprintf(stderr, "voice_linux ready\n");
fprintf(stderr, "voice_linux %s ready\n", VOICE_LINUX_VERSION);
fprintf(stderr, "hotkey toggle mode: press %s to START recording, press %s again to STOP and transcribe\n", cfg.hotkey, cfg.hotkey);
fprintf(stderr, "device: %s | model: %s | language: %s | gpu: %s\n",
cfg.audio_device, cfg.model_path, cfg.language, use_gpu ? "on" : "off");
+9
View File
@@ -0,0 +1,9 @@
#ifndef VOICE_VERSION_H
#define VOICE_VERSION_H
#define VOICE_LINUX_VERSION "v0.1.0"
#define VOICE_LINUX_VERSION_MAJOR 0
#define VOICE_LINUX_VERSION_MINOR 1
#define VOICE_LINUX_VERSION_PATCH 0
#endif