mirror of
https://github.com/adityachandelgit/BookLore.git
synced 2026-02-18 03:07:40 +01:00
318 lines
9.7 KiB
YAML
318 lines
9.7 KiB
YAML
name: Master - Build, Tag, Push, and Release
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- 'master'
|
|
|
|
jobs:
|
|
get-base-ref:
|
|
name: Get Base Ref
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
base_ref: ${{ steps.get_base.outputs.base_ref }}
|
|
steps:
|
|
- name: Checkout Repository
|
|
uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 2
|
|
- name: Get Base Ref
|
|
id: get_base
|
|
run: echo "base_ref=$(git rev-parse HEAD~1)" >> $GITHUB_OUTPUT
|
|
|
|
migration-check:
|
|
name: Flyway Migration Check on Master
|
|
needs: [ get-base-ref ]
|
|
uses: ./.github/workflows/migrations-check.yml
|
|
with:
|
|
base_ref: ${{ needs.get-base-ref.outputs.base_ref }}
|
|
head_ref: ${{ github.sha }}
|
|
|
|
backend-tests:
|
|
name: Backend Tests
|
|
needs: [ migration-check ]
|
|
if: needs.migration-check.result == 'success' || needs.migration-check.result == 'skipped'
|
|
runs-on: ubuntu-latest
|
|
|
|
permissions:
|
|
contents: read
|
|
checks: write
|
|
pull-requests: write
|
|
|
|
steps:
|
|
- name: Checkout Repository
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Set Up JDK 25
|
|
uses: actions/setup-java@v5
|
|
with:
|
|
java-version: '25'
|
|
distribution: 'temurin'
|
|
cache: gradle
|
|
|
|
- name: Execute Backend Tests
|
|
id: backend_tests
|
|
working-directory: ./booklore-api
|
|
run: |
|
|
echo "Running backend tests..."
|
|
./gradlew test --no-daemon --parallel --build-cache
|
|
continue-on-error: true
|
|
|
|
- name: Publish Backend Test Results
|
|
uses: EnricoMi/publish-unit-test-result-action@v2
|
|
if: always()
|
|
with:
|
|
files: booklore-api/build/test-results/**/*.xml
|
|
check_name: Backend Test Results
|
|
|
|
- name: Upload Backend Test Reports
|
|
uses: actions/upload-artifact@v6
|
|
if: always()
|
|
with:
|
|
name: backend-test-reports
|
|
path: |
|
|
booklore-api/build/reports/tests/
|
|
booklore-api/build/test-results/
|
|
retention-days: 30
|
|
|
|
- name: Validate Backend Test Results
|
|
if: steps.backend_tests.outcome == 'failure'
|
|
run: |
|
|
echo "❌ Backend tests failed"
|
|
exit 1
|
|
|
|
frontend-tests:
|
|
name: Frontend Tests
|
|
needs: [ migration-check ]
|
|
if: needs.migration-check.result == 'success' || needs.migration-check.result == 'skipped'
|
|
runs-on: ubuntu-latest
|
|
|
|
permissions:
|
|
contents: read
|
|
checks: write
|
|
pull-requests: write
|
|
|
|
steps:
|
|
- name: Checkout Repository
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Set Up Node.js
|
|
uses: actions/setup-node@v6
|
|
with:
|
|
node-version: '22'
|
|
cache: 'npm'
|
|
cache-dependency-path: booklore-ui/package-lock.json
|
|
|
|
- name: Install Frontend Dependencies
|
|
working-directory: ./booklore-ui
|
|
run: npm ci --force
|
|
|
|
- name: Execute Frontend Tests
|
|
id: frontend_tests
|
|
working-directory: ./booklore-ui
|
|
run: |
|
|
echo "Running frontend tests..."
|
|
npx ng test
|
|
continue-on-error: true
|
|
|
|
- name: Publish Frontend Test Results
|
|
uses: EnricoMi/publish-unit-test-result-action@v2
|
|
if: always()
|
|
with:
|
|
files: booklore-ui/test-results/vitest-results.xml
|
|
check_name: Frontend Test Results
|
|
|
|
- name: Upload Frontend Test Reports
|
|
uses: actions/upload-artifact@v6
|
|
if: always()
|
|
with:
|
|
name: frontend-test-reports
|
|
path: |
|
|
booklore-ui/test-results/vitest-results.xml
|
|
retention-days: 30
|
|
|
|
- name: Validate Frontend Test Results
|
|
if: steps.frontend_tests.outcome == 'failure'
|
|
run: |
|
|
echo "❌ Frontend tests failed"
|
|
exit 1
|
|
|
|
build-and-release:
|
|
needs: [ backend-tests, frontend-tests ]
|
|
if: needs.backend-tests.result == 'success' && needs.frontend-tests.result == 'success'
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
packages: write
|
|
pull-requests: read
|
|
|
|
steps:
|
|
- name: Checkout Repository
|
|
uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Authenticate to Docker Hub
|
|
uses: docker/login-action@v3
|
|
with:
|
|
username: ${{ secrets.DOCKER_USERNAME }}
|
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
|
|
- name: Authenticate to GitHub Container Registry
|
|
uses: docker/login-action@v3
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.actor }}
|
|
password: ${{ github.token }}
|
|
|
|
- name: Set Up QEMU for Multi-Architecture Builds
|
|
uses: docker/setup-qemu-action@v3
|
|
|
|
- name: Set Up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
|
|
- name: Retrieve Latest Master Version Tag
|
|
id: get_version
|
|
run: |
|
|
latest_tag=$(git tag --list "v*" --sort=-v:refname | head -n 1)
|
|
latest_tag=${latest_tag:-"v0.0.0"}
|
|
echo "latest_tag=$latest_tag" >> $GITHUB_ENV
|
|
echo "Latest master tag: $latest_tag"
|
|
|
|
- name: Determine Version Bump
|
|
id: determine_bump
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
echo "Determining version bump from PR labels..."
|
|
|
|
# Extract PR number from merge commit
|
|
pr_number=$(git log -1 --pretty=%B | grep -oE 'Merge pull request #[0-9]+' | grep -oE '[0-9]+') || true
|
|
if [ -z "$pr_number" ]; then
|
|
pr_number=$(gh pr list --state merged --base master --limit 1 --json number --jq '.[0].number')
|
|
fi
|
|
echo "PR number: $pr_number"
|
|
|
|
labels=$(gh pr view "$pr_number" --json labels --jq '.labels[].name' || echo "")
|
|
echo "PR labels: $labels"
|
|
|
|
if echo "$labels" | grep -q 'bump:major'; then
|
|
bump="major"
|
|
elif echo "$labels" | grep -q 'bump:minor'; then
|
|
bump="minor"
|
|
elif echo "$labels" | grep -q 'bump:patch'; then
|
|
bump="patch"
|
|
else
|
|
last_commit_msg=$(git log -1 --pretty=%B)
|
|
if echo "$last_commit_msg" | grep -iq '#major'; then
|
|
bump="major"
|
|
elif echo "$last_commit_msg" | grep -iq '#minor'; then
|
|
bump="minor"
|
|
elif echo "$last_commit_msg" | grep -iq '#patch'; then
|
|
bump="patch"
|
|
else
|
|
bump="patch"
|
|
fi
|
|
fi
|
|
|
|
# Calculate next version
|
|
semver=$(echo ${{ env.latest_tag }} | sed 's/^v//')
|
|
major=$(echo $semver | cut -d. -f1)
|
|
minor=$(echo $semver | cut -d. -f2)
|
|
patch=$(echo $semver | cut -d. -f3)
|
|
|
|
case "$bump" in
|
|
major) major=$((major+1)); minor=0; patch=0 ;;
|
|
minor) minor=$((minor+1)); patch=0 ;;
|
|
patch) patch=$((patch+1)) ;;
|
|
esac
|
|
|
|
next_version="v${major}.${minor}.${patch}"
|
|
echo "Version bump type: $bump"
|
|
echo "Next version: $next_version"
|
|
|
|
echo "bump=$bump" >> $GITHUB_ENV
|
|
echo "new_tag=$next_version" >> $GITHUB_ENV
|
|
|
|
# ----------------------------------------
|
|
# Native Angular build
|
|
# ----------------------------------------
|
|
- name: Set Up Node.js
|
|
uses: actions/setup-node@v6
|
|
with:
|
|
node-version: '22'
|
|
cache: 'npm'
|
|
cache-dependency-path: booklore-ui/package-lock.json
|
|
|
|
- name: Install Frontend Dependencies
|
|
working-directory: ./booklore-ui
|
|
run: npm ci --force
|
|
|
|
- name: Build Angular App
|
|
working-directory: ./booklore-ui
|
|
run: npx ng build --configuration=production
|
|
|
|
# ----------------------------------------
|
|
# Native Gradle build
|
|
# ----------------------------------------
|
|
- name: Set Up JDK 25
|
|
uses: actions/setup-java@v5
|
|
with:
|
|
java-version: '25'
|
|
distribution: 'temurin'
|
|
cache: gradle
|
|
|
|
- name: Copy Angular Dist to Spring Boot Resources
|
|
run: cp -r booklore-ui/dist/booklore/browser/. booklore-api/src/main/resources/static/
|
|
|
|
- name: Inject Version into application.yaml
|
|
env:
|
|
APP_VERSION: ${{ env.new_tag }}
|
|
run: |
|
|
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/v4.52.2/yq_linux_amd64
|
|
sudo chmod +x /usr/local/bin/yq
|
|
yq eval '.app.version = strenv(APP_VERSION)' -i booklore-api/src/main/resources/application.yaml
|
|
|
|
- name: Build Spring Boot JAR
|
|
working-directory: ./booklore-api
|
|
run: ./gradlew clean build -x test --no-daemon --parallel --build-cache
|
|
|
|
# ----------------------------------------
|
|
# Docker build & push
|
|
# ----------------------------------------
|
|
- name: Build and push Docker image
|
|
uses: docker/build-push-action@v6
|
|
with:
|
|
context: .
|
|
file: Dockerfile.ci
|
|
platforms: linux/amd64,linux/arm64
|
|
push: true
|
|
tags: |
|
|
booklore/booklore:${{ env.new_tag }}
|
|
booklore/booklore:latest
|
|
ghcr.io/booklore-app/booklore:${{ env.new_tag }}
|
|
ghcr.io/booklore-app/booklore:latest
|
|
build-args: |
|
|
APP_VERSION=${{ env.new_tag }}
|
|
APP_REVISION=${{ github.sha }}
|
|
cache-from: |
|
|
type=gha
|
|
type=registry,ref=ghcr.io/booklore-app/booklore:buildcache
|
|
cache-to: |
|
|
type=gha,mode=max
|
|
type=registry,ref=ghcr.io/booklore-app/booklore:buildcache,mode=max
|
|
|
|
- name: Update GitHub Release Draft
|
|
uses: release-drafter/release-drafter@v6
|
|
with:
|
|
tag: ${{ env.new_tag }}
|
|
name: "Release ${{ env.new_tag }}"
|
|
env:
|
|
GITHUB_TOKEN: ${{ github.token }}
|
|
|
|
- name: Publish GitHub Draft Release
|
|
env:
|
|
GITHUB_TOKEN: ${{ github.token }}
|
|
run: |
|
|
gh release edit ${{ env.new_tag }} --draft=true
|