diff --git a/.github/workflows/backoffice-bff-ci.yaml b/.github/workflows/backoffice-bff-ci.yaml index bc86417285..166eba0d97 100644 --- a/.github/workflows/backoffice-bff-ci.yaml +++ b/.github/workflows/backoffice-bff-ci.yaml @@ -2,14 +2,14 @@ name: backoffice-bff service ci on: push: - branches: [ "main" ] + branches: ["**"] paths: - "backoffice-bff/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/backoffice-bff-ci.yaml" - "pom.xml" pull_request: - branches: [ "main" ] + branches: ["**"] paths: - "backoffice-bff/**" - ".github/workflows/actions/action.yaml" @@ -18,15 +18,25 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -f backoffice-bff -Dcheckstyle.output.file=backoffice-bff-checkstyle-result.xml @@ -34,9 +44,28 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/backoffice-bff-checkstyle-result.xml' + path: "**/backoffice-bff-checkstyle-result.xml" - name: Run Maven Verify run: mvn clean verify -f backoffice-bff + + - name: Publish Test Results + uses: dorny/test-reporter@v1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('backoffice-bff/**/target/surefire-reports/TEST-*.xml', 'backoffice-bff/**/target/failsafe-reports/TEST-*.xml') != '' }} + with: + name: Backoffice-BFF-Test-Results + path: "backoffice-bff/**/*-reports/TEST*.xml" + reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: backoffice-bff-junit-test-results + path: | + backoffice-bff/**/target/surefire-reports/TEST-*.xml + backoffice-bff/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -48,26 +77,76 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('backoffice-bff/target/site/jacoco/jacoco.xml') != '' }} + with: + paths: ${{github.workspace}}/backoffice-bff/target/site/jacoco/jacoco.xml + token: ${{secrets.GITHUB_TOKEN}} + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Backoffice BFF Coverage Report" + update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: backoffice-bff-jacoco-coverage-report + path: | + backoffice-bff/target/site/jacoco/jacoco.xml + backoffice-bff/target/site/jacoco-it/jacoco.xml + backoffice-bff/target/site/jacoco/index.html + backoffice-bff/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl backoffice-bff -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./backoffice-bff push: true - tags: ghcr.io/nashtech-garage/yas-backoffice-bff:latest + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-backoffice-bff:latest diff --git a/.github/workflows/backoffice-ci.yaml b/.github/workflows/backoffice-ci.yaml index 262082dbe8..1eaac35dfb 100644 --- a/.github/workflows/backoffice-ci.yaml +++ b/.github/workflows/backoffice-ci.yaml @@ -2,13 +2,13 @@ name: backoffice service ci on: push: - branches: [ "main" ] + branches: ["**"] paths: - "backoffice/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/backoffice-ci.yaml" pull_request: - branches: [ "main" ] + branches: ["**"] paths: - "backoffice/**" - ".github/workflows/actions/action.yaml" @@ -16,71 +16,93 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run linting, prettier, security checks, SonarCloud analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write + security-events: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: actions/setup-node@v4 + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 with: node-version: 20 - - run: npm ci + + - name: Install dependencies + run: npm ci working-directory: backoffice - - run: npm run build + + - name: Build application + run: npm run build working-directory: backoffice - - run: npm run lint + + - name: Run linting + run: npm run lint working-directory: backoffice - - run: npx prettier --check . + + - name: Run Prettier check + run: npx prettier --check . working-directory: backoffice - - run: npm audit --omit=dev + + - name: Audit dependencies + run: npm audit --omit=dev continue-on-error: true working-directory: backoffice + - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@0.24.0 + uses: aquasecurity/trivy-action@6e7b7d1fd3e4fef0c5fa8cce1229c54b2c9bd0d8 # v0.24.0 with: - scan-type: 'fs' - scan-ref: './backoffice' - format: 'sarif' - output: 'trivy-results.sarif' + scan-type: "fs" + scan-ref: "./backoffice" + format: "sarif" + output: "trivy-results.sarif" + - name: SonarCloud Scan if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: SonarSource/sonarcloud-github-action@master with: projectBaseDir: backoffice env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build Docker image - if: ${{ github.ref == 'refs/heads/main' }} + + - name: Build and push Docker images uses: docker/build-push-action@v6 with: context: ./backoffice - tags: ghcr.io/nashtech-garage/yas-backoffice:latest - - name: Run Trivy vulnerability scanner - if: ${{ github.ref == 'refs/heads/main' }} - uses: aquasecurity/trivy-action@0.24.0 - with: - image-ref: 'ghcr.io/nashtech-garage/yas-backoffice:latest' - format: 'sarif' - output: 'trivy-results.sarif' - - name: Push Docker image - if: ${{ github.ref == 'refs/heads/main' }} - uses: docker/build-push-action@v6 - with: push: true - context: ./backoffice - tags: ghcr.io/nashtech-garage/yas-backoffice:latest - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: 'trivy-results.sarif' + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-backoffice:latest diff --git a/.github/workflows/cart-ci.yaml b/.github/workflows/cart-ci.yaml index 59f0045fa6..0dff69268d 100644 --- a/.github/workflows/cart-ci.yaml +++ b/.github/workflows/cart-ci.yaml @@ -2,14 +2,14 @@ name: cart service ci on: push: - branches: [ "main" ] + branches: ["**"] paths: - "cart/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/cart-ci.yaml" - "pom.xml" pull_request: - branches: [ "main" ] + branches: ["**"] paths: - "cart/**" - ".github/workflows/actions/action.yaml" @@ -18,73 +18,141 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Chạy unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write + security-events: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl cart -am + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl cart -am -Dcheckstyle.output.file=cart-checkstyle-result.xml + - name: Upload Checkstyle Result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/cart-checkstyle-result.xml' - - name: Test Results + path: "**/cart-checkstyle-result.xml" + + - name: Publish Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('cart/**/target/surefire-reports/TEST-*.xml', 'cart/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Cart-Service-Unit-Test-Results path: "cart/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: cart-junit-test-results + path: | + cart/**/target/surefire-reports/TEST-*.xml + cart/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 + - name: OWASP Dependency Check if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: dependency-check/Dependency-Check_Action@main env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral + - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports - - name: Analyze with sonar cloud + if-no-files-found: warn + retention-days: 14 + + - name: Analyze with SonarCloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl cart -am + - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('cart/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/cart/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Cart Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Cart Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: cart-jacoco-coverage-report + path: | + cart/target/site/jacoco/jacoco.xml + cart/target/site/jacoco-it/jacoco.xml + cart/target/site/jacoco/index.html + cart/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image và push lên registry (chỉ chạy trên main branch) + # ============================================================================ + Build: + needs: Test # Phụ thuộc vào phase Test thành công + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} # Chỉ chạy trên main branch hoặc workflow_dispatch + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl cart -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./cart push: true - tags: ghcr.io/nashtech-garage/yas-cart:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-cart:latest diff --git a/.github/workflows/charts-ci.yaml b/.github/workflows/charts-ci.yaml index 2cb67884c3..3ffa092688 100644 --- a/.github/workflows/charts-ci.yaml +++ b/.github/workflows/charts-ci.yaml @@ -2,7 +2,7 @@ name: release charts ci on: push: - branches: [ "main" ] + branches: ["**"] paths: - "k8s/charts/**" - ".github/workflows/charts-ci.yaml" @@ -35,4 +35,4 @@ jobs: with: charts_dir: k8s/charts env: - CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" \ No newline at end of file + CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a4905de43c..ee7379c925 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -13,11 +13,11 @@ name: "CodeQL Advanced" on: push: - branches: [ "main" ] + branches: ["**"] pull_request: - branches: [ "main" ] + branches: ["**"] schedule: - - cron: '19 21 * * 0' + - cron: "19 21 * * 0" jobs: analyze: @@ -43,10 +43,10 @@ jobs: fail-fast: false matrix: include: - - language: java-kotlin - build-mode: none # This mode only analyzes Java. Set this to 'autobuild' or 'manual' to analyze Kotlin too. - - language: javascript-typescript - build-mode: none + - language: java-kotlin + build-mode: none # This mode only analyzes Java. Set this to 'autobuild' or 'manual' to analyze Kotlin too. + - language: javascript-typescript + build-mode: none # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' # Use `c-cpp` to analyze code written in C, C++ or both # Use 'java-kotlin' to analyze code written in Java, Kotlin or both @@ -56,39 +56,39 @@ jobs: # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages steps: - - name: Checkout repository - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality - # If the analyze step fails for one of the languages you are analyzing with - # "We were unable to automatically build your code", modify the matrix above - # to set the build mode to "manual" for that language. Then modify this step - # to build your code. - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - if: matrix.build-mode == 'manual' - shell: bash - run: | - echo 'If you are using a "manual" build mode for one or more of the' \ - 'languages you are analyzing, replace this with the commands to build' \ - 'your code, for example:' - echo ' make bootstrap' - echo ' make release' - exit 1 + # If the analyze step fails for one of the languages you are analyzing with + # "We were unable to automatically build your code", modify the matrix above + # to set the build mode to "manual" for that language. Then modify this step + # to build your code. + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + - if: matrix.build-mode == 'manual' + shell: bash + run: | + echo 'If you are using a "manual" build mode for one or more of the' \ + 'languages you are analyzing, replace this with the commands to build' \ + 'your code, for example:' + echo ' make bootstrap' + echo ' make release' + exit 1 - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/customer-ci.yaml b/.github/workflows/customer-ci.yaml index 9258bd4ade..5b01db8177 100644 --- a/.github/workflows/customer-ci.yaml +++ b/.github/workflows/customer-ci.yaml @@ -2,14 +2,14 @@ name: customer service ci on: push: - branches: [ "main" ] + branches: ["**"] paths: - "customer/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/customer-ci.yaml" - "pom.xml" pull_request: - branches: [ "main" ] + branches: ["**"] paths: - "customer/**" - ".github/workflows/actions/action.yaml" @@ -18,16 +18,26 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl customer -am - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} @@ -36,14 +46,25 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/customer-checkstyle-result.xml' + path: "**/customer-checkstyle-result.xml" - name: Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('customer/**/target/surefire-reports/TEST-*.xml', 'customer/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Customer-Service-Unit-Test-Results path: "customer/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: customer-junit-test-results + path: | + customer/**/target/surefire-reports/TEST-*.xml + customer/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -55,36 +76,75 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('customer/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/customer/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Customer Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Customer Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: customer-jacoco-coverage-report + path: | + customer/target/site/jacoco/jacoco.xml + customer/target/site/jacoco-it/jacoco.xml + customer/target/site/jacoco/index.html + customer/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl customer -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./customer push: true - tags: ghcr.io/nashtech-garage/yas-customer:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-customer:latest diff --git a/.github/workflows/gitleaks-check.yaml b/.github/workflows/gitleaks-check.yaml index 4534d6144b..3e6f898906 100644 --- a/.github/workflows/gitleaks-check.yaml +++ b/.github/workflows/gitleaks-check.yaml @@ -1,17 +1,43 @@ -name: GitLeaks check nightly +name: GitLeaks check on: workflow_dispatch: schedule: - cron: "0 0 * * *" + push: + branches: ["**"] + pull_request: + branches: ["**"] + +permissions: + contents: read + actions: read + security-events: write + jobs: - check: + gitleaks: runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - name: Gitleaks check - run: | - docker pull zricethezav/gitleaks:v8.18.4 - docker run --rm -v ${{ github.workspace }}:/work -w /work zricethezav/gitleaks:v8.18.4 detect --source="." --config="/work/gitleaks.toml" --verbose --no-git \ No newline at end of file + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Gitleaks check + uses: gitleaks/gitleaks-action@v2 + continue-on-error: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITLEAKS_CONFIG: ${{ github.workspace }}/gitleaks.toml + + - name: Ensure SARIF file exists + if: always() + run: | + if [ ! -f results.sarif ]; then + echo '{"version":"2.1.0","runs":[]}' > results.sarif + fi + + - name: Upload SARIF to GitHub Security tab + if: always() + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: results.sarif \ No newline at end of file diff --git a/.github/workflows/inventory-ci.yaml b/.github/workflows/inventory-ci.yaml index a5e362ba3b..bd76afe85b 100644 --- a/.github/workflows/inventory-ci.yaml +++ b/.github/workflows/inventory-ci.yaml @@ -2,14 +2,14 @@ name: inventory service ci on: push: - branches: ["main"] + branches: ["**"] paths: - "inventory/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/inventory-ci.yaml" - "pom.xml" pull_request: - branches: ["main"] + branches: ["**"] paths: - "inventory/**" - ".github/workflows/actions/action.yaml" @@ -18,16 +18,26 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl inventory -am - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} @@ -36,29 +46,43 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/inventory-checkstyle-result.xml' + path: "**/inventory-checkstyle-result.xml" - name: Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('inventory/**/target/surefire-reports/TEST-*.xml', 'inventory/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Inventory-Service-Test-Results path: "inventory/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: inventory-junit-test-results + path: | + inventory/**/target/surefire-reports/TEST-*.xml + inventory/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: OWASP Dependency Check if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: dependency-check/Dependency-Check_Action@main env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -66,25 +90,61 @@ jobs: run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -f inventory - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('inventory/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/inventory/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Inventory Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Inventory Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: inventory-jacoco-coverage-report + path: | + inventory/target/site/jacoco/jacoco.xml + inventory/target/site/jacoco-it/jacoco.xml + inventory/target/site/jacoco/index.html + inventory/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl inventory -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./inventory push: true - tags: ghcr.io/nashtech-garage/yas-inventory:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-inventory:latest diff --git a/.github/workflows/location-ci.yaml b/.github/workflows/location-ci.yaml index 2199903905..7883830fdb 100644 --- a/.github/workflows/location-ci.yaml +++ b/.github/workflows/location-ci.yaml @@ -2,14 +2,14 @@ name: location service ci on: push: - branches: ["main"] + branches: ["**"] paths: - "location/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/location-ci.yaml" - "pom.xml" pull_request: - branches: ["main"] + branches: ["**"] paths: - "location/**" - ".github/workflows/actions/action.yaml" @@ -18,16 +18,26 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl location -am - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} @@ -36,14 +46,25 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/location-checkstyle-result.xml' + path: "**/location-checkstyle-result.xml" - name: Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('location/**/target/surefire-reports/TEST-*.xml', 'location/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Location-Service-Unit-Test-Results path: "location/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: location-junit-test-results + path: | + location/**/target/surefire-reports/TEST-*.xml + location/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -55,36 +76,75 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('location/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/location/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Location Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Location Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: location-jacoco-coverage-report + path: | + location/target/site/jacoco/jacoco.xml + location/target/site/jacoco-it/jacoco.xml + location/target/site/jacoco/index.html + location/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl location -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./location push: true - tags: ghcr.io/nashtech-garage/yas-location:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-location:latest diff --git a/.github/workflows/media-ci.yaml b/.github/workflows/media-ci.yaml index 006fb4fb92..b01e5b1b05 100644 --- a/.github/workflows/media-ci.yaml +++ b/.github/workflows/media-ci.yaml @@ -2,14 +2,14 @@ name: media service ci on: push: - branches: [ "main" ] + branches: ["**"] paths: - "media/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/media-ci.yaml" - "pom.xml" pull_request: - branches: [ "main" ] + branches: ["**"] paths: - "media/**" - ".github/workflows/actions/action.yaml" @@ -18,16 +18,26 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl media -am - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} @@ -36,14 +46,25 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/media-checkstyle-result.xml' + path: "**/media-checkstyle-result.xml" - name: Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('media/**/target/surefire-reports/TEST-*.xml', 'media/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Media-Service-Unit-Test-Results path: "media/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: media-junit-test-results + path: | + media/**/target/surefire-reports/TEST-*.xml + media/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -55,36 +76,75 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('media/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/media/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Media Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Media Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: media-jacoco-coverage-report + path: | + media/target/site/jacoco/jacoco.xml + media/target/site/jacoco-it/jacoco.xml + media/target/site/jacoco/index.html + media/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl media -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./media push: true - tags: ghcr.io/nashtech-garage/yas-media:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-media:latest diff --git a/.github/workflows/order-ci.yaml b/.github/workflows/order-ci.yaml index a9a37d2feb..64af2922ff 100644 --- a/.github/workflows/order-ci.yaml +++ b/.github/workflows/order-ci.yaml @@ -2,14 +2,14 @@ name: order service ci on: push: - branches: ["main"] + branches: ["**"] paths: - "order/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/order-ci.yaml" - "pom.xml" pull_request: - branches: ["main"] + branches: ["**"] paths: - "order/**" - ".github/workflows/actions/action.yaml" @@ -18,16 +18,26 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl order -am - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} @@ -36,14 +46,25 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/order-checkstyle-result.xml' + path: "**/order-checkstyle-result.xml" - name: Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('order/**/target/surefire-reports/TEST-*.xml', 'order/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Order-Service-Unit-Test-Results path: "order/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: order-junit-test-results + path: | + order/**/target/surefire-reports/TEST-*.xml + order/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -55,36 +76,75 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('order/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/order/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Order Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Order Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: order-jacoco-coverage-report + path: | + order/target/site/jacoco/jacoco.xml + order/target/site/jacoco-it/jacoco.xml + order/target/site/jacoco/index.html + order/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl order -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./order push: true - tags: ghcr.io/nashtech-garage/yas-order:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-order:latest diff --git a/.github/workflows/payment-ci.yaml b/.github/workflows/payment-ci.yaml index c311795486..3f078ea1b0 100644 --- a/.github/workflows/payment-ci.yaml +++ b/.github/workflows/payment-ci.yaml @@ -2,14 +2,14 @@ name: payment service ci on: push: - branches: ["main"] + branches: ["**"] paths: - "payment/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/payment-ci.yaml" - "pom.xml" pull_request: - branches: ["main"] + branches: ["**"] paths: - "payment/**" - ".github/workflows/actions/action.yaml" @@ -18,16 +18,26 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl payment -am - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} @@ -36,14 +46,25 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/payment-checkstyle-result.xml' + path: "**/payment-checkstyle-result.xml" - name: Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('payment/**/target/surefire-reports/TEST-*.xml', 'payment/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Payment-Service-Unit-Test-Results path: "payment/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: payment-junit-test-results + path: | + payment/**/target/surefire-reports/TEST-*.xml + payment/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -55,36 +76,75 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('payment/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/payment/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Payment Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Payment Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: payment-jacoco-coverage-report + path: | + payment/target/site/jacoco/jacoco.xml + payment/target/site/jacoco-it/jacoco.xml + payment/target/site/jacoco/index.html + payment/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl payment -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./payment push: true - tags: ghcr.io/nashtech-garage/yas-payment:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-payment:latest diff --git a/.github/workflows/payment-paypal-ci.yaml b/.github/workflows/payment-paypal-ci.yaml index bc0ad53089..6706b87148 100644 --- a/.github/workflows/payment-paypal-ci.yaml +++ b/.github/workflows/payment-paypal-ci.yaml @@ -2,14 +2,14 @@ name: payment-paypal service ci on: push: - branches: ["main"] + branches: ["**"] paths: - "payment-paypal/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/payment-paypal-ci.yaml" - "pom.xml" pull_request: - branches: ["main"] + branches: ["**"] paths: - "payment-paypal/**" - ".github/workflows/actions/action.yaml" @@ -18,16 +18,26 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl payment-paypal -am - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} @@ -36,14 +46,25 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/payment-paypal-checkstyle-result.xml' + path: "**/payment-paypal-checkstyle-result.xml" - name: Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('payment-paypal/**/target/surefire-reports/TEST-*.xml', 'payment-paypal/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Payment-Paypal-Unit-Test-Results path: "payment-paypal/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: payment-paypal-junit-test-results + path: | + payment-paypal/**/target/surefire-reports/TEST-*.xml + payment-paypal/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -55,36 +76,75 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('payment-paypal/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/payment-paypal/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Payment Paypal Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Payment Paypal Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: payment-paypal-jacoco-coverage-report + path: | + payment-paypal/target/site/jacoco/jacoco.xml + payment-paypal/target/site/jacoco-it/jacoco.xml + payment-paypal/target/site/jacoco/index.html + payment-paypal/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl payment-paypal -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./payment-paypal push: true - tags: ghcr.io/nashtech-garage/yas-payment-paypal:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-payment-paypal:latest diff --git a/.github/workflows/product-ci.yaml b/.github/workflows/product-ci.yaml index caf92af448..25a55b4be0 100644 --- a/.github/workflows/product-ci.yaml +++ b/.github/workflows/product-ci.yaml @@ -2,14 +2,14 @@ name: product service ci on: push: - branches: [ "main" ] + branches: ["**"] paths: - "product/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/product-ci.yaml" - "pom.xml" pull_request: - branches: [ "main" ] + branches: ["**"] paths: - "product/**" - ".github/workflows/actions/action.yaml" @@ -18,16 +18,26 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl product -am - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} @@ -36,14 +46,25 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/product-checkstyle-result.xml' + path: "**/product-checkstyle-result.xml" - name: Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('product/**/target/surefire-reports/TEST-*.xml', 'product/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Product-Service-Unit-Test-Results path: "product/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: product-junit-test-results + path: | + product/**/target/surefire-reports/TEST-*.xml + product/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -55,36 +76,75 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('product/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/product/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Product Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Product Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: product-jacoco-coverage-report + path: | + product/target/site/jacoco/jacoco.xml + product/target/site/jacoco-it/jacoco.xml + product/target/site/jacoco/index.html + product/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl product -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./product push: true - tags: ghcr.io/nashtech-garage/yas-product:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-product:latest diff --git a/.github/workflows/promotion-ci.yaml b/.github/workflows/promotion-ci.yaml index 3d1fa1458c..affd6df879 100644 --- a/.github/workflows/promotion-ci.yaml +++ b/.github/workflows/promotion-ci.yaml @@ -2,14 +2,14 @@ name: promotion service ci on: push: - branches: ["main"] + branches: ["**"] paths: - "promotion/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/promotion-ci.yaml" - "pom.xml" pull_request: - branches: ["main"] + branches: ["**"] paths: - "promotion/**" - ".github/workflows/actions/action.yaml" @@ -18,16 +18,26 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl promotion -am - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} @@ -36,14 +46,25 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/promotion-checkstyle-result.xml' + path: "**/promotion-checkstyle-result.xml" - name: Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('promotion/**/target/surefire-reports/TEST-*.xml', 'promotion/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Promotion-Service-Unit-Test-Results path: "promotion/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: promotion-junit-test-results + path: | + promotion/**/target/surefire-reports/TEST-*.xml + promotion/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -55,36 +76,75 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('promotion/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/promotion/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Promotion Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Promotion Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: promotion-jacoco-coverage-report + path: | + promotion/target/site/jacoco/jacoco.xml + promotion/target/site/jacoco-it/jacoco.xml + promotion/target/site/jacoco/index.html + promotion/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl promotion -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./promotion push: true - tags: ghcr.io/nashtech-garage/yas-promotion:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-promotion:latest diff --git a/.github/workflows/rating-ci.yaml b/.github/workflows/rating-ci.yaml index 9ad9c84ca8..91c236d6da 100644 --- a/.github/workflows/rating-ci.yaml +++ b/.github/workflows/rating-ci.yaml @@ -2,14 +2,14 @@ name: rating service ci on: push: - branches: ["main"] + branches: ["**"] paths: - "rating/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/rating-ci.yaml" - "pom.xml" pull_request: - branches: ["main"] + branches: ["**"] paths: - "rating/**" - ".github/workflows/actions/action.yaml" @@ -18,16 +18,26 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl rating -am - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} @@ -36,14 +46,25 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/rating-checkstyle-result.xml' + path: "**/rating-checkstyle-result.xml" - name: Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('rating/**/target/surefire-reports/TEST-*.xml', 'rating/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Rating-Service-Unit-Test-Results path: "rating/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: rating-junit-test-results + path: | + rating/**/target/surefire-reports/TEST-*.xml + rating/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -55,36 +76,75 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('rating/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/rating/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Rating Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Rating Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: rating-jacoco-coverage-report + path: | + rating/target/site/jacoco/jacoco.xml + rating/target/site/jacoco-it/jacoco.xml + rating/target/site/jacoco/index.html + rating/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl rating -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./rating push: true - tags: ghcr.io/nashtech-garage/yas-rating:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-rating:latest diff --git a/.github/workflows/recommendation-ci.yaml b/.github/workflows/recommendation-ci.yaml index ca8d1a2873..6e7391a8a1 100644 --- a/.github/workflows/recommendation-ci.yaml +++ b/.github/workflows/recommendation-ci.yaml @@ -2,14 +2,14 @@ name: recommendation service ci on: push: - branches: ["main"] + branches: ["**"] paths: - "recommendation/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/recommendation-ci.yaml" - "pom.xml" pull_request: - branches: ["main"] + branches: ["**"] paths: - "recommendation/**" - ".github/workflows/actions/action.yaml" @@ -18,16 +18,26 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl recommendation -am - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} @@ -36,14 +46,25 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/recommendation-checkstyle-result.xml' + path: "**/recommendation-checkstyle-result.xml" - name: Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('recommendation/**/target/surefire-reports/TEST-*.xml', 'recommendation/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Recommendation-Service-Unit-Test-Results path: "recommendation/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: recommendation-junit-test-results + path: | + recommendation/**/target/surefire-reports/TEST-*.xml + recommendation/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -55,36 +76,75 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('recommendation/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/recommendation/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Recommendation Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Recommendation Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: recommendation-jacoco-coverage-report + path: | + recommendation/target/site/jacoco/jacoco.xml + recommendation/target/site/jacoco-it/jacoco.xml + recommendation/target/site/jacoco/index.html + recommendation/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl recommendation -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./recommendation push: true - tags: ghcr.io/nashtech-garage/yas-recommendation:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-recommendation:latest diff --git a/.github/workflows/sampledata-ci.yaml b/.github/workflows/sampledata-ci.yaml index b3c7db5ed4..fc6eea6e47 100644 --- a/.github/workflows/sampledata-ci.yaml +++ b/.github/workflows/sampledata-ci.yaml @@ -2,14 +2,14 @@ name: sampledata service ci on: push: - branches: ["main"] + branches: ["**"] paths: - "sampledata/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/sampledata-ci.yaml" - "pom.xml" pull_request: - branches: ["main"] + branches: ["**"] paths: - "sampledata/**" - ".github/workflows/actions/action.yaml" @@ -18,16 +18,26 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl sampledata -am - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} @@ -36,7 +46,26 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/sampledata-checkstyle-result.xml' + path: "**/sampledata-checkstyle-result.xml" + + - name: Publish Test Results + uses: dorny/test-reporter@v1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('sampledata/**/target/surefire-reports/TEST-*.xml', 'sampledata/**/target/failsafe-reports/TEST-*.xml') != '' }} + with: + name: Sampledata-Service-Test-Results + path: "sampledata/**/*-reports/TEST*.xml" + reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: sampledata-junit-test-results + path: | + sampledata/**/target/surefire-reports/TEST-*.xml + sampledata/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -48,26 +77,76 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('sampledata/target/site/jacoco/jacoco.xml') != '' }} + with: + paths: ${{github.workspace}}/sampledata/target/site/jacoco/jacoco.xml + token: ${{secrets.GITHUB_TOKEN}} + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Sampledata Coverage Report" + update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: sampledata-jacoco-coverage-report + path: | + sampledata/target/site/jacoco/jacoco.xml + sampledata/target/site/jacoco-it/jacoco.xml + sampledata/target/site/jacoco/index.html + sampledata/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl sampledata -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./sampledata push: true - tags: ghcr.io/nashtech-garage/yas-sampledata:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-sampledata:latest diff --git a/.github/workflows/search-ci.yaml b/.github/workflows/search-ci.yaml index c77dc4011e..3449d749a6 100644 --- a/.github/workflows/search-ci.yaml +++ b/.github/workflows/search-ci.yaml @@ -2,14 +2,14 @@ name: search service ci on: push: - branches: ["main"] + branches: ["**"] paths: - "search/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/search-ci.yaml" - "pom.xml" pull_request: - branches: ["main"] + branches: ["**"] paths: - "search/**" - ".github/workflows/actions/action.yaml" @@ -18,73 +18,140 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write + pull-requests: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl search -am + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Install dependencies (skip common-library tests) + run: mvn install -pl search -am -DskipTests -Djacoco.skip=true --batch-mode --no-transfer-progress + + - name: Run Maven Tests + run: mvn test -f search --batch-mode --no-transfer-progress - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - run: mvn checkstyle:checkstyle -pl search -am -Dcheckstyle.output.file=search-checkstyle-result.xml + run: mvn checkstyle:checkstyle -f search -Dcheckstyle.output.file=search-checkstyle-result.xml --batch-mode --no-transfer-progress - name: Upload Checkstyle Result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/search-checkstyle-result.xml' + path: "**/search-checkstyle-result.xml" - name: Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('search/**/target/surefire-reports/TEST-*.xml', 'search/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Search-Service-Unit-Test-Results path: "search/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: search-junit-test-results + path: | + search/**/target/surefire-reports/TEST-*.xml + search/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -f search + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -f search --batch-mode --no-transfer-progress - name: OWASP Dependency Check if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: dependency-check/Dependency-Check_Action@main env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('search/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/search/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Search Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Search Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: search-jacoco-coverage-report + path: | + search/target/site/jacoco/jacoco.xml + search/target/site/jacoco-it/jacoco.xml + search/target/site/jacoco/index.html + search/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + - name: Enforce JaCoCo Coverage Threshold + run: mvn jacoco:check@check -f search --batch-mode --no-transfer-progress + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl search -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./search push: true - tags: ghcr.io/nashtech-garage/yas-search:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-search:latest diff --git a/.github/workflows/storefront-bff-ci.yaml b/.github/workflows/storefront-bff-ci.yaml index b9e9c534ea..2a2d904e0c 100644 --- a/.github/workflows/storefront-bff-ci.yaml +++ b/.github/workflows/storefront-bff-ci.yaml @@ -2,14 +2,14 @@ name: storefront-bff service ci on: push: - branches: [ "main" ] + branches: ["**"] paths: - "storefront-bff/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/storefront-bff-ci.yaml" - "pom.xml" pull_request: - branches: [ "main" ] + branches: ["**"] paths: - "storefront-bff/**" - ".github/workflows/actions/action.yaml" @@ -18,15 +18,25 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + - name: Run Maven Build Command run: mvn clean install -pl storefront-bff -am - name: Run Maven Checkstyle @@ -36,7 +46,7 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/storefront-bff-checkstyle-result.xml' + path: "**/storefront-bff-checkstyle-result.xml" - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -48,36 +58,94 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 + + - name: Publish Test Results + uses: dorny/test-reporter@v1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('storefront-bff/**/target/surefire-reports/TEST-*.xml', 'storefront-bff/**/target/failsafe-reports/TEST-*.xml') != '' }} + with: + name: Storefront-BFF-Test-Results + path: "storefront-bff/**/*-reports/TEST*.xml" + reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: storefront-bff-junit-test-results + path: | + storefront-bff/**/target/surefire-reports/TEST-*.xml + storefront-bff/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('storefront-bff/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/storefront-bff/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Storefront BFF Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Storefront BFF Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: storefront-bff-jacoco-coverage-report + path: | + storefront-bff/target/site/jacoco/jacoco.xml + storefront-bff/target/site/jacoco-it/jacoco.xml + storefront-bff/target/site/jacoco/index.html + storefront-bff/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl storefront-bff -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./storefront-bff push: true - tags: ghcr.io/nashtech-garage/yas-storefront-bff:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-storefront-bff:latest diff --git a/.github/workflows/storefront-ci.yaml b/.github/workflows/storefront-ci.yaml index d5cd57eece..f8e58eeb09 100644 --- a/.github/workflows/storefront-ci.yaml +++ b/.github/workflows/storefront-ci.yaml @@ -2,13 +2,13 @@ name: storefront service ci on: push: - branches: [ "main" ] + branches: ["**"] paths: - "storefront/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/storefront-ci.yaml" pull_request: - branches: [ "main" ] + branches: ["**"] paths: - "storefront/**" - ".github/workflows/actions/action.yaml" @@ -16,44 +16,78 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run linting, prettier, security checks, SonarCloud analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: actions/setup-node@v4 + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 with: node-version: 20 - - run: npm ci + + - name: Install dependencies + run: npm ci working-directory: storefront - - run: npm run build + + - name: Build application + run: npm run build working-directory: storefront - - run: npm run lint + + - name: Run linting + run: npm run lint working-directory: storefront - - run: npx prettier --check . + + - name: Run Prettier check + run: npx prettier --check . working-directory: storefront + - name: SonarCloud Scan if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: SonarSource/sonarcloud-github-action@master with: projectBaseDir: storefront env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./storefront push: true - tags: ghcr.io/nashtech-garage/yas-storefront:latest + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-storefront:latest diff --git a/.github/workflows/tax-ci.yaml b/.github/workflows/tax-ci.yaml index f677cfd69a..c8cac1191a 100644 --- a/.github/workflows/tax-ci.yaml +++ b/.github/workflows/tax-ci.yaml @@ -2,14 +2,14 @@ name: tax service ci on: push: - branches: ["main"] + branches: ["**"] paths: - "tax/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/tax-ci.yaml" - "pom.xml" pull_request: - branches: ["main"] + branches: ["**"] paths: - "tax/**" - ".github/workflows/actions/action.yaml" @@ -18,16 +18,26 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl tax -am - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} @@ -36,14 +46,25 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/tax-checkstyle-result.xml' + path: "**/tax-checkstyle-result.xml" - name: Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('tax/**/target/surefire-reports/TEST-*.xml', 'tax/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Tax-Service-Unit-Test-Results path: "tax/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: tax-junit-test-results + path: | + tax/**/target/surefire-reports/TEST-*.xml + tax/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -55,36 +76,75 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('tax/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/tax/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Tax Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Tax Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: tax-jacoco-coverage-report + path: | + tax/target/site/jacoco/jacoco.xml + tax/target/site/jacoco-it/jacoco.xml + tax/target/site/jacoco/index.html + tax/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl tax -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./tax push: true - tags: ghcr.io/nashtech-garage/yas-tax:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-tax:latest diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml new file mode 100644 index 0000000000..3310f502e1 --- /dev/null +++ b/.github/workflows/test-coverage.yaml @@ -0,0 +1,132 @@ +name: Java Test & Coverage CI + +on: + push: + branches: ["**"] + paths: + - "common-library/**" + - "pom.xml" + - ".github/workflows/test-coverage.yaml" + pull_request: + branches: ["**"] + paths: + - "common-library/**" + - "pom.xml" + - ".github/workflows/test-coverage.yaml" + workflow_dispatch: + +jobs: + # ============================================================================ + # PHASE TEST — Chạy unit test + integration test, generate report, check coverage + # ============================================================================ + Test: + runs-on: ubuntu-latest + permissions: + contents: read + checks: write # Cần để publish test report lên GitHub UI + pull-requests: write # Cần để comment coverage lên PR + + env: + # Chỉ chạy các step tốn tài nguyên khi từ repo gốc (không phải fork) + FROM_ORIGINAL_REPOSITORY: >- + ${{ github.event.pull_request.head.repo.full_name == github.repository + || github.ref == 'refs/heads/main' }} + + steps: + # ------------------------------------------------------------------ + # 1. Checkout source code (fetch-depth=0 cần cho SonarCloud + JaCoCo) + # ------------------------------------------------------------------ + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + # ------------------------------------------------------------------ + # 2. Setup JDK 25 + cache Maven dependencies (dùng composite action có sẵn) + # ------------------------------------------------------------------ + - name: Setup JDK & Maven cache + uses: ./.github/workflows/actions + + # ------------------------------------------------------------------ + # 3. Chạy toàn bộ test (unit + integration) + JaCoCo coverage check + # - mvn verify: chạy surefire (unit) + failsafe (IT) + jacoco:check + # - jacoco:check sẽ FAIL build nếu coverage < 70% (đã cấu hình pom.xml) + # ------------------------------------------------------------------ + - name: Run Tests & Coverage Check + run: mvn verify --batch-mode --no-transfer-progress + + # ------------------------------------------------------------------ + # 4. Publish JUnit XML report lên GitHub Checks tab + # - Hiển thị từng test case PASS/FAIL trực tiếp trên GitHub UI + # - Chạy cả khi test fail (success() || failure()) + # ------------------------------------------------------------------ + - name: Publish Unit Test Report + uses: dorny/test-reporter@v1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + with: + name: Unit Test Results + # Surefire (unit test) viết report vào thư mục surefire-reports + path: "**/target/surefire-reports/TEST-*.xml" + reporter: java-junit + fail-on-error: false + + - name: Publish Integration Test Report + uses: dorny/test-reporter@v1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + with: + name: Integration Test Results + # Failsafe (integration test *IT.java) viết vào failsafe-reports + path: "**/target/failsafe-reports/TEST-*.xml" + reporter: java-junit + fail-on-error: false + + # ------------------------------------------------------------------ + # 5. Upload JUnit XML test results làm artifact (download & xem lại) + # - always() đảm bảo upload dù test PASS hay FAIL + # - retention-days: giữ artifact 14 ngày + # ------------------------------------------------------------------ + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: junit-test-results + path: | + **/target/surefire-reports/TEST-*.xml + **/target/failsafe-reports/TEST-*.xml + retention-days: 14 + + # ------------------------------------------------------------------ + # 6. Upload JaCoCo XML report làm artifact (dùng cho SonarCloud / download) + # ------------------------------------------------------------------ + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: jacoco-coverage-report + # jacoco/jacoco.xml = unit test coverage + # jacoco-it/jacoco.xml = integration test coverage + path: | + **/target/site/jacoco/jacoco.xml + **/target/site/jacoco-it/jacoco.xml + **/target/site/jacoco/index.html + **/target/site/jacoco-it/index.html + retention-days: 14 + + # ------------------------------------------------------------------ + # 6. Comment coverage summary lên Pull Request + # - madrapps/jacoco-report đọc jacoco.xml và post comment lên PR + # - min-coverage-overall: ngưỡng toàn project + # - min-coverage-changed-files: ngưỡng cho file thay đổi trong PR + # ------------------------------------------------------------------ + - name: Add Coverage Comment to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: "**/target/site/jacoco/jacoco.xml" + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "JaCoCo Coverage Report" + update-comment: true + pass-emoji: "✅" + fail-emoji: "❌" diff --git a/.github/workflows/webhook-ci.yaml b/.github/workflows/webhook-ci.yaml index b0b05bc755..67c3d4195c 100644 --- a/.github/workflows/webhook-ci.yaml +++ b/.github/workflows/webhook-ci.yaml @@ -2,14 +2,14 @@ name: webhook service ci on: push: - branches: ["main"] + branches: ["**"] paths: - "webhook/**" - ".github/workflows/actions/action.yaml" - ".github/workflows/webhook-ci.yaml" - "pom.xml" pull_request: - branches: ["main"] + branches: ["**"] paths: - "webhook/**" - ".github/workflows/actions/action.yaml" @@ -18,16 +18,26 @@ on: workflow_dispatch: jobs: - Build: + # ============================================================================ + # PHASE 1: TEST - Run unit tests, code quality checks, security analysis + # ============================================================================ + Test: runs-on: ubuntu-latest + permissions: + contents: read + checks: write env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - uses: ./.github/workflows/actions - - name: Run Maven Build Command + fetch-depth: 0 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Run Maven Tests and Build run: mvn clean install -pl webhook -am - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} @@ -36,14 +46,25 @@ jobs: if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: - path: '**/webhook-checkstyle-result.xml' + path: "**/webhook-checkstyle-result.xml" - name: Unit Test Results uses: dorny/test-reporter@v1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) && hashFiles('webhook/**/target/surefire-reports/TEST-*.xml', 'webhook/**/target/failsafe-reports/TEST-*.xml') != '' }} with: name: Webhook-Service-Unit-Test-Results path: "webhook/**/*-reports/TEST*.xml" reporter: java-junit + + - name: Upload JUnit Test Results + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: webhook-junit-test-results + path: | + webhook/**/target/surefire-reports/TEST-*.xml + webhook/**/target/failsafe-reports/TEST-*.xml + if-no-files-found: warn + retention-days: 14 - name: Analyze with sonar cloud if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} env: @@ -55,36 +76,75 @@ jobs: env: JAVA_HOME: /opt/jdk with: - project: 'yas' - path: '.' - format: 'HTML' + project: "yas" + path: "." + format: "HTML" + args: --disableCentral - name: Upload OWASP Dependency Check results if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + uses: actions/upload-artifact@v4 with: name: OWASP Dependency Check Report path: ${{github.workspace}}/reports + if-no-files-found: warn + retention-days: 14 - name: Add coverage report to PR uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' && hashFiles('webhook/target/site/jacoco/jacoco.xml') != '' }} with: paths: ${{github.workspace}}/webhook/target/site/jacoco/jacoco.xml token: ${{secrets.GITHUB_TOKEN}} - min-coverage-overall: 80 - min-coverage-changed-files: 60 - title: 'Webhook Coverage Report' + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "Webhook Coverage Report" update-comment: true + + - name: Upload JaCoCo Coverage Report + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: webhook-jacoco-coverage-report + path: | + webhook/target/site/jacoco/jacoco.xml + webhook/target/site/jacoco-it/jacoco.xml + webhook/target/site/jacoco/index.html + webhook/target/site/jacoco-it/index.html + if-no-files-found: warn + retention-days: 14 + + # ============================================================================ + # PHASE 2: BUILD - Build Docker image and push to registry + # ============================================================================ + Build: + needs: Test + runs-on: ubuntu-latest + if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }} + permissions: + contents: read + packages: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup JDK environment + uses: ./.github/workflows/actions + + - name: Build application (generate /target) + run: mvn clean package -pl webhook -am -DskipTests + + - name: Set lowercase image owner + run: echo "IMAGE_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV + - name: Log in to the Container registry - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push Docker images - if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./webhook push: true - tags: ghcr.io/nashtech-garage/yas-webhook:latest \ No newline at end of file + tags: ghcr.io/${{ env.IMAGE_OWNER }}/yas-webhook:latest diff --git a/automation-ui/automation-base/pom.xml b/automation-ui/automation-base/pom.xml index 28a4a9a947..f17d98fbc3 100644 --- a/automation-ui/automation-base/pom.xml +++ b/automation-ui/automation-base/pom.xml @@ -12,10 +12,10 @@ jar - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-automation-ui-base + Ming1309_yas-automation-ui-base diff --git a/automation-ui/backoffice/pom.xml b/automation-ui/backoffice/pom.xml index bb90ba647b..8f61e4a4d6 100644 --- a/automation-ui/backoffice/pom.xml +++ b/automation-ui/backoffice/pom.xml @@ -13,9 +13,9 @@ backoffice - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-automation-ui-backoffice + Ming1309_yas-automation-ui-backoffice diff --git a/automation-ui/pom.xml b/automation-ui/pom.xml index 87d8ce2e35..9121147518 100644 --- a/automation-ui/pom.xml +++ b/automation-ui/pom.xml @@ -39,6 +39,8 @@ 7.14.0 1.18.34 + false + false @@ -145,6 +147,10 @@ org.owasp dependency-check-maven + + ${dependency-check.failOnError} + ${dependency-check.centralAnalyzerEnabled} + diff --git a/automation-ui/storefront/pom.xml b/automation-ui/storefront/pom.xml index 889bc58bd0..c1c30ec83c 100644 --- a/automation-ui/storefront/pom.xml +++ b/automation-ui/storefront/pom.xml @@ -13,9 +13,9 @@ storefront - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-automation-ui-storefront + Ming1309_yas-automation-ui-storefront diff --git a/backoffice-bff/pom.xml b/backoffice-bff/pom.xml index 0e3f17f643..dc498329c1 100644 --- a/backoffice-bff/pom.xml +++ b/backoffice-bff/pom.xml @@ -13,7 +13,7 @@ backoffice-bff Backend for backoffice - nashtech-garage_yas-backoffice-bff + Ming1309_yas-backoffice-bff diff --git a/backoffice/sonar-project.properties b/backoffice/sonar-project.properties index 975086d6ae..4516edb4de 100644 --- a/backoffice/sonar-project.properties +++ b/backoffice/sonar-project.properties @@ -1,5 +1,5 @@ -sonar.projectKey=nashtech-garage_yas-backoffice -sonar.organization=nashtech-garage +sonar.projectKey=Ming1309_yas-backoffice +sonar.organization=ming1309 # This is the name and version displayed in the SonarCloud UI. #sonar.projectName=backoffice diff --git a/cart/pom.xml b/cart/pom.xml index d9da458518..74ed389b82 100644 --- a/cart/pom.xml +++ b/cart/pom.xml @@ -14,9 +14,9 @@ YAS Cart service - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-cart + Ming1309_yas-cart diff --git a/common-library/pom.xml b/common-library/pom.xml index 2fc5e79655..771ce10fdb 100644 --- a/common-library/pom.xml +++ b/common-library/pom.xml @@ -16,9 +16,9 @@ YAS Common Library service - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-common-library + Ming1309_yas-common-library diff --git a/customer/pom.xml b/customer/pom.xml index 9fdae74848..472f266821 100644 --- a/customer/pom.xml +++ b/customer/pom.xml @@ -13,9 +13,9 @@ YAS Customer service - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-customer + Ming1309_yas-customer diff --git a/delivery/pom.xml b/delivery/pom.xml index 45f4720bc7..1a295db218 100644 --- a/delivery/pom.xml +++ b/delivery/pom.xml @@ -16,9 +16,9 @@ YAS Delivery service - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-delivery + Ming1309_yas-delivery diff --git a/inventory/pom.xml b/inventory/pom.xml index 85c98a29b2..101d481a4d 100644 --- a/inventory/pom.xml +++ b/inventory/pom.xml @@ -13,9 +13,9 @@ inventory YAS Inventory Service - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-inventory + Ming1309_yas-inventory diff --git a/location/pom.xml b/location/pom.xml index a444b4aa68..9f710d7322 100644 --- a/location/pom.xml +++ b/location/pom.xml @@ -13,9 +13,9 @@ location YAS Location Service - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-location + Ming1309_yas-location diff --git a/media/pom.xml b/media/pom.xml index ffebf38456..a4e4818ec9 100644 --- a/media/pom.xml +++ b/media/pom.xml @@ -13,9 +13,9 @@ media Yas Media service - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-media + Ming1309_yas-media diff --git a/order/pom.xml b/order/pom.xml index 726a7cbfaf..1f4eec8f16 100644 --- a/order/pom.xml +++ b/order/pom.xml @@ -12,9 +12,9 @@ order Order Service for yas project - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-order + Ming1309_yas-order diff --git a/payment-paypal/pom.xml b/payment-paypal/pom.xml index 5d971d7fc3..a9a5e302af 100644 --- a/payment-paypal/pom.xml +++ b/payment-paypal/pom.xml @@ -14,9 +14,9 @@ payment-paypal Payment with paypal service for yas project - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-payment-paypal + Ming1309_yas-payment-paypal diff --git a/payment/pom.xml b/payment/pom.xml index 46ad0f1b96..4564488d15 100644 --- a/payment/pom.xml +++ b/payment/pom.xml @@ -12,9 +12,9 @@ payment Payment Service for Yas Project - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-payment + Ming1309_yas-payment diff --git a/pom.xml b/pom.xml index f572ae554f..9c3062a0dd 100644 --- a/pom.xml +++ b/pom.xml @@ -37,6 +37,38 @@ delivery + + + spring-releases + Spring Releases + https://repo.spring.io/release + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + + spring-releases + Spring Releases + https://repo.spring.io/release + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + UTF-8 25 @@ -45,9 +77,9 @@ 1.0-SNAPSHOT 1.0-SNAPSHOT - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-yas-parent + Ming1309_yas-yas-parent 1.6.3 1.18.42 0.2.0 @@ -69,6 +101,8 @@ 5.9 2.0.12 0.8.14 + false + false @@ -300,6 +334,10 @@ org.owasp dependency-check-maven + + ${dependency-check.failOnError} + ${dependency-check.centralAnalyzerEnabled} + @@ -368,6 +406,31 @@ + + org.codehaus.mojo + flatten-maven-plugin + 1.5.0 + + true + resolveCiFriendliesOnly + + + + flatten + process-resources + + flatten + + + + flatten.clean + clean + + clean + + + + org.codehaus.mojo build-helper-maven-plugin @@ -418,6 +481,85 @@ + + org.jacoco + jacoco-maven-plugin + + + + prepare-agent + + prepare-agent + + + + + report + test + + report + + + + HTML + XML + + ${project.build.directory}/site/jacoco + + + + + prepare-agent-integration + + prepare-agent-integration + + + + + report-integration + verify + + report-integration + + + + HTML + XML + + ${project.build.directory}/site/jacoco-it + + + + + check + verify + + check + + + + + BUNDLE + + + + LINE + COVEREDRATIO + 0.70 + + + + BRANCH + COVEREDRATIO + 0.70 + + + + + + + + \ No newline at end of file diff --git a/product/pom.xml b/product/pom.xml index 38b5d9503d..b0d5485a61 100644 --- a/product/pom.xml +++ b/product/pom.xml @@ -14,9 +14,9 @@ YAS Product service - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-product + Ming1309_yas-product diff --git a/promotion/pom.xml b/promotion/pom.xml index e41dd4f550..8a6c3b0bee 100644 --- a/promotion/pom.xml +++ b/promotion/pom.xml @@ -13,9 +13,9 @@ promotion YAS Promotion Service - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-promotion + Ming1309_yas-promotion diff --git a/rating/pom.xml b/rating/pom.xml index 38851fab2c..e8ac6e9e85 100644 --- a/rating/pom.xml +++ b/rating/pom.xml @@ -12,9 +12,9 @@ rating YAS Rating service - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-rating + Ming1309_yas-rating diff --git a/recommendation/pom.xml b/recommendation/pom.xml index e2e1dc6165..c3fad8f1ea 100644 --- a/recommendation/pom.xml +++ b/recommendation/pom.xml @@ -17,6 +17,7 @@ UTF-8 + Ming1309_yas-recommendation 1.0.0-M2 1.12.0 diff --git a/sampledata/pom.xml b/sampledata/pom.xml index d31d5535ca..ac2a5da679 100644 --- a/sampledata/pom.xml +++ b/sampledata/pom.xml @@ -14,9 +14,9 @@ YAS sampledata service - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-sampledata + Ming1309_yas-sampledata diff --git a/search/pom.xml b/search/pom.xml index 4a4c968c7f..9c56b5d5d3 100644 --- a/search/pom.xml +++ b/search/pom.xml @@ -13,9 +13,9 @@ search Demo project for Spring Boot - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-search + Ming1309_yas-search diff --git a/search/src/test/java/com/yas/search/constant/ConstantsTest.java b/search/src/test/java/com/yas/search/constant/ConstantsTest.java new file mode 100644 index 0000000000..5c830ecd78 --- /dev/null +++ b/search/src/test/java/com/yas/search/constant/ConstantsTest.java @@ -0,0 +1,34 @@ +package com.yas.search.constant; + +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ConstantsTest { + + @Test + void testProductFieldConstructor() throws Exception { + Constructor constructor = ProductField.class.getDeclaredConstructor(); + assertTrue(constructor.trySetAccessible()); + InvocationTargetException exception = assertThrows(InvocationTargetException.class, constructor::newInstance); + assertTrue(exception.getCause() instanceof UnsupportedOperationException); + } + + @Test + void testMessageCodeConstructor() throws Exception { + Constructor constructor = MessageCode.class.getDeclaredConstructor(); + assertTrue(constructor.trySetAccessible()); + constructor.newInstance(); + } + + @Test + void testActionConstructor() throws Exception { + Constructor constructor = Action.class.getDeclaredConstructor(); + assertTrue(constructor.trySetAccessible()); + constructor.newInstance(); + } +} diff --git a/search/src/test/java/com/yas/search/consumer/ProductSyncDataConsumerTest.java b/search/src/test/java/com/yas/search/consumer/ProductSyncDataConsumerTest.java index 0cd241383f..cbee4d83f8 100644 --- a/search/src/test/java/com/yas/search/consumer/ProductSyncDataConsumerTest.java +++ b/search/src/test/java/com/yas/search/consumer/ProductSyncDataConsumerTest.java @@ -63,7 +63,6 @@ void testSync_whenUpdateAction_updateProduct() { verify(productSyncDataService, times(1)).updateProduct(productId); } - @Disabled("Handle later once elasticsearch sync delete complete") @Test void testSync_whenDeleteAction_deleteProduct() { // When @@ -79,4 +78,33 @@ void testSync_whenDeleteAction_deleteProduct() { // Then verify(productSyncDataService, times(1)).deleteProduct(productId); } + + @Test + void testSync_whenReadAction_createProduct() { + // When + long productId = 4L; + productSyncDataConsumer.sync( + ProductMsgKey.builder().id(productId).build(), + ProductCdcMessage.builder() + .after(Product.builder().id(productId).build()) + .op(com.yas.commonlibrary.kafka.cdc.message.Operation.READ) + .build() + ); + + // Then + verify(productSyncDataService, times(1)).createProduct(productId); + } + + @Test + void testSync_whenMessageIsNull_deleteProduct() { + // When + long productId = 5L; + productSyncDataConsumer.sync( + ProductMsgKey.builder().id(productId).build(), + null + ); + + // Then + verify(productSyncDataService, times(1)).deleteProduct(productId); + } } diff --git a/search/src/test/java/com/yas/search/kafka/config/consumer/AppKafkaListenerConfigurerTest.java b/search/src/test/java/com/yas/search/kafka/config/consumer/AppKafkaListenerConfigurerTest.java new file mode 100644 index 0000000000..4441e934fe --- /dev/null +++ b/search/src/test/java/com/yas/search/kafka/config/consumer/AppKafkaListenerConfigurerTest.java @@ -0,0 +1,22 @@ +package com.yas.search.kafka.config.consumer; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.junit.jupiter.api.Test; +import org.springframework.kafka.config.KafkaListenerEndpointRegistrar; +import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; + +class AppKafkaListenerConfigurerTest { + + @Test + void configureKafkaListeners_SetsValidator() { + LocalValidatorFactoryBean validator = mock(LocalValidatorFactoryBean.class); + AppKafkaListenerConfigurer configurer = new AppKafkaListenerConfigurer(validator); + KafkaListenerEndpointRegistrar registrar = mock(KafkaListenerEndpointRegistrar.class); + + configurer.configureKafkaListeners(registrar); + + verify(registrar).setValidator(validator); + } +} diff --git a/search/src/test/java/com/yas/search/service/ProductServiceTest.java b/search/src/test/java/com/yas/search/service/ProductServiceTest.java index 30b1ffc945..5f7211eb2d 100644 --- a/search/src/test/java/com/yas/search/service/ProductServiceTest.java +++ b/search/src/test/java/com/yas/search/service/ProductServiceTest.java @@ -143,6 +143,34 @@ void testFindProductAdvance_whenSortTypeIsDefault_ReturnProductListGetVm() { assertEquals("createdOn: DESC", Objects.requireNonNull(captor.getValue().getSort()).toString()); } + @Test + void testFindProductAdvance_whenCriteriaAreNull_ReturnProductListGetVm() { + + SearchHits searchHits = + getSearchHits(); + + SearchPage productPage = mock(SearchPage.class); + when(productPage.getNumber()).thenReturn(0); + when(productPage.getSize()).thenReturn(10); + when(productPage.getTotalElements()).thenReturn(1L); + when(productPage.getTotalPages()).thenReturn(1); + when(productPage.isLast()).thenReturn(true); + + ArgumentCaptor captor = ArgumentCaptor.forClass(NativeQuery.class); + + when(elasticsearchOperations.search(any(NativeQuery.class), eq(Product.class))).thenReturn(searchHits); + + ProductCriteriaDto criteriaDto = new ProductCriteriaDto( + "test", 0, 10, null, "", + null, null, null, SortType.DEFAULT); + productService.findProductAdvance(criteriaDto); + + verify(elasticsearchOperations, times(1)) + .search(captor.capture(), eq(Product.class)); + + assertEquals("createdOn: DESC", Objects.requireNonNull(captor.getValue().getSort()).toString()); + } + @Test void testAutoCompleteProductName_whenExistsProducts_returnProductNameListVm() { diff --git a/search/src/test/java/com/yas/search/service/ProductSyncDataServiceTest.java b/search/src/test/java/com/yas/search/service/ProductSyncDataServiceTest.java index d9f9f14de6..71d130df52 100644 --- a/search/src/test/java/com/yas/search/service/ProductSyncDataServiceTest.java +++ b/search/src/test/java/com/yas/search/service/ProductSyncDataServiceTest.java @@ -219,16 +219,13 @@ void testDeleteProduct_whenProductExists_deletesProduct() { verify(productRepository).deleteById(id); } - @Disabled @Test - void testDeleteProduct_whenProductDoesNotExist_throwsNotFoundException() { + void testDeleteProduct_whenProductDoesNotExist_logsWarning() { Long id = 1L; when(productRepository.existsById(id)).thenReturn(false); - assertThatThrownBy(() -> productSyncDataService.deleteProduct(id)) - .isInstanceOf(NotFoundException.class) - .hasMessageContaining("The product 1 is not found"); + productSyncDataService.deleteProduct(id); verify(productRepository, never()).deleteById(id); } diff --git a/search/src/test/java/com/yas/search/viewmodel/error/ErrorVmTest.java b/search/src/test/java/com/yas/search/viewmodel/error/ErrorVmTest.java new file mode 100644 index 0000000000..2eb456d4cf --- /dev/null +++ b/search/src/test/java/com/yas/search/viewmodel/error/ErrorVmTest.java @@ -0,0 +1,18 @@ +package com.yas.search.viewmodel.error; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ErrorVmTest { + + @Test + void testErrorVm_ConstructorWithThreeParams() { + ErrorVm errorVm = new ErrorVm("400", "Bad Request", "Detail error"); + assertEquals("400", errorVm.statusCode()); + assertEquals("Bad Request", errorVm.title()); + assertEquals("Detail error", errorVm.detail()); + assertTrue(errorVm.fieldErrors().isEmpty()); + } +} diff --git a/storefront-bff/pom.xml b/storefront-bff/pom.xml index 73c328d456..5b8b636d4f 100644 --- a/storefront-bff/pom.xml +++ b/storefront-bff/pom.xml @@ -13,9 +13,9 @@ storefront-bff Back end for Storefront - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-storefront-bff + Ming1309_yas-storefront-bff diff --git a/storefront/sonar-project.properties b/storefront/sonar-project.properties index 65ed6b21f9..78181a5d4b 100644 --- a/storefront/sonar-project.properties +++ b/storefront/sonar-project.properties @@ -1,5 +1,5 @@ -sonar.projectKey=nashtech-garage_yas-storefront -sonar.organization=nashtech-garage +sonar.projectKey=Ming1309_yas-storefront +sonar.organization=ming1309 # This is the name and version displayed in the SonarCloud UI. #sonar.projectName=storefront diff --git a/tax/pom.xml b/tax/pom.xml index 9cf390a73f..28197aba16 100644 --- a/tax/pom.xml +++ b/tax/pom.xml @@ -13,9 +13,9 @@ tax YAS Tax Service - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-tax + Ming1309_yas-tax diff --git a/webhook/pom.xml b/webhook/pom.xml index fad67048d8..e40dcc5fd0 100644 --- a/webhook/pom.xml +++ b/webhook/pom.xml @@ -13,9 +13,9 @@ webhook YAS Webhook service - nashtech-garage + ming1309 https://sonarcloud.io - nashtech-garage_yas-webhook + Ming1309_yas-webhook