Files
signer/increment_and_push.sh

329 lines
9.7 KiB
Bash
Executable File

#!/bin/bash
set -e
# signer (Rust) — Increment and Push Script
#
# Increments the version (patch/minor/major), updates Cargo.toml and
# src/lib.rs, commits, tags, and pushes. Optionally creates a release
# build and uploads assets to Gitea.
#
# 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 Create release build and upload assets
# -h, --help Show this help message
# Colors for output
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"
show_usage() {
echo "signer (Rust) Increment and Push Script"
echo ""
echo "USAGE:"
echo " $0 [OPTIONS] \"commit message\""
echo ""
echo "OPTIONS:"
echo " -p, --patch Increment patch version (default)"
echo " -m, --minor Increment minor version"
echo " -M, --major Increment major version"
echo " -r, --release Create release build and upload assets"
echo " -h, --help Show this help message"
}
while [[ $# -gt 0 ]]; do
case $1 in
-r|--release)
RELEASE_MODE=true
shift
;;
-p|--patch)
VERSION_INCREMENT_TYPE="patch"
shift
;;
-m|--minor)
VERSION_INCREMENT_TYPE="minor"
shift
;;
-M|--major)
VERSION_INCREMENT_TYPE="major"
shift
;;
-h|--help)
show_usage
exit 0
;;
*)
if [[ -z "$COMMIT_MESSAGE" ]]; then
COMMIT_MESSAGE="$1"
fi
shift
;;
esac
done
if [[ -z "$COMMIT_MESSAGE" ]]; then
print_error "Commit message is required"
show_usage
exit 1
fi
check_git_repo() {
if ! git rev-parse --git-dir > /dev/null 2>&1; then
print_error "Not in a git repository"
exit 1
fi
}
# Update version in Cargo.toml and src/lib.rs
update_version_in_source() {
local new_version="$1" # e.g. "v0.0.2"
local new_version_no_v="${new_version#v}" # e.g. "0.0.2"
# Update Cargo.toml
sed -i "s/^version = \".*\"/version = \"$new_version_no_v\"/" Cargo.toml
print_success "Updated Cargo.toml to $new_version_no_v"
# Update src/lib.rs (VERSION constant)
sed -i "s/pub const VERSION: \&str = \"v[0-9]*\.[0-9]*\.[0-9]*\"/pub const VERSION: \&str = \"$new_version\"/" src/lib.rs
print_success "Updated src/lib.rs to $new_version"
}
increment_version() {
local increment_type="$1"
LATEST_TAG=$(git tag -l 'v*.*.*' | sort -V | tail -n 1 || echo "")
if [[ -z "$LATEST_TAG" ]]; then
LATEST_TAG="v0.0.0"
print_warning "No version tags found, starting from $LATEST_TAG"
fi
VERSION=${LATEST_TAG#v}
if [[ $VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
MAJOR=${BASH_REMATCH[1]}
MINOR=${BASH_REMATCH[2]}
PATCH=${BASH_REMATCH[3]}
else
print_error "Invalid version format in tag: $LATEST_TAG"
exit 1
fi
if [[ "$increment_type" == "major" ]]; then
NEW_VERSION="v$((MAJOR + 1)).0.0"
elif [[ "$increment_type" == "minor" ]]; then
NEW_VERSION="v${MAJOR}.$((MINOR + 1)).0"
else
NEW_VERSION="v${MAJOR}.${MINOR}.$((PATCH + 1))"
fi
update_version_in_source "$NEW_VERSION"
export NEW_VERSION
}
git_commit_and_push() {
git add .
if ! git diff --staged --quiet; then
git commit -m "$NEW_VERSION - $COMMIT_MESSAGE"
else
print_warning "No changes to commit"
fi
git push
git push origin "$NEW_VERSION" 2>/dev/null || git push --force origin "$NEW_VERSION" 2>/dev/null || true
}
verify_binary_version() {
local bin_path="$1"
local expected="$2"
if [[ ! -x "$bin_path" ]]; then
print_error "Binary not found or not executable: $bin_path"
return 1
fi
local got
got="$($bin_path --version 2>/dev/null | awk '{print $2}')"
if [[ "$got" != "$expected" ]]; then
print_error "Binary version mismatch: expected $expected, got ${got:-<unknown>}"
return 1
fi
return 0
}
build_release_binary() {
print_status "Building static musl release binaries..."
./build_musl.sh || return 1
local bin_path="dist/signer"
verify_binary_version "$bin_path" "$NEW_VERSION" || return 1
local client_path="dist/signer_client"
if [[ -f "$client_path" ]]; then
verify_binary_version "$client_path" "$NEW_VERSION" || return 1
print_success "Portable client binary built: $client_path"
fi
print_success "Portable signer binary built: $bin_path"
return 0
}
create_source_tarball() {
local tarball_name="signer-${NEW_VERSION#v}.tar.gz"
if tar -czf "$tarball_name" \
--exclude='target/*' \
--exclude='.git*' \
--exclude='*.log' \
--exclude='*.tar.gz' \
. > /dev/null 2>&1; then
echo "$tarball_name"
else
return 1
fi
}
create_gitea_release() {
if [[ ! -f "$HOME/.gitea_token" ]]; then
print_warning "No ~/.gitea_token found. Skipping release creation."
return 0
fi
local token
token=$(cat "$HOME/.gitea_token" | tr -d '\n\r')
local api_url="https://git.laantungir.net/api/v1/repos/laantungir/signer"
local response
response=$(curl -s -X POST "$api_url/releases" \
-H "Authorization: token $token" \
-H "Content-Type: application/json" \
-d "{\"tag_name\": \"$NEW_VERSION\", \"target_commitish\": \"master\", \"name\": \"$NEW_VERSION\", \"body\": \"$COMMIT_MESSAGE\", \"draft\": false, \"prerelease\": false}")
if echo "$response" | grep -q '"id"'; then
local release_id
release_id=$(echo "$response" | grep -o '"id":[0-9]*' | head -1 | cut -d':' -f2)
# Work around Gitea bug: releases created via API get created_unix=0
local now_unix
now_unix=$(date +%s)
print_status "Fixing release timestamp in Gitea database (workaround for Gitea bug)..."
ssh -o ConnectTimeout=10 ubuntu@laantungir.net \
"sudo sqlite3 /data/gitea/gitea.db \"UPDATE release SET created_unix=$now_unix WHERE id=$release_id;\"" \
2>/dev/null || print_warning "Could not fix release timestamp via SSH (release may not appear in web UI)"
echo "$release_id"
else
print_error "Failed to create Gitea release: $response"
return 1
fi
}
upload_release_assets() {
local release_id="$1"
local binary_path="$2"
local tarball_path="$3"
if [[ ! -f "$HOME/.gitea_token" ]]; then
print_warning "No ~/.gitea_token found. Skipping asset uploads."
return 0
fi
local token
token=$(cat "$HOME/.gitea_token" | tr -d '\n\r')
local api_url="https://git.laantungir.net/api/v1/repos/laantungir/signer"
local assets_url="$api_url/releases/$release_id/assets"
upload_asset() {
local path="$1"
if [[ -f "$path" ]]; then
print_status "Uploading $(basename "$path")..."
curl -s -X POST "$assets_url" \
-H "Authorization: token $token" \
-F "attachment=@$path;filename=$(basename "$path")" \
-F "name=$(basename "$path")" > /dev/null
fi
}
upload_asset "$binary_path"
upload_asset "$tarball_path"
}
main() {
check_git_repo
if [[ "$RELEASE_MODE" == true ]]; then
increment_version "$VERSION_INCREMENT_TYPE"
if git tag "$NEW_VERSION" > /dev/null 2>&1; then
print_success "Created tag: $NEW_VERSION"
else
git tag -d "$NEW_VERSION" > /dev/null 2>&1 || true
git tag "$NEW_VERSION" > /dev/null 2>&1
fi
if ! build_release_binary; then
print_error "Release build failed; aborting before push/upload"
exit 1
fi
git_commit_and_push
local binary_path="dist/signer"
local client_path="dist/signer_client"
local tarball_path=""
tarball_path=$(create_source_tarball || true)
local release_id=""
release_id=$(create_gitea_release || true)
if [[ -n "$release_id" ]]; then
upload_release_assets "$release_id" "$binary_path" "$tarball_path"
# Also upload the signer-client binary if it exists
if [[ -f "$client_path" ]]; then
local token
token=$(cat "$HOME/.gitea_token" | tr -d '\n\r')
local api_url="https://git.laantungir.net/api/v1/repos/laantungir/signer"
local assets_url="$api_url/releases/$release_id/assets"
print_status "Uploading signer-client..."
curl -s -X POST "$assets_url" \
-H "Authorization: token $token" \
-F "attachment=@$client_path;filename=signer_client" \
-F "name=signer_client" > /dev/null
fi
fi
print_success "Release flow completed: $NEW_VERSION"
else
increment_version "$VERSION_INCREMENT_TYPE"
if git tag "$NEW_VERSION" > /dev/null 2>&1; then
print_success "Created tag: $NEW_VERSION"
else
git tag -d "$NEW_VERSION" > /dev/null 2>&1 || true
git tag "$NEW_VERSION" > /dev/null 2>&1
fi
git_commit_and_push
print_success "Increment and push completed: $NEW_VERSION"
fi
}
main