Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## Summary

## Changes

-

## Type of Change

- [ ] `feat` — New feature
- [ ] `fix` — Bug fix
- [ ] `perf` — Performance improvement
- [ ] `refactor` — Code refactor (no behavior change)
- [ ] `chore` — Build, tooling, dependencies
- [ ] `docs` — Documentation only
- [ ] `ci` — CI/CD changes
- [ ] `BREAKING CHANGE` — Incompatible API change

## Checklist

- [ ] Code builds without errors (`go build ./...` / `bun run build`)
- [ ] Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/)
- [ ] `.env.example` updated if new environment variables were added
- [ ] API documentation updated if endpoints changed
Empty file added CHANGELOG.md
Empty file.
4 changes: 4 additions & 0 deletions backend/config/version.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
"description": "🧘‍♂️ ZenReply: Protect Your Deep Work",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"release:patch": "bash scripts/release.sh patch",
"release:minor": "bash scripts/release.sh minor",
"release:major": "bash scripts/release.sh major",
"release": "bash scripts/release.sh",
"prepare": "husky"
},
"repository": {
Expand Down
157 changes: 157 additions & 0 deletions scripts/release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
BOLD='\033[1m'
NC='\033[0m'

log_info() { echo -e "${BLUE}ℹ${NC} $*"; }
log_success() { echo -e "${GREEN}✓${NC} $*"; }
log_warn() { echo -e "${YELLOW}⚠${NC} $*"; }
log_error() { echo -e "${RED}✗${NC} $*" >&2; }

# Helpers
require_command() {
if ! command -v "$1" &>/dev/null; then
log_error "Required command not found: $1"
exit 1
fi
}

require_command git
require_command node

# Validate working directory
cd "$ROOT_DIR"

if [[ ! -f "package.json" ]]; then
log_error "Must be run from the ZenReply root directory."
exit 1
fi

# Check for uncommitted changes
if [[ -n "$(git status --porcelain)" ]]; then
log_error "Working directory is not clean. Commit or stash changes first."
git status --short
exit 1
fi

# Determine current version
CURRENT_VERSION=$(node -p "require('./package.json').version")
log_info "Current version: ${BOLD}${CURRENT_VERSION}${NC}"

# Parse bump type or explicit version
BUMP="${1:-}"

if [[ -z "$BUMP" ]]; then
log_error "Usage: $0 <patch|minor|major|x.y.z>"
exit 1
fi

bump_semver() {
local version="$1"
local part="$2"
IFS='.' read -r major minor patch <<< "$version"
case "$part" in
major) echo "$((major + 1)).0.0" ;;
minor) echo "${major}.$((minor + 1)).0" ;;
patch) echo "${major}.${minor}.$((patch + 1))" ;;
*) echo "$part" ;; # explicit version
esac
}

NEW_VERSION=$(bump_semver "$CURRENT_VERSION" "$BUMP")

# Validate semver format
if ! [[ "$NEW_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
log_error "Invalid version format: $NEW_VERSION (expected: x.y.z or x.y.z-rc.1)"
exit 1
fi

log_info "New version: ${BOLD}${NEW_VERSION}${NC}"
echo ""

# ── Confirm ───────────────────────────────────────────────────
read -rp "$(echo -e "${YELLOW}?${NC} Bump ${CURRENT_VERSION} → ${NEW_VERSION} and push tag? [y/N] ")" confirm
if [[ "${confirm,,}" != "y" ]]; then
log_warn "Aborted."
exit 0
fi

echo ""

# Step 1: Update root package.json
log_info "Updating root package.json..."
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
pkg.version = '${NEW_VERSION}';
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
"
log_success "package.json → ${NEW_VERSION}"

# Step 2: Update frontend/package.json
if [[ -f "frontend/package.json" ]]; then
log_info "Updating frontend/package.json..."
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('frontend/package.json', 'utf8'));
pkg.version = '${NEW_VERSION}';
fs.writeFileSync('frontend/package.json', JSON.stringify(pkg, null, 2) + '\n');
"
log_success "frontend/package.json → ${NEW_VERSION}"
fi

# Step 3: Update backend version constant
log_info "Updating backend/config/version.go..."
cat > "backend/config/version.go" << EOF
// Code generated by scripts/release.sh — DO NOT EDIT.
package config

const Version = "${NEW_VERSION}"
EOF
log_success "backend/config/version.go → ${NEW_VERSION}"

# Step 4: Git commit
log_info "Committing version bump..."
git add \
package.json \
frontend/package.json \
backend/config/version.go

git commit -m "chore(release): v${NEW_VERSION}

Bump version across all packages:
- package.json: ${CURRENT_VERSION} → ${NEW_VERSION}
- frontend/package.json: ${CURRENT_VERSION} → ${NEW_VERSION}
- backend/config/version.go: ${CURRENT_VERSION} → ${NEW_VERSION}"

log_success "Committed: chore(release): v${NEW_VERSION}"

# Step 5: Create annotated Git tag
log_info "Creating tag v${NEW_VERSION}..."
git tag -a "v${NEW_VERSION}" -m "Release v${NEW_VERSION}"
log_success "Tag created: v${NEW_VERSION}"

# Step 6: Push commit + tag
log_info "Pushing to origin..."
git push origin main
git push origin "v${NEW_VERSION}"
log_success "Pushed commit and tag to origin"

echo ""
echo -e "${GREEN}${BOLD} Release v${NEW_VERSION} triggered!${NC}"
echo ""
echo -e " GitHub Actions will now:"
echo -e " ${BLUE}1.${NC} Build Docker image (linux/amd64 + linux/arm64)"
echo -e " ${BLUE}2.${NC} Push to ghcr.io with tags: ${NEW_VERSION}, latest"
echo -e " ${BLUE}3.${NC} Create GitHub Release with auto-generated notes"
echo ""
echo -e " Track progress: ${BLUE}https://github.com/blogic-kietle/ZenReply/actions${NC}"
Loading