270 lines
11 KiB
YAML
270 lines
11 KiB
YAML
name: Version and Release
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
version-bump:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
new_version: ${{ steps.version.outputs.new_version }}
|
|
version_changed: ${{ steps.version.outputs.version_changed }}
|
|
component_changed: ${{ steps.version.outputs.component_changed }}
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
with:
|
|
fetch-depth: 0
|
|
token: ${{ secrets.GITEA_TOKEN || github.token }}
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v3
|
|
with:
|
|
node-version: '18'
|
|
|
|
- name: Configure Git
|
|
run: |
|
|
git config --global user.name 'Gitea Actions Bot'
|
|
git config --global user.email 'actions@gitea.local'
|
|
|
|
- name: Detect changes and bump version
|
|
id: version
|
|
run: |
|
|
set -e # Exit on error
|
|
|
|
echo "=== Debug Info ==="
|
|
echo "GitHub event before: ${{ github.event.before }}"
|
|
echo "GitHub SHA: ${{ github.sha }}"
|
|
echo "Current directory: $(pwd)"
|
|
echo "Git log (last 5): $(git log --oneline -5)"
|
|
|
|
# Get the commit range for changed files
|
|
if [ "${{ github.event.before }}" != "0000000000000000000000000000000000000000" ] && [ "${{ github.event.before }}" != "" ]; then
|
|
COMMIT_RANGE="${{ github.event.before }}..${{ github.sha }}"
|
|
echo "Using commit range: $COMMIT_RANGE"
|
|
CHANGED_FILES=$(git diff --name-only $COMMIT_RANGE || echo "")
|
|
else
|
|
# First commit or no previous commit, check against HEAD~1 if it exists
|
|
if git rev-parse HEAD~1 >/dev/null 2>&1; then
|
|
COMMIT_RANGE="HEAD~1..HEAD"
|
|
echo "Using commit range: $COMMIT_RANGE"
|
|
CHANGED_FILES=$(git diff --name-only $COMMIT_RANGE || echo "")
|
|
else
|
|
echo "First commit detected, checking all files"
|
|
CHANGED_FILES=$(git ls-files)
|
|
fi
|
|
fi
|
|
|
|
echo "Changed files:"
|
|
echo "$CHANGED_FILES"
|
|
|
|
# Check what changed (using echo to pipe to grep to avoid grep exit codes)
|
|
BACKEND_CHANGED=$(echo "$CHANGED_FILES" | grep -c '^backend/' || echo "0")
|
|
FRONTEND_CHANGED=$(echo "$CHANGED_FILES" | grep -c '^frontend/' || echo "0")
|
|
ROOT_CHANGED=$(echo "$CHANGED_FILES" | grep -c -E '^(package\.json|docker-compose|Dockerfile|scripts/)' || echo "0")
|
|
|
|
echo "Backend files changed: $BACKEND_CHANGED"
|
|
echo "Frontend files changed: $FRONTEND_CHANGED"
|
|
echo "Root files changed: $ROOT_CHANGED"
|
|
|
|
# Get current versions
|
|
BACKEND_VERSION=$(node -p "require('./backend/package.json').version" 2>/dev/null || echo "1.1.0")
|
|
FRONTEND_VERSION=$(node -p "require('./frontend/package.json').version" 2>/dev/null || echo "1.1.0")
|
|
|
|
echo "Current backend version: $BACKEND_VERSION"
|
|
echo "Current frontend version: $FRONTEND_VERSION"
|
|
|
|
# Determine what to update based on changes
|
|
BACKEND_UPDATE=false
|
|
FRONTEND_UPDATE=false
|
|
COMPONENT_CHANGED="none"
|
|
|
|
if [ "$ROOT_CHANGED" -gt 0 ]; then
|
|
# Root changes affect both components
|
|
BACKEND_UPDATE=true
|
|
FRONTEND_UPDATE=true
|
|
COMPONENT_CHANGED="both"
|
|
SOURCE_VERSION=$BACKEND_VERSION
|
|
echo "Root changes detected - updating both components"
|
|
elif [ "$BACKEND_CHANGED" -gt 0 ] && [ "$FRONTEND_CHANGED" -gt 0 ]; then
|
|
# Both components changed
|
|
BACKEND_UPDATE=true
|
|
FRONTEND_UPDATE=true
|
|
COMPONENT_CHANGED="both"
|
|
# Use the higher version as source
|
|
if [ "$(printf '%s\n' "$BACKEND_VERSION" "$FRONTEND_VERSION" | sort -V | tail -n1)" = "$BACKEND_VERSION" ]; then
|
|
SOURCE_VERSION=$BACKEND_VERSION
|
|
else
|
|
SOURCE_VERSION=$FRONTEND_VERSION
|
|
fi
|
|
echo "Both backend and frontend changed - updating both"
|
|
elif [ "$BACKEND_CHANGED" -gt 0 ]; then
|
|
# Only backend changed
|
|
BACKEND_UPDATE=true
|
|
COMPONENT_CHANGED="backend"
|
|
SOURCE_VERSION=$BACKEND_VERSION
|
|
echo "Only backend changed - updating backend"
|
|
elif [ "$FRONTEND_CHANGED" -gt 0 ]; then
|
|
# Only frontend changed
|
|
FRONTEND_UPDATE=true
|
|
COMPONENT_CHANGED="frontend"
|
|
SOURCE_VERSION=$FRONTEND_VERSION
|
|
echo "Only frontend changed - updating frontend"
|
|
else
|
|
echo "No relevant changes detected"
|
|
echo "version_changed=false" >> $GITHUB_OUTPUT
|
|
echo "component_changed=none" >> $GITHUB_OUTPUT
|
|
echo "new_version=" >> $GITHUB_OUTPUT
|
|
exit 0
|
|
fi
|
|
|
|
echo "Component changed: $COMPONENT_CHANGED"
|
|
echo "Source version: $SOURCE_VERSION"
|
|
echo "Backend update: $BACKEND_UPDATE"
|
|
echo "Frontend update: $FRONTEND_UPDATE"
|
|
|
|
# Calculate new version
|
|
IFS='.' read -r -a version_parts <<< "$SOURCE_VERSION"
|
|
MAJOR="${version_parts[0]}"
|
|
MINOR="${version_parts[1]}"
|
|
PATCH="${version_parts[2]}"
|
|
|
|
# Increment patch version and ensure tag uniqueness
|
|
git fetch --tags --quiet || true
|
|
NEW_PATCH=$((PATCH + 1))
|
|
NEW_VERSION="$MAJOR.$MINOR.$NEW_PATCH"
|
|
|
|
while git rev-parse "v${NEW_VERSION}" >/dev/null 2>&1; do
|
|
echo "Tag v${NEW_VERSION} already exists, bumping patch version again"
|
|
NEW_PATCH=$((NEW_PATCH + 1))
|
|
NEW_VERSION="$MAJOR.$MINOR.$NEW_PATCH"
|
|
done
|
|
|
|
echo "New version: $NEW_VERSION"
|
|
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
|
|
echo "component_changed=$COMPONENT_CHANGED" >> $GITHUB_OUTPUT
|
|
|
|
# Update versions in package.json files
|
|
if [ "$BACKEND_UPDATE" = true ]; then
|
|
echo "Updating backend version to $NEW_VERSION"
|
|
cd backend && npm version $NEW_VERSION --no-git-tag-version
|
|
cd ..
|
|
fi
|
|
|
|
if [ "$FRONTEND_UPDATE" = true ]; then
|
|
echo "Updating frontend version to $NEW_VERSION"
|
|
cd frontend && npm version $NEW_VERSION --no-git-tag-version
|
|
cd ..
|
|
fi
|
|
|
|
# Check if there are changes to commit
|
|
if [[ -n $(git status --porcelain) ]]; then
|
|
echo "version_changed=true" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "version_changed=false" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
- name: Commit version bump
|
|
if: steps.version.outputs.version_changed == 'true'
|
|
run: |
|
|
set -e # Exit on any error
|
|
|
|
# First, ensure we have the latest changes
|
|
echo "Fetching latest changes..."
|
|
git fetch origin main
|
|
|
|
# Check if we're behind and need to update
|
|
LOCAL=$(git rev-parse HEAD)
|
|
REMOTE=$(git rev-parse origin/main)
|
|
|
|
if [ "$LOCAL" != "$REMOTE" ]; then
|
|
echo "Local is behind remote, pulling changes..."
|
|
git pull origin main --no-rebase
|
|
fi
|
|
|
|
COMPONENT="${{ steps.version.outputs.component_changed }}"
|
|
|
|
if [ "$COMPONENT" = "both" ]; then
|
|
git add backend/package.json backend/package-lock.json frontend/package.json frontend/package-lock.json
|
|
git commit -m "chore: bump version to ${{ steps.version.outputs.new_version }} (backend + frontend)"
|
|
elif [ "$COMPONENT" = "backend" ]; then
|
|
git add backend/package.json backend/package-lock.json
|
|
git commit -m "chore: bump backend version to ${{ steps.version.outputs.new_version }}"
|
|
elif [ "$COMPONENT" = "frontend" ]; then
|
|
git add frontend/package.json frontend/package-lock.json
|
|
git commit -m "chore: bump frontend version to ${{ steps.version.outputs.new_version }}"
|
|
fi
|
|
|
|
# Pull latest changes before pushing to avoid conflicts
|
|
echo "Pulling latest changes from origin/main..."
|
|
if ! git pull --rebase origin main; then
|
|
echo "Rebase failed, attempting to resolve..."
|
|
# If rebase fails, abort and try a regular merge
|
|
git rebase --abort || true
|
|
git pull origin main --no-rebase
|
|
fi
|
|
|
|
# Push the changes with retry logic
|
|
echo "Pushing version bump..."
|
|
PUSH_SUCCESS=false
|
|
|
|
for i in 1 2 3; do
|
|
echo "Push attempt $i of 3..."
|
|
|
|
# Try to push
|
|
if git push origin main 2>&1; then
|
|
echo "Successfully pushed version bump on attempt $i"
|
|
PUSH_SUCCESS=true
|
|
break
|
|
else
|
|
echo "Push failed on attempt $i"
|
|
|
|
if [ $i -lt 3 ]; then
|
|
echo "Waiting 5 seconds before retry..."
|
|
sleep 5
|
|
|
|
echo "Pulling latest changes..."
|
|
git fetch origin main
|
|
|
|
# Try rebase first, fall back to merge
|
|
if ! git rebase origin/main; then
|
|
echo "Rebase failed, trying merge..."
|
|
git rebase --abort 2>/dev/null || true
|
|
git pull origin main --no-rebase
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [ "$PUSH_SUCCESS" = "false" ]; then
|
|
echo "ERROR: Failed to push after 3 attempts"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Create Git tag
|
|
if: steps.version.outputs.version_changed == 'true'
|
|
run: |
|
|
COMPONENT="${{ steps.version.outputs.component_changed }}"
|
|
|
|
if [ "$COMPONENT" = "both" ]; then
|
|
TAG_MESSAGE="Release v${{ steps.version.outputs.new_version }} (backend + frontend)"
|
|
elif [ "$COMPONENT" = "backend" ]; then
|
|
TAG_MESSAGE="Release v${{ steps.version.outputs.new_version }} (backend)"
|
|
elif [ "$COMPONENT" = "frontend" ]; then
|
|
TAG_MESSAGE="Release v${{ steps.version.outputs.new_version }} (frontend)"
|
|
fi
|
|
|
|
git tag -a "v${{ steps.version.outputs.new_version }}" -m "$TAG_MESSAGE"
|
|
git push origin "v${{ steps.version.outputs.new_version }}"
|
|
|
|
trigger-drone:
|
|
needs: version-bump
|
|
if: needs.version-bump.outputs.version_changed == 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Trigger Drone Build
|
|
run: |
|
|
echo "Version bumped to ${{ needs.version-bump.outputs.new_version }}"
|
|
echo "Component(s) changed: ${{ needs.version-bump.outputs.component_changed }}"
|
|
echo "Drone will automatically trigger on the new tag"
|
|
# Drone CI will automatically trigger on the tag push event
|