304 lines
No EOL
11 KiB
YAML
304 lines
No EOL
11 KiB
YAML
name: Optimized CI
|
||
|
||
on:
|
||
pull_request:
|
||
push:
|
||
branches:
|
||
- main
|
||
- 'feature/**'
|
||
|
||
concurrency:
|
||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||
cancel-in-progress: true
|
||
|
||
jobs:
|
||
backend-lint:
|
||
name: "Backend Checkstyle & Tests"
|
||
container:
|
||
image: "cimg/openjdk:23.0-node"
|
||
steps:
|
||
- name: "Checkout"
|
||
uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 0
|
||
|
||
- name: "Cache Gradle dependencies"
|
||
uses: https://github.com/actions/cache@v4
|
||
with:
|
||
path: |
|
||
~/.gradle/caches
|
||
~/.gradle/wrapper
|
||
backend/.gradle
|
||
key: gradle-${{ runner.os }}-${{ hashFiles('backend/build.gradle.kts', 'backend/gradle/wrapper/gradle-wrapper.properties') }}
|
||
restore-keys: |
|
||
gradle-${{ runner.os }}-
|
||
|
||
- name: "Setup Gradle"
|
||
working-directory: ./backend
|
||
run: chmod +x ./gradlew
|
||
|
||
- name: "Run Checkstyle"
|
||
working-directory: ./backend
|
||
run: ./gradlew checkstyleMain checkstyleTest --parallel --build-cache
|
||
|
||
- name: "Run Tests"
|
||
working-directory: ./backend
|
||
run: ./gradlew test --parallel --build-cache
|
||
|
||
- name: "Upload Test Results"
|
||
if: always()
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: backend-test-results
|
||
path: backend/build/reports/tests/
|
||
retention-days: 7
|
||
|
||
- name: "Stop Gradle"
|
||
if: always()
|
||
working-directory: ./backend
|
||
run: ./gradlew --stop
|
||
|
||
backend-build:
|
||
name: "Backend Build & Package"
|
||
needs: backend-lint
|
||
container:
|
||
image: "cimg/openjdk:23.0-node"
|
||
steps:
|
||
- name: "Checkout"
|
||
uses: actions/checkout@v4
|
||
|
||
- name: "Cache Gradle dependencies"
|
||
uses: https://github.com/actions/cache@v4
|
||
with:
|
||
path: |
|
||
~/.gradle/caches
|
||
~/.gradle/wrapper
|
||
backend/.gradle
|
||
key: gradle-${{ runner.os }}-${{ hashFiles('backend/build.gradle.kts', 'backend/gradle/wrapper/gradle-wrapper.properties') }}
|
||
restore-keys: |
|
||
gradle-${{ runner.os }}-
|
||
|
||
- name: "Setup Gradle"
|
||
working-directory: ./backend
|
||
run: chmod +x ./gradlew
|
||
|
||
- name: "Build JAR"
|
||
working-directory: ./backend
|
||
run: ./gradlew bootJar --parallel --build-cache
|
||
|
||
- name: "Upload Artifacts"
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: backend-jar
|
||
path: backend/build/libs/*.jar
|
||
retention-days: 5
|
||
|
||
- name: "Stop Gradle"
|
||
if: always()
|
||
working-directory: ./backend
|
||
run: ./gradlew --stop
|
||
|
||
frontend-lint:
|
||
name: "Frontend Lint & Format"
|
||
container:
|
||
image: catthehacker/ubuntu:act-latest
|
||
steps:
|
||
- name: "Checkout Code"
|
||
uses: actions/checkout@v4
|
||
|
||
- name: "Install Bun"
|
||
uses: oven-sh/setup-bun@v2
|
||
with:
|
||
bun-version: latest
|
||
|
||
- name: "Cache Dependencies"
|
||
uses: actions/cache@v4
|
||
with:
|
||
path: frontend/node_modules
|
||
key: ${{ runner.os }}-bun-${{ hashFiles('frontend/bun.lock') }}
|
||
restore-keys: |
|
||
${{ runner.os }}-bun-
|
||
|
||
- name: "Install dependencies"
|
||
working-directory: ./frontend
|
||
run: bun install --frozen-lockfile
|
||
|
||
- name: "Run ESLint"
|
||
working-directory: ./frontend
|
||
run: bun run lint
|
||
|
||
- name: "Run Prettier Check"
|
||
working-directory: ./frontend
|
||
run: bun run format:check
|
||
|
||
frontend-test:
|
||
name: "Frontend Tests"
|
||
needs: frontend-lint
|
||
container:
|
||
image: catthehacker/ubuntu:act-latest
|
||
steps:
|
||
- name: "Checkout Code"
|
||
uses: actions/checkout@v4
|
||
|
||
- name: "Install Bun"
|
||
uses: oven-sh/setup-bun@v2
|
||
with:
|
||
bun-version: latest
|
||
|
||
- name: "Cache Dependencies"
|
||
uses: actions/cache@v4
|
||
with:
|
||
path: frontend/node_modules
|
||
key: ${{ runner.os }}-bun-${{ hashFiles('frontend/bun.lock') }}
|
||
restore-keys: |
|
||
${{ runner.os }}-bun-
|
||
|
||
- name: "Install dependencies"
|
||
working-directory: ./frontend
|
||
run: bun install --frozen-lockfile
|
||
|
||
- name: "Run Tests"
|
||
working-directory: ./frontend
|
||
run: bun run test --no-watch --browsers=ChromeHeadless
|
||
|
||
- name: "Upload Test Results"
|
||
if: always()
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: frontend-test-results
|
||
path: frontend/coverage/
|
||
retention-days: 7
|
||
|
||
frontend-build:
|
||
name: "Frontend Build"
|
||
needs: frontend-test
|
||
container:
|
||
image: catthehacker/ubuntu:act-latest
|
||
steps:
|
||
- name: "Checkout Code"
|
||
uses: actions/checkout@v4
|
||
|
||
- name: "Install Bun"
|
||
uses: oven-sh/setup-bun@v2
|
||
with:
|
||
bun-version: latest
|
||
|
||
- name: "Cache Dependencies"
|
||
uses: actions/cache@v4
|
||
with:
|
||
path: frontend/node_modules
|
||
key: ${{ runner.os }}-bun-${{ hashFiles('frontend/bun.lock') }}
|
||
restore-keys: |
|
||
${{ runner.os }}-bun-
|
||
|
||
- name: "Cache Build"
|
||
uses: actions/cache@v4
|
||
with:
|
||
path: frontend/dist
|
||
key: ${{ runner.os }}-dist-${{ github.sha }}
|
||
restore-keys: |
|
||
${{ runner.os }}-dist-
|
||
|
||
- name: "Install dependencies"
|
||
working-directory: ./frontend
|
||
run: bun install --frozen-lockfile
|
||
|
||
- name: "Production Build"
|
||
working-directory: ./frontend
|
||
run: bun run build --configuration production
|
||
|
||
- name: "Upload Build Artifacts"
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: frontend-build
|
||
path: frontend/dist/
|
||
retention-days: 5
|
||
|
||
pr-analysis:
|
||
name: "PR Quality Analysis"
|
||
if: github.event_name == 'pull_request'
|
||
runs-on: ubuntu-latest
|
||
needs: [backend-build, frontend-build]
|
||
steps:
|
||
- name: "Checkout Code"
|
||
uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 0
|
||
|
||
- name: "Setup Node.js"
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: 20
|
||
|
||
- name: "Code Size Analysis"
|
||
run: |
|
||
echo "### PR Size Analysis :mag:" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Metric | Value |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Files changed | $(git diff --name-only origin/${{ github.base_ref }} | wc -l) |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Lines added | $(git diff --stat origin/${{ github.base_ref }} | tail -n 1 | awk '{print $4}') |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Lines removed | $(git diff --stat origin/${{ github.base_ref }} | tail -n 1 | awk '{print $6}') |" >> $GITHUB_STEP_SUMMARY
|
||
|
||
- name: "PR Summary"
|
||
run: |
|
||
echo "### PR Summary :clipboard:" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "#### Modified Files by Type" >> $GITHUB_STEP_SUMMARY
|
||
echo "| File Type | Count |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Java (.java) | $(git diff --name-only origin/${{ github.base_ref }} | grep "\.java$" | wc -l) |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| TypeScript (.ts) | $(git diff --name-only origin/${{ github.base_ref }} | grep "\.ts$" | wc -l) |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| HTML (.html) | $(git diff --name-only origin/${{ github.base_ref }} | grep "\.html$" | wc -l) |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| CSS/SCSS (.css/.scss) | $(git diff --name-only origin/${{ github.base_ref }} | grep -E "\.(css|scss)$" | wc -l) |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Configuration files | $(git diff --name-only origin/${{ github.base_ref }} | grep -E "\.(json|yml|yaml|properties|xml|gradle|kts)$" | wc -l) |" >> $GITHUB_STEP_SUMMARY
|
||
|
||
- name: "Add Test Analysis"
|
||
run: |
|
||
echo "### Test Coverage Impact :test_tube:" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Component | Status |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY
|
||
|
||
JAVA_FILES=$(git diff --name-only origin/${{ github.base_ref }} | grep "\.java$" | wc -l)
|
||
JAVA_TEST_FILES=$(git diff --name-only origin/${{ github.base_ref }} | grep "Test\.java$" | wc -l)
|
||
|
||
TS_FILES=$(git diff --name-only origin/${{ github.base_ref }} | grep "\.ts$" | grep -v "\.spec\.ts$" | wc -l)
|
||
TS_TEST_FILES=$(git diff --name-only origin/${{ github.base_ref }} | grep "\.spec\.ts$" | wc -l)
|
||
|
||
if [ $JAVA_FILES -gt 0 ] && [ $JAVA_TEST_FILES -eq 0 ]; then
|
||
echo "| Backend | ⚠️ Java code changes without test updates |" >> $GITHUB_STEP_SUMMARY
|
||
elif [ $JAVA_FILES -gt 0 ] && [ $JAVA_TEST_FILES -gt 0 ]; then
|
||
echo "| Backend | ✅ Java code changes with test updates |" >> $GITHUB_STEP_SUMMARY
|
||
elif [ $JAVA_FILES -eq 0 ]; then
|
||
echo "| Backend | ➖ No Java code changes |" >> $GITHUB_STEP_SUMMARY
|
||
fi
|
||
|
||
if [ $TS_FILES -gt 0 ] && [ $TS_TEST_FILES -eq 0 ]; then
|
||
echo "| Frontend | ⚠️ TypeScript code changes without test updates |" >> $GITHUB_STEP_SUMMARY
|
||
elif [ $TS_FILES -gt 0 ] && [ $TS_TEST_FILES -gt 0 ]; then
|
||
echo "| Frontend | ✅ TypeScript code changes with test updates |" >> $GITHUB_STEP_SUMMARY
|
||
elif [ $TS_FILES -eq 0 ]; then
|
||
echo "| Frontend | ➖ No TypeScript code changes |" >> $GITHUB_STEP_SUMMARY
|
||
fi
|
||
|
||
merge-readiness:
|
||
name: "Merge Readiness Check"
|
||
needs: [backend-lint, backend-build, frontend-lint, frontend-test, frontend-build]
|
||
if: github.event_name == 'pull_request'
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: "Merge Status"
|
||
run: |
|
||
echo "### PR Readiness Status :rocket:" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Check | Status |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Backend Checkstyle | ✅ Passed |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Backend Tests | ✅ Passed |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Backend Build | ✅ Passed |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Frontend Lint | ✅ Passed |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Frontend Tests | ✅ Passed |" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Frontend Build | ✅ Passed |" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "✅ **This PR is ready to merge!**" >> $GITHUB_STEP_SUMMARY |