diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..b31a8251 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,126 @@ +name: CI Pipeline + +on: + push: + branches: [main, DevOps] + pull_request: + branches: [main, DevOps] + workflow_dispatch: + inputs: + DOCKER_TAG: + description: "Docker image tag for the build" + required: true + default: "latest" + +env: + IMAGE_NAME: bankapp + +jobs: + security-scans: + name: Security Scans + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Trivy Filesystem Scan + uses: aquasecurity/trivy-action@0.35.0 + with: + scan-type: "fs" + scan-ref: "." + format: "table" + exit-code: "0" + severity: "CRITICAL,HIGH" + + - name: OWASP Dependency Check + uses: dependency-check/Dependency-Check_Action@main + with: + project: "bankapp" + path: "." + format: "XML" + out: "reports" + + - name: Upload Dependency Check Report + uses: actions/upload-artifact@v4 + if: always() + with: + name: dependency-check-report + path: reports/ + + code-quality: + name: SonarQube Analysis + runs-on: ubuntu-latest + continue-on-error: true + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: "17" + distribution: "temurin" + cache: "maven" + + - name: Build with Maven + run: mvn clean verify -DskipTests=true + + - name: SonarQube Analysis + uses: SonarSource/sonarqube-scan-action@v5 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + with: + args: > + -Dsonar.projectKey=bankapp + -Dsonar.projectName=bankapp + -Dsonar.java.binaries=target/classes + + - name: SonarQube Quality Gate + uses: SonarSource/sonarqube-quality-gate-action@v1 + timeout-minutes: 1 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + docker: + name: Docker Build & Push + runs-on: ubuntu-latest + needs: [security-scans] + if: always() && needs.security-scans.result == 'success' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set Docker tag + id: tag + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + echo "docker_tag=${{ github.event.inputs.DOCKER_TAG }}" >> "$GITHUB_OUTPUT" + else + echo "docker_tag=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT" + fi + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to DockerHub + if: ${{ secrets.DOCKERHUB_USERNAME != '' && secrets.DOCKERHUB_TOKEN != '' }} + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and Push Docker Image + uses: docker/build-push-action@v6 + with: + context: . + push: ${{ secrets.DOCKERHUB_USERNAME != '' && secrets.DOCKERHUB_TOKEN != '' }} + tags: | + ${{ secrets.DOCKERHUB_USERNAME || 'local' }}/${{ env.IMAGE_NAME }}:${{ steps.tag.outputs.docker_tag }} + cache-from: type=gha + cache-to: type=gha,mode=max