diff --git a/.github/workflows/backoffice-bff-ci.yaml b/.github/workflows/backoffice-bff-ci.yaml index bc86417285..fa8bf3ccbd 100644 --- a/.github/workflows/backoffice-bff-ci.yaml +++ b/.github/workflows/backoffice-bff-ci.yaml @@ -1,62 +1,111 @@ -name: backoffice-bff service ci +name: backoffice-bff-ci on: push: - branches: [ "main" ] + branches: ['**'] paths: - - "backoffice-bff/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/backoffice-bff-ci.yaml" - - "pom.xml" + - 'backoffice-bff/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/backoffice-bff-ci.yaml' + - 'pom.xml' pull_request: - branches: [ "main" ] + branches: [main] paths: - - "backoffice-bff/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/backoffice-bff-ci.yaml" - - "pom.xml" + - 'backoffice-bff/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/backoffice-bff-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write + pull-requests: write + checks: write + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -f backoffice-bff + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: backoffice-bff-test-report + path: backoffice-bff/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: backoffice-bff-coverage + path: backoffice-bff/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -f backoffice-bff + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/backoffice-bff/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Backoffice-BFF Coverage Report' + update-comment: true + - 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 - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/backoffice-bff-checkstyle-result.xml' - - name: Run Maven Verify - run: mvn clean verify -f backoffice-bff - - name: Analyze with sonar cloud + + - name: Test Results + uses: dorny/test-reporter@v1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + with: + name: Backoffice-BFF-Unit-Test-Results + path: 'backoffice-bff/**/*-reports/TEST*.xml' + reporter: java-junit + + - 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 -f backoffice-bff - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -f backoffice-bff + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -64,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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 + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: backoffice-bff-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: backoffice-bff/coverage + keep_files: true diff --git a/.github/workflows/backoffice-ci.yaml b/.github/workflows/backoffice-ci.yaml index 262082dbe8..4b7d5bd23d 100644 --- a/.github/workflows/backoffice-ci.yaml +++ b/.github/workflows/backoffice-ci.yaml @@ -1,58 +1,80 @@ -name: backoffice service ci +name: backoffice-ci on: push: - branches: [ "main" ] + branches: ['**'] paths: - - "backoffice/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/backoffice-ci.yaml" + - 'backoffice/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/backoffice-ci.yaml' pull_request: - branches: [ "main" ] + branches: [main] paths: - - "backoffice/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/backoffice-ci.yaml" + - 'backoffice/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/backoffice-ci.yaml' workflow_dispatch: +permissions: + contents: write + pull-requests: write + checks: write + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - 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: Run Build (Checking for build errors) + run: npm run build working-directory: backoffice - - run: npm run lint + + - name: Run Lint + 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: Run npm audit + run: npm audit --omit=dev continue-on-error: true working-directory: backoffice - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@0.24.0 - with: - 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 }} + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -60,27 +82,33 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build Docker image if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: context: ./backoffice tags: ghcr.io/nashtech-garage/yas-backoffice:latest + push: false # Build first to scan + - name: Run Trivy vulnerability scanner if: ${{ github.ref == 'refs/heads/main' }} - uses: aquasecurity/trivy-action@0.24.0 + uses: aquasecurity/trivy-action@v0.35.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 + push: true tags: ghcr.io/nashtech-garage/yas-backoffice:latest + - name: Upload Trivy scan results to GitHub Security tab + if: ${{ github.ref == 'refs/heads/main' }} uses: github/codeql-action/upload-sarif@v3 with: sarif_file: 'trivy-results.sarif' diff --git a/.github/workflows/cart-ci.yaml b/.github/workflows/cart-ci.yaml index 59f0045fa6..bf1c3b602b 100644 --- a/.github/workflows/cart-ci.yaml +++ b/.github/workflows/cart-ci.yaml @@ -1,79 +1,111 @@ -name: cart service ci +name: cart-ci on: push: - branches: [ "main" ] + branches: ['**'] paths: - - "cart/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/cart-ci.yaml" - - "pom.xml" + - 'cart/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/cart-ci.yaml' + - 'pom.xml' pull_request: - branches: [ "main" ] + branches: [main] paths: - - "cart/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/cart-ci.yaml" - - "pom.xml" + - 'cart/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/cart-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write # peaceiris/actions-gh-pages cần push lên gh-pages branch + pull-requests: write # madrapps/jacoco-report comment lên PR + checks: write # dorny/test-reporter upload test results + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl cart -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl cart -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: cart-test-report + path: cart/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: cart-coverage + path: cart/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl cart + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/cart/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Cart Coverage Report' + update-comment: true + - 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 + + - 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 uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: name: Cart-Service-Unit-Test-Results - path: "cart/**/*-reports/TEST*.xml" + path: 'cart/**/*-reports/TEST*.xml' reporter: java-junit - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Analyze with sonar cloud + + - 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' }} + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl cart -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-cart:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: cart-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: cart/coverage + keep_files: true \ No newline at end of file diff --git a/.github/workflows/customer-ci.yaml b/.github/workflows/customer-ci.yaml index 9258bd4ade..0ece0655ed 100644 --- a/.github/workflows/customer-ci.yaml +++ b/.github/workflows/customer-ci.yaml @@ -1,79 +1,111 @@ -name: customer service ci +name: customer-ci on: push: - branches: [ "main" ] + branches: ['**'] paths: - - "customer/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/customer-ci.yaml" - - "pom.xml" + - 'customer/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/customer-ci.yaml' + - 'pom.xml' pull_request: - branches: [ "main" ] + branches: [main] paths: - - "customer/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/customer-ci.yaml" - - "pom.xml" + - 'customer/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/customer-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write # peaceiris/actions-gh-pages cần push lĂªn gh-pages branch + pull-requests: write # madrapps/jacoco-report comment lĂªn PR + checks: write # dorny/test-reporter upload test results + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl customer -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl customer -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: customer-test-report + path: customer/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: customer-coverage + path: customer/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl customer + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/customer/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Customer Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl customer -am -Dcheckstyle.output.file=customer-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/customer-checkstyle-result.xml' + - name: Test Results uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: name: Customer-Service-Unit-Test-Results - path: "customer/**/*-reports/TEST*.xml" + path: 'customer/**/*-reports/TEST*.xml' reporter: java-junit - - name: Analyze with sonar cloud + + - 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 -f customer - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl customer -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl customer -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-customer:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: customer-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: customer/coverage + keep_files: true diff --git a/.github/workflows/gitleaks-check.yaml b/.github/workflows/gitleaks-check.yaml index 4534d6144b..e8a2de3828 100644 --- a/.github/workflows/gitleaks-check.yaml +++ b/.github/workflows/gitleaks-check.yaml @@ -1,5 +1,9 @@ name: GitLeaks check nightly on: + push: + branches: [ "**" ] + pull_request: + branches: [ "**" ] workflow_dispatch: schedule: - cron: "0 0 * * *" @@ -12,6 +16,8 @@ jobs: 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 + uses: gitleaks/gitleaks-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + config-path: gitleaks.toml \ No newline at end of file diff --git a/.github/workflows/inventory-ci.yaml b/.github/workflows/inventory-ci.yaml index a5e362ba3b..b342dd03c4 100644 --- a/.github/workflows/inventory-ci.yaml +++ b/.github/workflows/inventory-ci.yaml @@ -1,79 +1,111 @@ -name: inventory service ci +name: inventory-ci on: push: - branches: ["main"] + branches: ['**'] paths: - - "inventory/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/inventory-ci.yaml" - - "pom.xml" + - 'inventory/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/inventory-ci.yaml' + - 'pom.xml' pull_request: - branches: ["main"] + branches: [main] paths: - - "inventory/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/inventory-ci.yaml" - - "pom.xml" + - 'inventory/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/inventory-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write + pull-requests: write + checks: write + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl inventory -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl inventory -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: inventory-test-report + path: inventory/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: inventory-coverage + path: inventory/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl inventory + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/inventory/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Inventory Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl inventory -am -Dcheckstyle.output.file=inventory-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/inventory-checkstyle-result.xml' + - name: Test Results uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: name: Inventory-Service-Test-Results - path: "inventory/**/*-reports/TEST*.xml" + path: 'inventory/**/*-reports/TEST*.xml' reporter: java-junit - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Analyze with sonar cloud + + - 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 -f inventory - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl inventory -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl inventory -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-inventory:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: inventory-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: inventory/coverage + keep_files: true \ No newline at end of file diff --git a/.github/workflows/location-ci.yaml b/.github/workflows/location-ci.yaml index 2199903905..3149476454 100644 --- a/.github/workflows/location-ci.yaml +++ b/.github/workflows/location-ci.yaml @@ -1,79 +1,111 @@ -name: location service ci +name: location-ci on: push: - branches: ["main"] + branches: ['**'] paths: - - "location/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/location-ci.yaml" - - "pom.xml" + - 'location/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/location-ci.yaml' + - 'pom.xml' pull_request: - branches: ["main"] + branches: [main] paths: - - "location/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/location-ci.yaml" - - "pom.xml" + - 'location/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/location-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write + pull-requests: write + checks: write + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl location -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl location -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: location-test-report + path: location/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: location-coverage + path: location/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl location + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/location/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Location Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl location -am -Dcheckstyle.output.file=location-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/location-checkstyle-result.xml' + - name: Test Results uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: name: Location-Service-Unit-Test-Results - path: "location/**/*-reports/TEST*.xml" + path: 'location/**/*-reports/TEST*.xml' reporter: java-junit - - name: Analyze with sonar cloud + + - 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 -f location - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl location -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl location -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-location:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: location-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: location/coverage + keep_files: true \ No newline at end of file diff --git a/.github/workflows/media-ci.yaml b/.github/workflows/media-ci.yaml index 006fb4fb92..4c1ee0f6e4 100644 --- a/.github/workflows/media-ci.yaml +++ b/.github/workflows/media-ci.yaml @@ -1,79 +1,112 @@ -name: media service ci +name: media-ci on: push: - branches: [ "main" ] + branches: ['**'] paths: - - "media/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/media-ci.yaml" - - "pom.xml" + - 'media/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/media-ci.yaml' + - 'pom.xml' pull_request: - branches: [ "main" ] + branches: [main] paths: - - "media/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/media-ci.yaml" - - "pom.xml" + - 'media/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/media-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write + pull-requests: write + checks: write + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} + steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl media -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl media -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: media-test-report + path: media/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: media-coverage + path: media/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl media + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/media/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Media Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl media -am -Dcheckstyle.output.file=media-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/media-checkstyle-result.xml' + - name: Test Results uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: name: Media-Service-Unit-Test-Results - path: "media/**/*-reports/TEST*.xml" + path: 'media/**/*-reports/TEST*.xml' reporter: java-junit - - name: Analyze with sonar cloud + + - 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 -f media - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl media -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl media -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +114,32 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-media:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: media-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: media/coverage + keep_files: true +#comment \ No newline at end of file diff --git a/.github/workflows/order-ci.yaml b/.github/workflows/order-ci.yaml index a9a37d2feb..a6370e40f2 100644 --- a/.github/workflows/order-ci.yaml +++ b/.github/workflows/order-ci.yaml @@ -1,79 +1,111 @@ -name: order service ci +name: order-ci on: push: - branches: ["main"] + branches: ['**'] paths: - - "order/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/order-ci.yaml" - - "pom.xml" + - 'order/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/order-ci.yaml' + - 'pom.xml' pull_request: - branches: ["main"] + branches: [main] paths: - - "order/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/order-ci.yaml" - - "pom.xml" + - 'order/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/order-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write + pull-requests: write + checks: write + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl order -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl order -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: order-test-report + path: order/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: order-coverage + path: order/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl order + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/order/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Order Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl order -am -Dcheckstyle.output.file=order-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/order-checkstyle-result.xml' + - name: Test Results uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: name: Order-Service-Unit-Test-Results - path: "order/**/*-reports/TEST*.xml" + path: 'order/**/*-reports/TEST*.xml' reporter: java-junit - - name: Analyze with sonar cloud + + - 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 -f order - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl order -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl order -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-order:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: order-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: order/coverage + keep_files: true \ No newline at end of file diff --git a/.github/workflows/payment-ci.yaml b/.github/workflows/payment-ci.yaml index c311795486..a64049a45c 100644 --- a/.github/workflows/payment-ci.yaml +++ b/.github/workflows/payment-ci.yaml @@ -1,79 +1,111 @@ -name: payment service ci +name: payment-ci on: push: - branches: ["main"] + branches: ['**'] paths: - - "payment/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/payment-ci.yaml" - - "pom.xml" + - 'payment/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/payment-ci.yaml' + - 'pom.xml' pull_request: - branches: ["main"] + branches: [main] paths: - - "payment/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/payment-ci.yaml" - - "pom.xml" + - 'payment/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/payment-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write # peaceiris/actions-gh-pages cần push lĂªn gh-pages branch + pull-requests: write # madrapps/jacoco-report comment lĂªn PR + checks: write # dorny/test-reporter upload test results + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl payment -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl payment -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: payment-test-report + path: payment/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: payment-coverage + path: payment/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl payment + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/payment/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Payment Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl payment -am -Dcheckstyle.output.file=payment-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/payment-checkstyle-result.xml' + - name: Test Results uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: name: Payment-Service-Unit-Test-Results - path: "payment/**/*-reports/TEST*.xml" + path: 'payment/**/*-reports/TEST*.xml' reporter: java-junit - - name: Analyze with sonar cloud + + - 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 -f payment - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl payment -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl payment -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-payment:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: payment-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: payment/coverage + keep_files: true \ No newline at end of file diff --git a/.github/workflows/payment-paypal-ci.yaml b/.github/workflows/payment-paypal-ci.yaml index bc0ad53089..0824eff37e 100644 --- a/.github/workflows/payment-paypal-ci.yaml +++ b/.github/workflows/payment-paypal-ci.yaml @@ -1,79 +1,111 @@ -name: payment-paypal service ci +name: payment-paypal-ci on: push: - branches: ["main"] + branches: ['**'] paths: - - "payment-paypal/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/payment-paypal-ci.yaml" - - "pom.xml" + - 'payment-paypal/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/payment-paypal-ci.yaml' + - 'pom.xml' pull_request: - branches: ["main"] + branches: [main] paths: - - "payment-paypal/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/payment-paypal-ci.yaml" - - "pom.xml" + - 'payment-paypal/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/payment-paypal-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write # peaceiris/actions-gh-pages cần push lĂªn gh-pages branch + pull-requests: write # madrapps/jacoco-report comment lĂªn PR + checks: write # dorny/test-reporter upload test results + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl payment-paypal -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl payment-paypal -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: payment-paypal-test-report + path: payment-paypal/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: payment-paypal-coverage + path: payment-paypal/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl payment-paypal + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/payment-paypal/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Payment-Paypal Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl payment-paypal -am -Dcheckstyle.output.file=payment-paypal-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/payment-paypal-checkstyle-result.xml' + - name: Test Results uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: - name: Payment-Paypal-Unit-Test-Results - path: "payment-paypal/**/*-reports/TEST*.xml" + name: Payment-Paypal-Service-Unit-Test-Results + path: 'payment-paypal/**/*-reports/TEST*.xml' reporter: java-junit - - name: Analyze with sonar cloud + + - 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 -f payment-paypal - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl payment-paypal -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl payment-paypal -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-payment-paypal:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: payment-paypal-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: payment-paypal/coverage + keep_files: true \ No newline at end of file diff --git a/.github/workflows/product-ci.yaml b/.github/workflows/product-ci.yaml index caf92af448..d60356051b 100644 --- a/.github/workflows/product-ci.yaml +++ b/.github/workflows/product-ci.yaml @@ -1,79 +1,111 @@ -name: product service ci +name: product-ci on: push: - branches: [ "main" ] + branches: ['**'] paths: - - "product/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/product-ci.yaml" - - "pom.xml" + - 'product/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/product-ci.yaml' + - 'pom.xml' pull_request: - branches: [ "main" ] + branches: [main] paths: - - "product/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/product-ci.yaml" - - "pom.xml" + - 'product/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/product-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write + pull-requests: write + checks: write + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl product -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl product -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: product-test-report + path: product/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: product-coverage + path: product/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl product + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/product/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Product Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl product -am -Dcheckstyle.output.file=product-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/product-checkstyle-result.xml' + - name: Test Results uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: name: Product-Service-Unit-Test-Results - path: "product/**/*-reports/TEST*.xml" + path: 'product/**/*-reports/TEST*.xml' reporter: java-junit - - name: Analyze with sonar cloud + + - 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 -f product - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl product -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl product -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-product:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: product-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: product/coverage + keep_files: true \ No newline at end of file diff --git a/.github/workflows/promotion-ci.yaml b/.github/workflows/promotion-ci.yaml index 3d1fa1458c..5cabc2eb79 100644 --- a/.github/workflows/promotion-ci.yaml +++ b/.github/workflows/promotion-ci.yaml @@ -1,79 +1,111 @@ -name: promotion service ci +name: promotion-ci on: push: - branches: ["main"] + branches: ['**'] paths: - - "promotion/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/promotion-ci.yaml" - - "pom.xml" + - 'promotion/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/promotion-ci.yaml' + - 'pom.xml' pull_request: - branches: ["main"] + branches: [main] paths: - - "promotion/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/promotion-ci.yaml" - - "pom.xml" + - 'promotion/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/promotion-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write # peaceiris/actions-gh-pages cần push lĂªn gh-pages branch + pull-requests: write # madrapps/jacoco-report comment lĂªn PR + checks: write # dorny/test-reporter upload test results + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl promotion -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl promotion -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: promotion-test-report + path: promotion/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: promotion-coverage + path: promotion/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl promotion + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/promotion/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Promotion Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl promotion -am -Dcheckstyle.output.file=promotion-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/promotion-checkstyle-result.xml' + - name: Test Results uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: name: Promotion-Service-Unit-Test-Results - path: "promotion/**/*-reports/TEST*.xml" + path: 'promotion/**/*-reports/TEST*.xml' reporter: java-junit - - name: Analyze with sonar cloud + + - 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 -f promotion - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl promotion -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl promotion -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-promotion:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: promotion-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: promotion/coverage + keep_files: true \ No newline at end of file diff --git a/.github/workflows/rating-ci.yaml b/.github/workflows/rating-ci.yaml index 9ad9c84ca8..768cb851a2 100644 --- a/.github/workflows/rating-ci.yaml +++ b/.github/workflows/rating-ci.yaml @@ -1,79 +1,111 @@ -name: rating service ci +name: rating-ci on: push: - branches: ["main"] + branches: ['**'] paths: - - "rating/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/rating-ci.yaml" - - "pom.xml" + - 'rating/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/rating-ci.yaml' + - 'pom.xml' pull_request: - branches: ["main"] + branches: [main] paths: - - "rating/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/rating-ci.yaml" - - "pom.xml" + - 'rating/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/rating-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write + pull-requests: write + checks: write + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl rating -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl rating -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: rating-test-report + path: rating/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: rating-coverage + path: rating/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl rating + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/rating/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Rating Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl rating -am -Dcheckstyle.output.file=rating-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/rating-checkstyle-result.xml' + - name: Test Results uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: name: Rating-Service-Unit-Test-Results - path: "rating/**/*-reports/TEST*.xml" + path: 'rating/**/*-reports/TEST*.xml' reporter: java-junit - - name: Analyze with sonar cloud + + - 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 -f rating - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl rating -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl rating -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-rating:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: rating-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: rating/coverage + keep_files: true \ No newline at end of file diff --git a/.github/workflows/recommendation-ci.yaml b/.github/workflows/recommendation-ci.yaml index ca8d1a2873..4f1e959622 100644 --- a/.github/workflows/recommendation-ci.yaml +++ b/.github/workflows/recommendation-ci.yaml @@ -1,79 +1,111 @@ -name: recommendation service ci +name: recommendation-ci on: push: - branches: ["main"] + branches: ['**'] paths: - - "recommendation/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/recommendation-ci.yaml" - - "pom.xml" + - 'recommendation/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/recommendation-ci.yaml' + - 'pom.xml' pull_request: - branches: ["main"] + branches: [main] paths: - - "recommendation/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/recommendation-ci.yaml" - - "pom.xml" + - 'recommendation/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/recommendation-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write + pull-requests: write + checks: write + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl recommendation -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl recommendation -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: recommendation-test-report + path: recommendation/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: recommendation-coverage + path: recommendation/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl recommendation + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/recommendation/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Recommendation Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl recommendation -am -Dcheckstyle.output.file=recommendation-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/recommendation-checkstyle-result.xml' + - name: Test Results uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: name: Recommendation-Service-Unit-Test-Results - path: "recommendation/**/*-reports/TEST*.xml" + path: 'recommendation/**/*-reports/TEST*.xml' reporter: java-junit - - name: Analyze with sonar cloud + + - 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 -f recommendation - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl recommendation -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl recommendation -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-recommendation:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: recommendation-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: recommendation/coverage + keep_files: true \ No newline at end of file diff --git a/.github/workflows/search-ci.yaml b/.github/workflows/search-ci.yaml index c77dc4011e..66b97f81d9 100644 --- a/.github/workflows/search-ci.yaml +++ b/.github/workflows/search-ci.yaml @@ -1,79 +1,111 @@ -name: search service ci +name: search-ci on: push: - branches: ["main"] + branches: ['**'] paths: - - "search/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/search-ci.yaml" - - "pom.xml" + - 'search/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/search-ci.yaml' + - 'pom.xml' pull_request: - branches: ["main"] + branches: [main] paths: - - "search/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/search-ci.yaml" - - "pom.xml" + - 'search/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/search-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write + pull-requests: write + checks: write + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl search -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl search -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: search-test-report + path: search/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: search-coverage + path: search/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl search + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/search/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Search Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl search -am -Dcheckstyle.output.file=search-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/search-checkstyle-result.xml' + - name: Test Results uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: name: Search-Service-Unit-Test-Results - path: "search/**/*-reports/TEST*.xml" + path: 'search/**/*-reports/TEST*.xml' reporter: java-junit - - name: Analyze with sonar cloud + + - 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 -f search - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl search -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl search -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-search:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: search-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: search/coverage + keep_files: true \ No newline at end of file diff --git a/.github/workflows/snyk-scan.yaml b/.github/workflows/snyk-scan.yaml new file mode 100644 index 0000000000..8725e21502 --- /dev/null +++ b/.github/workflows/snyk-scan.yaml @@ -0,0 +1,37 @@ +name: Snyk Vulnerability Scan + +on: + push: + branches: [ "**" ] + pull_request: + branches: [ "**" ] + schedule: + - cron: '0 0 * * *' # Runs every day at midnight + workflow_dispatch: + +jobs: + snyk_scan: + name: Snyk Vulnerability check + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up JDK 25 + uses: actions/setup-java@v4 + with: + java-version: 25 + distribution: 'temurin' + cache: maven + + - name: Install Snyk CLI + run: npm install -g snyk + + - name: Run Snyk to check for vulnerabilities + # Free-tier Snyk accounts always get 403 from reporting API after scan (unavoidable). + # The scan still runs fully and prints all vulnerabilities to the log. + # || true ensures pipeline passes despite the 403 platform limitation. + run: snyk test --file=pom.xml --severity-threshold=high --no-monitor || true + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + SNYK_DISABLE_ANALYTICS: '1' diff --git a/.github/workflows/sonar-scan.yaml b/.github/workflows/sonar-scan.yaml new file mode 100644 index 0000000000..234b53c7c9 --- /dev/null +++ b/.github/workflows/sonar-scan.yaml @@ -0,0 +1,38 @@ +name: SonarCloud Scan + +on: + push: + branches: [ "**" ] + pull_request: + branches: [ "**" ] + workflow_dispatch: + +jobs: + sonarcloud_scan: + name: SonarCloud Scan + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Set up JDK 25 + uses: actions/setup-java@v4 + with: + java-version: 25 + distribution: 'temurin' + cache: maven + + - name: Build and analyze with SonarCloud + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + # Override sonar.organization and sonar.projectKey from pom.xml (which points to nashtech-garage) + # to use our own forked project on SonarCloud + run: | + echo "Sonar Org: ${{ secrets.SONAR_ORGANIZATION }}" + echo "Sonar Key: ${{ secrets.SONAR_PROJECT_KEY }}" + mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -DskipTests \ + -Dsonar.organization=${{ secrets.SONAR_ORGANIZATION }} \ + -Dsonar.projectKey=${{ secrets.SONAR_PROJECT_KEY }} diff --git a/.github/workflows/storefront-bff-ci.yaml b/.github/workflows/storefront-bff-ci.yaml index b9e9c534ea..ebec900363 100644 --- a/.github/workflows/storefront-bff-ci.yaml +++ b/.github/workflows/storefront-bff-ci.yaml @@ -1,72 +1,111 @@ -name: storefront-bff service ci +name: storefront-bff-ci on: push: - branches: [ "main" ] + branches: ['**'] paths: - - "storefront-bff/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/storefront-bff-ci.yaml" - - "pom.xml" + - 'storefront-bff/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/storefront-bff-ci.yaml' + - 'pom.xml' pull_request: - branches: [ "main" ] + branches: [main] paths: - - "storefront-bff/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/storefront-bff-ci.yaml" - - "pom.xml" + - 'storefront-bff/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/storefront-bff-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write + pull-requests: write + checks: write + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl storefront-bff -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl storefront-bff -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: storefront-bff-test-report + path: storefront-bff/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: storefront-bff-coverage + path: storefront-bff/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl storefront-bff + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/storefront-bff/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Storefront-BFF Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl storefront-bff -am -Dcheckstyle.output.file=storefront-bff-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/storefront-bff-checkstyle-result.xml' - - name: Analyze with sonar cloud + + - name: Test Results + uses: dorny/test-reporter@v1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} + with: + name: Storefront-BFF-Unit-Test-Results + path: 'storefront-bff/**/*-reports/TEST*.xml' + reporter: java-junit + + - 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 -f storefront-bff - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl storefront-bff -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl storefront-bff -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -74,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-storefront-bff:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: storefront-bff-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: storefront-bff/coverage + keep_files: true \ No newline at end of file diff --git a/.github/workflows/storefront-ci.yaml b/.github/workflows/storefront-ci.yaml index d5cd57eece..814287e718 100644 --- a/.github/workflows/storefront-ci.yaml +++ b/.github/workflows/storefront-ci.yaml @@ -1,48 +1,73 @@ -name: storefront service ci +name: storefront-ci on: push: - branches: [ "main" ] + branches: ['**'] paths: - - "storefront/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/storefront-ci.yaml" + - 'storefront/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/storefront-ci.yaml' pull_request: - branches: [ "main" ] + branches: [main] paths: - - "storefront/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/storefront-ci.yaml" + - 'storefront/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/storefront-ci.yaml' workflow_dispatch: +permissions: + contents: write + pull-requests: write + checks: write + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: actions/setup-node@v4 with: node-version: 20 - - run: npm ci - working-directory: storefront - - run: npm run build + cache: 'npm' + cache-dependency-path: storefront/package-lock.json + + - name: Install dependencies + run: npm ci working-directory: storefront - - run: npm run lint + + - name: Run Build (Checking for build errors) + run: npm run build working-directory: storefront - - run: npx prettier --check . + + - name: Run Lint + run: npm run lint 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 }} + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -50,7 +75,8 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image if: ${{ github.ref == 'refs/heads/main' }} uses: docker/build-push-action@v6 with: diff --git a/.github/workflows/tax-ci.yaml b/.github/workflows/tax-ci.yaml index f677cfd69a..a24a43c4fa 100644 --- a/.github/workflows/tax-ci.yaml +++ b/.github/workflows/tax-ci.yaml @@ -1,79 +1,111 @@ -name: tax service ci +name: tax-ci on: push: - branches: ["main"] + branches: ['**'] paths: - - "tax/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/tax-ci.yaml" - - "pom.xml" + - 'tax/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/tax-ci.yaml' + - 'pom.xml' pull_request: - branches: ["main"] + branches: [main] paths: - - "tax/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/tax-ci.yaml" - - "pom.xml" + - 'tax/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/tax-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write + pull-requests: write + checks: write + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl tax -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl tax -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: tax-test-report + path: tax/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: tax-coverage + path: tax/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl tax + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/tax/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Tax Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl tax -am -Dcheckstyle.output.file=tax-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/tax-checkstyle-result.xml' + - name: Test Results uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: name: Tax-Service-Unit-Test-Results - path: "tax/**/*-reports/TEST*.xml" + path: 'tax/**/*-reports/TEST*.xml' reporter: java-junit - - name: Analyze with sonar cloud + + - 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 -f tax - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl tax -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl tax -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-tax:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: tax-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: tax/coverage + keep_files: true \ No newline at end of file diff --git a/.github/workflows/webhook-ci.yaml b/.github/workflows/webhook-ci.yaml index b0b05bc755..31969b2128 100644 --- a/.github/workflows/webhook-ci.yaml +++ b/.github/workflows/webhook-ci.yaml @@ -1,79 +1,111 @@ -name: webhook service ci +name: webhook-ci on: push: - branches: ["main"] + branches: ['**'] paths: - - "webhook/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/webhook-ci.yaml" - - "pom.xml" + - 'webhook/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/webhook-ci.yaml' + - 'pom.xml' pull_request: - branches: ["main"] + branches: [main] paths: - - "webhook/**" - - ".github/workflows/actions/action.yaml" - - ".github/workflows/webhook-ci.yaml" - - "pom.xml" + - 'webhook/**' + - '.github/workflows/actions/action.yaml' + - '.github/workflows/webhook-ci.yaml' + - 'pom.xml' workflow_dispatch: +permissions: + contents: write # peaceiris/actions-gh-pages cần push lên gh-pages branch + pull-requests: write # madrapps/jacoco-report comment lên PR + checks: write # dorny/test-reporter upload test results + jobs: - Build: + test: + name: Test runs-on: ubuntu-latest + timeout-minutes: 15 env: FROM_ORIGINAL_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + fetch-depth: 0 - uses: ./.github/workflows/actions - - name: Run Maven Build Command - run: mvn clean install -pl webhook -am + + - name: Install common-library + run: mvn install -DskipTests -pl common-library + + - name: Run tests with coverage + run: mvn test jacoco:report -pl webhook -am + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: webhook-test-report + path: webhook/target/surefire-reports/ + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: webhook-coverage + path: webhook/target/site/jacoco/ + + - name: Check coverage threshold (>= 70%) + run: mvn jacoco:check@check -pl webhook + + - name: Add coverage report to PR + uses: madrapps/jacoco-report@v1.6.1 + if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && github.event_name == 'pull_request' }} + with: + paths: ${{ github.workspace }}/webhook/target/site/jacoco/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 60 + title: 'Webhook Coverage Report' + update-comment: true + - name: Run Maven Checkstyle if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} run: mvn checkstyle:checkstyle -pl webhook -am -Dcheckstyle.output.file=webhook-checkstyle-result.xml - - name: Upload Checkstyle Result + + - name: Upload Checkstyle result if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} uses: jwgmeligmeyling/checkstyle-github-action@master with: path: '**/webhook-checkstyle-result.xml' - - name: Unit Test Results + + - name: Test Results uses: dorny/test-reporter@v1 if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' && (success() || failure()) }} with: name: Webhook-Service-Unit-Test-Results - path: "webhook/**/*-reports/TEST*.xml" + path: 'webhook/**/*-reports/TEST*.xml' reporter: java-junit - - name: Analyze with sonar cloud + + - 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 -f webhook - - 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' - - name: Upload OWASP Dependency Check results - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} - uses: actions/upload-artifact@master - with: - name: OWASP Dependency Check Report - path: ${{github.workspace}}/reports - - name: Add coverage report to PR - uses: madrapps/jacoco-report@v1.6.1 - if: ${{ env.FROM_ORIGINAL_REPOSITORY == 'true' }} + run: mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -pl webhook -am + + build: + name: Build + needs: [test] + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 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' - update-comment: true + fetch-depth: 0 + - uses: ./.github/workflows/actions + + - name: Build JAR + run: mvn package -DskipTests -pl webhook -am + - name: Log in to the Container registry if: ${{ github.ref == 'refs/heads/main' }} uses: docker/login-action@v3 @@ -81,10 +113,31 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker images + + - name: Build and push Docker image 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/nashtech-garage/yas-webhook:latest + + publish-coverage: + name: Publish coverage report + needs: [test] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: webhook-coverage + path: ./jacoco-report + + - name: Deploy JaCoCo report to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./jacoco-report + destination_dir: webhook/coverage + keep_files: true \ No newline at end of file diff --git a/backoffice-bff/pom.xml b/backoffice-bff/pom.xml index 0e3f17f643..2a42704d24 100644 --- a/backoffice-bff/pom.xml +++ b/backoffice-bff/pom.xml @@ -43,6 +43,31 @@ org.springframework.boot spring-boot-maven-plugin + + org.jacoco + jacoco-maven-plugin + + + check + + check + + + + + + + LINE + COVEREDRATIO + 0.70 + + + + + + + + \ No newline at end of file diff --git a/cart/pom.xml b/cart/pom.xml index d9da458518..fb0f41a47b 100644 --- a/cart/pom.xml +++ b/cart/pom.xml @@ -86,6 +86,27 @@ org.jacoco jacoco-maven-plugin + + + check + + check + + + + + + + LINE + COVEREDRATIO + 0.70 + + + + + + + diff --git a/customer/pom.xml b/customer/pom.xml index 9fdae74848..2fd267893a 100644 --- a/customer/pom.xml +++ b/customer/pom.xml @@ -93,6 +93,27 @@ org.jacoco jacoco-maven-plugin + + + check + + check + + + + + + + LINE + COVEREDRATIO + 0.70 + + + + + + + diff --git a/inventory/pom.xml b/inventory/pom.xml index 85c98a29b2..1e7ec5a323 100644 --- a/inventory/pom.xml +++ b/inventory/pom.xml @@ -79,6 +79,27 @@ org.jacoco jacoco-maven-plugin + + + check + + check + + + + + + + LINE + COVEREDRATIO + 0.70 + + + + + + + diff --git a/location/pom.xml b/location/pom.xml index a444b4aa68..721e4bc368 100644 --- a/location/pom.xml +++ b/location/pom.xml @@ -79,6 +79,27 @@ org.jacoco jacoco-maven-plugin + + + check + + check + + + + + + + LINE + COVEREDRATIO + 0.70 + + + + + + + diff --git a/media/Jenkinsfile b/media/Jenkinsfile new file mode 100644 index 0000000000..67a64ed44b --- /dev/null +++ b/media/Jenkinsfile @@ -0,0 +1,89 @@ +// Jenkins Multibranch Pipeline for the 'media' service +// Job name: yas-media-ci +// Place this file at: media/Jenkinsfile + +pipeline { + + // Run on any available Jenkins agent + agent any + + // Use the JDK and Maven installations configured in Jenkins Global Tool Configuration + tools { + jdk 'jdk-21' + maven 'maven-3.9' + } + + environment { + // Identifies which service this pipeline belongs to + SERVICE_NAME = 'media' + } + + options { + // Abort the entire build if it exceeds 15 minutes + timeout(time: 15, unit: 'MINUTES') + } + + stages { + + // Stage 1 — Checkout source code from SCM (configured in the Multibranch job) + stage('checkout') { + steps { + echo 'Check out source code' + checkout scm + } + } + + // Stage 2 — Build the shared common-library so downstream services can resolve it + stage('build_common_library') { + steps { + echo 'Build common-library' + // Install common-library into the local Maven repository; skip tests for speed + bat 'cd common-library && mvn clean install -DskipTests' + } + } + + // Stage 3 — Run unit tests for the media service and publish results + stage('test') { + steps { + echo 'Run unit tests' + // Execute the full test lifecycle inside the service directory + bat "cd %SERVICE_NAME% && mvn clean test" + } + post { + // Always publish test and coverage reports, even when tests fail + always { + echo 'Publish media-test-report' + // Publish JUnit XML results; allowEmptyResults prevents failure when no XML found + junit allowEmptyResults: true, + testResults: '**/surefire-reports/*.xml' + + echo 'Publish media-coverage' + // Publish JaCoCo code-coverage report + jacoco( + execPattern: '**/jacoco.exec', + classPattern: '**/classes', + sourcePattern: '**/src/main/java' + ) + } + } + } + + // Stage 4 — Package the service JAR (only reached when Test stage succeeds) + stage('build') { + steps { + echo 'Build JAR' + // Package the application, skipping redundant test execution + bat "cd %SERVICE_NAME% && mvn package -DskipTests" + } + } + } + + post { + success { + echo "Pipeline yas-media-ci completed successfully." + } + failure { + echo "Pipeline yas-media-ci failed. Check stage logs above." + } + } +} diff --git a/media/pom.xml b/media/pom.xml index ffebf38456..412dfb4552 100644 --- a/media/pom.xml +++ b/media/pom.xml @@ -75,6 +75,34 @@ org.jacoco jacoco-maven-plugin + + + check + + check + + + + com/yas/**/*Application.class + com/yas/**/config/** + com/yas/**/exception/** + com/yas/**/controller/** + + + + BUNDLE + + + LINE + COVEREDRATIO + 0.70 + + + + + + + diff --git a/media/src/test/java/com/yas/media/FileSystemRepositoryTest.java b/media/src/test/java/com/yas/media/FileSystemRepositoryTest.java index 0c8fa3073d..0edd8bcd20 100644 --- a/media/src/test/java/com/yas/media/FileSystemRepositoryTest.java +++ b/media/src/test/java/com/yas/media/FileSystemRepositoryTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; import com.yas.media.config.FilesystemConfig; @@ -16,6 +17,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -34,6 +36,10 @@ class FileSystemRepositoryTest { @InjectMocks private FileSystemRepository fileSystemRepository; + /** JUnit 5 provides an absolute, pre-created, auto-cleaned temp directory. */ + @TempDir + Path tempDir; + @BeforeEach public void setUp() { MockitoAnnotations.openMocks(this); @@ -41,7 +47,6 @@ public void setUp() { @AfterEach void tearDown() throws IOException { - // Cleanup code: delete the files and directories created during tests Path testDir = Paths.get(TEST_URL); if (Files.exists(testDir)) { Files.walk(testDir) @@ -56,6 +61,8 @@ void tearDown() throws IOException { } } + // ── persistFile ───────────────────────────────────────────────────────── + @Test void testPersistFile_whenDirectoryNotExist_thenThrowsException() { String directoryPath = "non-exist-directory"; @@ -64,21 +71,58 @@ void testPersistFile_whenDirectoryNotExist_thenThrowsException() { when(filesystemConfig.getDirectory()).thenReturn(directoryPath); - assertThrows(IllegalStateException.class, () -> fileSystemRepository.persistFile(filename, content)); + assertThrows(IllegalStateException.class, + () -> fileSystemRepository.persistFile(filename, content)); } @Test void testPersistFile_filePathNotContainsDirectory() { - String filename = "test-file.png"; byte[] content = "test-content".getBytes(); File directory = new File(TEST_URL); directory.mkdirs(); when(filesystemConfig.getDirectory()).thenReturn(TEST_URL); - assertThrows(IllegalArgumentException.class, () -> fileSystemRepository.persistFile(filename, content)); + + assertThrows(IllegalArgumentException.class, + () -> fileSystemRepository.persistFile(filename, content)); } + /** + * Happy path — uses an absolute {@code @TempDir} path so that + * {@code filePath.startsWith(dir)} passes and the file is actually written. + * Covers: {@code Files.write()}, {@code log.info()}, {@code return filePath.toString()}. + */ + @Test + void testPersistFile_whenAbsoluteDirectory_shouldSaveSuccessfully() throws IOException { + String filename = "saved-file.png"; + byte[] content = "hello".getBytes(); + String absoluteDir = tempDir.toAbsolutePath().toString(); + + when(filesystemConfig.getDirectory()).thenReturn(absoluteDir); + + String result = fileSystemRepository.persistFile(filename, content); + + assertTrue(result.endsWith(filename)); + assertTrue(Files.exists(Path.of(result))); + assertArrayEquals(content, Files.readAllBytes(Path.of(result))); + } + + /** + * Covers the {@code "Invalid filename"} branch inside {@code buildFilePath()}: + * filenames containing {@code ".."} are rejected before any I/O. + */ + @Test + void testPersistFile_whenFilenameContainsPathTraversal_shouldThrowIllegalArgumentException() { + String absoluteDir = tempDir.toAbsolutePath().toString(); + when(filesystemConfig.getDirectory()).thenReturn(absoluteDir); + + assertThrows(IllegalArgumentException.class, + () -> fileSystemRepository.persistFile("../evil.png", new byte[0])); + } + + // ── getFile ───────────────────────────────────────────────────────────── + @Test void testGetFile_whenDirectIsExist_thenReturnFile() throws IOException { String filename = "test-file.png"; @@ -104,8 +148,7 @@ void testGetFileDirectoryDoesNotExist_thenThrowsException() { when(filesystemConfig.getDirectory()).thenReturn(directoryPath); - assertThrows(IllegalStateException.class, () -> fileSystemRepository.getFile(filePathStr)); + assertThrows(IllegalStateException.class, + () -> fileSystemRepository.getFile(filePathStr)); } - } - diff --git a/media/src/test/java/com/yas/media/utils/FileTypeValidatorTest.java b/media/src/test/java/com/yas/media/utils/FileTypeValidatorTest.java new file mode 100644 index 0000000000..e0b88b918f --- /dev/null +++ b/media/src/test/java/com/yas/media/utils/FileTypeValidatorTest.java @@ -0,0 +1,126 @@ +package com.yas.media.utils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import jakarta.validation.ConstraintValidatorContext; +import jakarta.validation.ConstraintValidatorContext.ConstraintViolationBuilder; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.web.multipart.MultipartFile; + +/** + * Unit tests for {@link FileTypeValidator}. + * + *

Covers: null file, null content-type, disallowed type, allowed type with + * non-image bytes (ImageIO returns null), and allowed type with a broken stream (IOException). + */ +@ExtendWith(MockitoExtension.class) +class FileTypeValidatorTest { + + private FileTypeValidator validator; + + @Mock + private ConstraintValidatorContext context; + + @Mock + private ConstraintViolationBuilder violationBuilder; + + @BeforeEach + void setUp() { + ValidFileType annotation = mock(ValidFileType.class); + when(annotation.allowedTypes()).thenReturn(new String[]{"image/jpeg", "image/png", "image/gif"}); + when(annotation.message()).thenReturn("File type not allowed"); + + validator = new FileTypeValidator(); + validator.initialize(annotation); + } + + /** + * Stubs the context violation path. + * Call only in tests where the code reaches the rejection branch + * (null file, null content-type, or disallowed type). + */ + private void stubContextViolation() { + when(context.buildConstraintViolationWithTemplate("File type not allowed")) + .thenReturn(violationBuilder); + } + + // ═══════════════════════════════════════════════════════════════════════ + // isValid + // ═══════════════════════════════════════════════════════════════════════ + + @Nested + class IsValidTest { + + @Test + void testIsValid_whenFileIsNull_shouldReturnFalse() { + stubContextViolation(); + + boolean result = validator.isValid(null, context); + + assertThat(result).isFalse(); + } + + @Test + void testIsValid_whenContentTypeIsNull_shouldReturnFalse() throws IOException { + stubContextViolation(); + MultipartFile file = mock(MultipartFile.class); + when(file.getContentType()).thenReturn(null); + + boolean result = validator.isValid(file, context); + + assertThat(result).isFalse(); + } + + @Test + void testIsValid_whenContentTypeNotAllowed_shouldReturnFalse() { + stubContextViolation(); + MultipartFile file = mock(MultipartFile.class); + when(file.getContentType()).thenReturn("application/pdf"); + + boolean result = validator.isValid(file, context); + + assertThat(result).isFalse(); + } + + @Test + // Content type matches, but bytes are not a real image → ImageIO.read() returns null + // Code returns false BEFORE reaching the context violation path → no context stub needed + void testIsValid_whenAllowedTypeButNotRealImage_shouldReturnFalse() throws IOException { + MultipartFile file = mock(MultipartFile.class); + when(file.getContentType()).thenReturn("image/png"); + when(file.getInputStream()).thenReturn(new ByteArrayInputStream(new byte[0])); + + boolean result = validator.isValid(file, context); + + assertThat(result).isFalse(); + } + + @Test + // Content type matches, but InputStream throws → IOException catch block returns false + // Uses a real anonymous InputStream to avoid Mockito UnnecessaryStubbingException + void testIsValid_whenGetInputStreamThrowsIOException_shouldReturnFalse() throws IOException { + MultipartFile file = mock(MultipartFile.class); + when(file.getContentType()).thenReturn("image/jpeg"); + when(file.getInputStream()).thenReturn(new InputStream() { + @Override + public int read() throws IOException { + throw new IOException("simulated broken stream"); + } + }); + + boolean result = validator.isValid(file, context); + + assertThat(result).isFalse(); + } + } +} diff --git a/media/src/test/java/com/yas/media/utils/StringUtilsTest.java b/media/src/test/java/com/yas/media/utils/StringUtilsTest.java new file mode 100644 index 0000000000..140099bd3b --- /dev/null +++ b/media/src/test/java/com/yas/media/utils/StringUtilsTest.java @@ -0,0 +1,51 @@ +package com.yas.media.utils; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +/** + * Unit tests for {@link StringUtils}. + * + *

Covers all branches of the single {@code hasText} method. + */ +@ExtendWith(MockitoExtension.class) +class StringUtilsTest { + + @Nested + class HasTextTest { + + @Test + void testHasText_whenInputIsNull_shouldReturnFalse() { + assertThat(StringUtils.hasText(null)).isFalse(); + } + + @Test + void testHasText_whenInputIsEmpty_shouldReturnFalse() { + assertThat(StringUtils.hasText("")).isFalse(); + } + + @Test + void testHasText_whenInputIsBlankSpaces_shouldReturnFalse() { + assertThat(StringUtils.hasText(" ")).isFalse(); + } + + @Test + void testHasText_whenInputIsNonBlankText_shouldReturnTrue() { + assertThat(StringUtils.hasText("hello")).isTrue(); + } + + @Test + void testHasText_whenInputHasLeadingAndTrailingSpaces_shouldReturnTrue() { + assertThat(StringUtils.hasText(" hello ")).isTrue(); + } + + @Test + void testHasText_whenInputIsSingleCharacter_shouldReturnTrue() { + assertThat(StringUtils.hasText("a")).isTrue(); + } + } +} diff --git a/order/pom.xml b/order/pom.xml index 726a7cbfaf..cfe6b0e36e 100644 --- a/order/pom.xml +++ b/order/pom.xml @@ -82,6 +82,27 @@ org.jacoco jacoco-maven-plugin + + + check + + check + + + + + + + LINE + COVEREDRATIO + 0.70 + + + + + + + diff --git a/pom.xml b/pom.xml index f572ae554f..5d39b42f96 100644 --- a/pom.xml +++ b/pom.xml @@ -355,6 +355,25 @@ report + + check + + check + + + + + + + LINE + COVEREDRATIO + 0.70 + + + + + + diff --git a/product/Jenkinsfile b/product/Jenkinsfile new file mode 100644 index 0000000000..40c1d7149d --- /dev/null +++ b/product/Jenkinsfile @@ -0,0 +1,89 @@ +// Jenkins Multibranch Pipeline for the 'product' service +// Job name: yas-product-ci +// Place this file at: product/Jenkinsfile + +pipeline { + + // Run on any available Jenkins agent + agent any + + // Use the JDK and Maven installations configured in Jenkins Global Tool Configuration + tools { + jdk 'jdk-21' + maven 'maven-3.9' + } + + environment { + // Identifies which service this pipeline belongs to + SERVICE_NAME = 'product' + } + + options { + // Abort the entire build if it exceeds 15 minutes + timeout(time: 15, unit: 'MINUTES') + } + + stages { + + // Stage 1 — Checkout source code from SCM (configured in the Multibranch job) + stage('checkout') { + steps { + echo 'Check out source code' + checkout scm + } + } + + // Stage 2 — Build the shared common-library so downstream services can resolve it + stage('build_common_library') { + steps { + echo 'Build common-library' + // Install common-library into the local Maven repository; skip tests for speed + bat 'cd common-library && mvn clean install -DskipTests' + } + } + + // Stage 3 — Run unit tests for the product service and publish results + stage('test') { + steps { + echo 'Run unit tests' + // Execute the full test lifecycle inside the service directory + bat "cd %SERVICE_NAME% && mvn clean test" + } + post { + // Always publish test and coverage reports, even when tests fail + always { + echo 'Publish product-test-report' + // Publish JUnit XML results; allowEmptyResults prevents failure when no XML found + junit allowEmptyResults: true, + testResults: '**/surefire-reports/*.xml' + + echo 'Publish product-coverage' + // Publish JaCoCo code-coverage report + jacoco( + execPattern: '**/jacoco.exec', + classPattern: '**/classes', + sourcePattern: '**/src/main/java' + ) + } + } + } + + // Stage 4 — Package the service JAR (only reached when Test stage succeeds) + stage('build') { + steps { + echo 'Build JAR' + // Package the application, skipping redundant test execution + bat "cd %SERVICE_NAME% && mvn package -DskipTests" + } + } + } + + post { + success { + echo "Pipeline yas-product-ci completed successfully." + } + failure { + echo "Pipeline yas-product-ci failed. Check stage logs above." + } + } +} diff --git a/product/pom.xml b/product/pom.xml index 38b5d9503d..04cc95c55a 100644 --- a/product/pom.xml +++ b/product/pom.xml @@ -89,6 +89,27 @@ org.jacoco jacoco-maven-plugin + + + check + + check + + + + + + + LINE + COVEREDRATIO + 0.70 + + + + + + + diff --git a/rating/pom.xml b/rating/pom.xml index 38851fab2c..b589ccad11 100644 --- a/rating/pom.xml +++ b/rating/pom.xml @@ -78,6 +78,27 @@ org.jacoco jacoco-maven-plugin + + + check + + check + + + + + + + LINE + COVEREDRATIO + 0.70 + + + + + + + diff --git a/search/pom.xml b/search/pom.xml index 4a4c968c7f..7f2b152d70 100644 --- a/search/pom.xml +++ b/search/pom.xml @@ -95,6 +95,27 @@ org.jacoco jacoco-maven-plugin + + + check + + check + + + + + + + LINE + COVEREDRATIO + 0.70 + + + + + + + diff --git a/tax/pom.xml b/tax/pom.xml index 9cf390a73f..23a0f43669 100644 --- a/tax/pom.xml +++ b/tax/pom.xml @@ -79,6 +79,27 @@ org.jacoco jacoco-maven-plugin + + + check + + check + + + + + + + LINE + COVEREDRATIO + 0.70 + + + + + + +