244 lines
6.1 KiB
Bash
Executable File
244 lines
6.1 KiB
Bash
Executable File
#!/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.0.1"
|
|
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.0.1"
|
|
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"
|