From c7f81a301fe8cfeaf1c211e373fe665885d91420 Mon Sep 17 00:00:00 2001 From: Daniel Volz Date: Mon, 29 Dec 2025 21:07:46 +0100 Subject: [PATCH] feat: add release script for version management and tagging --- .github/workflows/docker-build.yml | 60 ++++++++++++++++ scripts/release.sh | 106 +++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100755 scripts/release.sh diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index fa245ae..5165ab2 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -67,3 +67,63 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max platforms: linux/amd64,linux/arm64 + + # ============================================================================= + # Create GitHub Release (only on tag push) + # ============================================================================= + create-release: + runs-on: ubuntu-latest + needs: build-and-push + if: startsWith(github.ref, 'refs/tags/v') + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch all history for changelog generation + + - name: Get previous tag + id: prev_tag + run: | + PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") + echo "tag=${PREV_TAG}" >> $GITHUB_OUTPUT + + - name: Generate changelog + id: changelog + run: | + CURRENT_TAG=${GITHUB_REF#refs/tags/} + PREV_TAG="${{ steps.prev_tag.outputs.tag }}" + + echo "## What's Changed" > changelog.md + echo "" >> changelog.md + + if [ -n "$PREV_TAG" ]; then + # Get commits between tags + git log ${PREV_TAG}..${CURRENT_TAG} --pretty=format:"* %s (%h)" --no-merges >> changelog.md + else + # First release - get recent commits + git log -20 --pretty=format:"* %s (%h)" --no-merges >> changelog.md + fi + + echo "" >> changelog.md + echo "" >> changelog.md + echo "## Docker Images" >> changelog.md + echo "" >> changelog.md + echo '```bash' >> changelog.md + echo "docker pull ghcr.io/${{ github.repository_owner }}/medassist-ng-backend:${CURRENT_TAG#v}" >> changelog.md + echo "docker pull ghcr.io/${{ github.repository_owner }}/medassist-ng-frontend:${CURRENT_TAG#v}" >> changelog.md + echo '```' >> changelog.md + echo "" >> changelog.md + echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${PREV_TAG}...${CURRENT_TAG}" >> changelog.md + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + body_path: changelog.md + generate_release_notes: false + draft: false + prerelease: ${{ contains(github.ref, '-rc') || contains(github.ref, '-beta') || contains(github.ref, '-alpha') }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 0000000..f05d1ae --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,106 @@ +#!/bin/bash +# ============================================================================= +# MedAssist Release Script +# ============================================================================= +# Usage: +# ./scripts/release.sh patch # 1.0.0 -> 1.0.1 (bugfixes) +# ./scripts/release.sh minor # 1.0.0 -> 1.1.0 (new features) +# ./scripts/release.sh major # 1.0.0 -> 2.0.0 (breaking changes) +# ./scripts/release.sh 1.2.3 # explicit version +# ============================================================================= + +set -e + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Get script directory and project root +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +cd "$PROJECT_ROOT" + +# Check for uncommitted changes +if [[ -n $(git status --porcelain) ]]; then + echo -e "${RED}Error: You have uncommitted changes. Commit or stash them first.${NC}" + git status --short + exit 1 +fi + +# Get current version from backend/package.json +CURRENT_VERSION=$(grep '"version"' backend/package.json | sed 's/.*"version": "\(.*\)".*/\1/') +echo -e "${BLUE}Current version: ${YELLOW}v${CURRENT_VERSION}${NC}" + +# Calculate new version +if [[ -z "$1" ]]; then + echo -e "${RED}Usage: $0 ${NC}" + exit 1 +fi + +case "$1" in + patch) + IFS='.' read -r major minor patch <<< "$CURRENT_VERSION" + NEW_VERSION="$major.$minor.$((patch + 1))" + ;; + minor) + IFS='.' read -r major minor patch <<< "$CURRENT_VERSION" + NEW_VERSION="$major.$((minor + 1)).0" + ;; + major) + IFS='.' read -r major minor patch <<< "$CURRENT_VERSION" + NEW_VERSION="$((major + 1)).0.0" + ;; + *) + # Assume explicit version (validate format) + if [[ ! "$1" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo -e "${RED}Invalid version format. Use: x.y.z${NC}" + exit 1 + fi + NEW_VERSION="$1" + ;; +esac + +echo -e "${GREEN}New version: ${YELLOW}v${NEW_VERSION}${NC}" +echo "" + +# Confirm +read -p "Release v${NEW_VERSION}? (y/N) " -n 1 -r +echo "" +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "Aborted." + exit 1 +fi + +# Update version in package.json files +echo -e "${BLUE}Updating package.json files...${NC}" +sed -i '' "s/\"version\": \"${CURRENT_VERSION}\"/\"version\": \"${NEW_VERSION}\"/" backend/package.json +sed -i '' "s/\"version\": \"${CURRENT_VERSION}\"/\"version\": \"${NEW_VERSION}\"/" frontend/package.json 2>/dev/null || true + +# Commit version bump +echo -e "${BLUE}Committing version bump...${NC}" +git add backend/package.json frontend/package.json 2>/dev/null || git add backend/package.json +git commit -m "chore: release v${NEW_VERSION}" + +# Check if tag exists +if git rev-parse "v${NEW_VERSION}" >/dev/null 2>&1; then + echo -e "${YELLOW}Tag v${NEW_VERSION} already exists. Overwriting...${NC}" + git tag -d "v${NEW_VERSION}" + git push origin ":refs/tags/v${NEW_VERSION}" 2>/dev/null || true +fi + +# Create and push tag +echo -e "${BLUE}Creating tag v${NEW_VERSION}...${NC}" +git tag -a "v${NEW_VERSION}" -m "Release v${NEW_VERSION}" + +# Push +echo -e "${BLUE}Pushing to origin...${NC}" +git push origin main +git push origin "v${NEW_VERSION}" + +echo "" +echo -e "${GREEN}✓ Released v${NEW_VERSION}${NC}" +echo -e "${BLUE}GitHub Actions will now build and publish Docker images.${NC}" +echo -e "Track progress: ${YELLOW}https://github.com/DanielVolz/medassist-ng/actions${NC}"