name: CI on: push: jobs: backend-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up JDK 25 uses: actions/setup-java@v4 with: distribution: temurin java-version: 25 - name: Run backend verify run: cd backend && ./mvnw -B verify frontend-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Node 24 uses: actions/setup-node@v4 with: node-version: 24 - name: Install dependencies run: cd frontend && npm ci - name: Lint run: cd frontend && npm run lint - name: Generate API types run: cd frontend && npm run generate:api - name: Type check run: cd frontend && npm run type-check - name: Unit tests run: cd frontend && npm run test:unit -- --run - name: Production build run: cd frontend && npm run build frontend-e2e: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Node 24 uses: actions/setup-node@v4 with: node-version: 24 - name: Install dependencies run: cd frontend && npm ci - name: Install Playwright browsers run: cd frontend && npx playwright install --with-deps chromium - name: Run E2E tests run: cd frontend && npm run test:e2e - name: Upload Playwright report uses: actions/upload-artifact@v4 if: ${{ !cancelled() }} with: name: playwright-report path: frontend/playwright-report/ retention-days: 30 build-and-publish: needs: [backend-test, frontend-test, frontend-e2e] if: startsWith(github.ref, 'refs/tags/') && contains(github.ref_name, '.') runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Parse SemVer tag id: semver run: | TAG="${{ github.ref_name }}" if [[ ! "$TAG" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "Not a valid SemVer tag: $TAG" exit 1 fi MAJOR="${TAG%%.*}" MINOR="${TAG%.*}" echo "full=$TAG" >> "$GITHUB_OUTPUT" echo "minor=$MINOR" >> "$GITHUB_OUTPUT" echo "major=$MAJOR" >> "$GITHUB_OUTPUT" - name: Build image run: | REGISTRY="${{ github.server_url }}" REGISTRY="${REGISTRY#https://}" REGISTRY="${REGISTRY#http://}" REPO="${{ github.repository }}" IMAGE="${REGISTRY}/${REPO}" docker build -t "${IMAGE}:${{ steps.semver.outputs.full }}" . docker tag "${IMAGE}:${{ steps.semver.outputs.full }}" "${IMAGE}:${{ steps.semver.outputs.minor }}" docker tag "${IMAGE}:${{ steps.semver.outputs.full }}" "${IMAGE}:${{ steps.semver.outputs.major }}" docker tag "${IMAGE}:${{ steps.semver.outputs.full }}" "${IMAGE}:latest" echo "IMAGE=${IMAGE}" >> "$GITHUB_ENV" - name: Push to registry run: | echo "${{ secrets.REGISTRY_TOKEN }}" | docker login -u "${{ github.repository_owner }}" --password-stdin "${IMAGE%%/*}" docker push "${IMAGE}:${{ steps.semver.outputs.full }}" docker push "${IMAGE}:${{ steps.semver.outputs.minor }}" docker push "${IMAGE}:${{ steps.semver.outputs.major }}" docker push "${IMAGE}:latest"