chore(configuration): Update Dockerfile, docker-compose and flyway mi… #8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| pull_request: | |
| branches: [main] | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| JAVA_VERSION: '21' | |
| jobs: | |
| # ============================================================================== | |
| # Job 1: Static Analysis (Detekt) | |
| # ============================================================================== | |
| detekt: | |
| name: Static Analysis | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'temurin' | |
| java-version: ${{ env.JAVA_VERSION }} | |
| cache: 'gradle' | |
| - name: Setup Gradle | |
| uses: gradle/actions/setup-gradle@v3 | |
| with: | |
| gradle-version: wrapper | |
| cache-read-only: ${{ github.ref != 'refs/heads/main' }} | |
| - name: Run Detekt | |
| run: ./gradlew detekt --no-daemon --parallel | |
| - name: Upload Detekt Results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: detekt-results | |
| path: '**/build/reports/detekt/' | |
| retention-days: 7 | |
| # ============================================================================== | |
| # Job 2: Unit Tests | |
| # ============================================================================== | |
| unit-tests: | |
| name: Unit Tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'temurin' | |
| java-version: ${{ env.JAVA_VERSION }} | |
| cache: 'gradle' | |
| - name: Setup Gradle | |
| uses: gradle/actions/setup-gradle@v3 | |
| with: | |
| gradle-version: wrapper | |
| - name: Run Unit Tests | |
| run: ./gradlew test --no-daemon --parallel | |
| - name: Publish Test Results | |
| if: always() | |
| uses: EnricoMi/publish-unit-test-result-action@v2 | |
| with: | |
| files: '**/build/test-results/test/TEST-*.xml' | |
| check_name: 'Unit Test Results' | |
| - name: Upload Test Reports | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: unit-test-reports | |
| path: '**/build/reports/tests/' | |
| retention-days: 7 | |
| # ============================================================================== | |
| # Job 3: Integration Tests | |
| # ============================================================================== | |
| integration-tests: | |
| name: Integration Tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'temurin' | |
| java-version: ${{ env.JAVA_VERSION }} | |
| cache: 'gradle' | |
| - name: Setup Gradle | |
| uses: gradle/actions/setup-gradle@v3 | |
| with: | |
| gradle-version: wrapper | |
| - name: Run Integration Tests | |
| run: ./gradlew integrationTest --no-daemon --parallel | |
| - name: Publish Integration Test Results | |
| if: always() | |
| uses: EnricoMi/publish-unit-test-result-action@v2 | |
| with: | |
| files: '**/build/test-results/integrationTest/TEST-*.xml' | |
| check_name: 'Integration Test Results' | |
| - name: Upload Integration Test Reports | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: integration-test-reports | |
| path: '**/build/reports/tests/integrationTest/' | |
| retention-days: 7 | |
| # ============================================================================== | |
| # Job 4: Build and Push Docker Image (only on main) | |
| # ============================================================================== | |
| build: | |
| name: Build & Push Image | |
| runs-on: ubuntu-latest | |
| needs: [detekt, unit-tests, integration-tests] | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| permissions: | |
| contents: read | |
| packages: write | |
| security-events: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Extract version from gradle.properties | |
| id: version | |
| run: | | |
| VERSION=$(grep '^version=' gradle.properties | cut -d'=' -f2) | |
| echo "version=${VERSION}" >> $GITHUB_OUTPUT | |
| echo "Version: ${VERSION}" | |
| # Convert image name to lowercase for Docker compatibility | |
| IMAGE_NAME_LOWER=$(echo "${{ env.IMAGE_NAME }}" | tr '[:upper:]' '[:lower:]') | |
| echo "image_name_lower=${IMAGE_NAME_LOWER}" >> $GITHUB_OUTPUT | |
| - name: Setup JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'temurin' | |
| java-version: ${{ env.JAVA_VERSION }} | |
| cache: 'gradle' | |
| - name: Build application JAR | |
| run: ./gradlew assembly:buildFatJar --no-daemon --parallel -x test -x detekt | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GHCR_PAT }} | |
| - name: Extract Docker metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=semver,pattern={{version}},value=${{ steps.version.outputs.version }} | |
| type=semver,pattern={{major}}.{{minor}},value=${{ steps.version.outputs.version }} | |
| type=sha,format=short | |
| type=raw,value=latest | |
| - name: Build and push Docker image | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| platforms: linux/amd64 | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| build-args: | | |
| APP_VERSION=${{ steps.version.outputs.version }} | |
| BUILD_DATE=${{ github.event.head_commit.timestamp }} | |
| VCS_REF=${{ github.sha }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| provenance: true | |
| sbom: true | |
| - name: Scan image with Trivy | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| image-ref: ${{ env.REGISTRY }}/${{ steps.version.outputs.image_name_lower }}:${{ steps.version.outputs.version }} | |
| format: 'sarif' | |
| output: 'trivy-results.sarif' | |
| severity: 'CRITICAL,HIGH' | |
| exit-code: '0' | |
| - name: Upload Trivy results to GitHub Security | |
| if: always() | |
| uses: github/codeql-action/upload-sarif@v3 | |
| with: | |
| sarif_file: 'trivy-results.sarif' | |
| - name: Generate SBOM with Syft | |
| uses: anchore/sbom-action@v0 | |
| with: | |
| image: ${{ env.REGISTRY }}/${{ steps.version.outputs.image_name_lower }}:${{ steps.version.outputs.version }} | |
| format: cyclonedx-json | |
| output-file: sbom.cyclonedx.json | |
| - name: Upload SBOM artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: sbom | |
| path: sbom.cyclonedx.json | |
| retention-days: 90 | |
| - name: Summary | |
| run: | | |
| echo "## Build Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Image:** \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "**Commit:** \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "**Tags:**" >> $GITHUB_STEP_SUMMARY | |
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | |
| echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY | |
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY |