From 4f452923ed11da4df31c35af0fcde0f9175873bd Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:27:28 +0000 Subject: [PATCH] feat: migrate Jenkins pipeline to GitHub Actions CI/CD workflows - Add CI workflow with build, Trivy scan, OWASP dependency check, SonarQube analysis, Docker build & push stages - Add CD workflow to update Kubernetes deployment manifest - Preserve all original pipeline stages and security scanning Co-Authored-By: vanessa.salas --- .github/workflows/cd.yml | 59 +++++++++++++ .github/workflows/ci.yml | 180 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 239 insertions(+) create mode 100644 .github/workflows/cd.yml create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 00000000..89962a45 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,59 @@ +name: BankApp CD + +on: + workflow_dispatch: + inputs: + docker_tag: + description: 'Docker tag of the image built by the CI workflow' + required: true + type: string + +env: + K8S_DEPLOYMENT_FILE: kubernetes/bankapp-deployment.yml + DOCKER_IMAGE: ${{ vars.DOCKERHUB_USERNAME }}/bankapp + +jobs: + update-k8s-manifest: + name: "Update Kubernetes Manifest" + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: DevOps + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Verify Docker image tag + run: echo "Docker tag received - ${{ inputs.docker_tag }}" + + - name: Update Kubernetes deployment manifest + run: | + sed -i "s|image:.*bankapp.*|image: ${{ env.DOCKER_IMAGE }}:${{ inputs.docker_tag }}|g" \ + ${{ env.K8S_DEPLOYMENT_FILE }} + echo "Updated manifest:" + grep 'image:' ${{ env.K8S_DEPLOYMENT_FILE }} + + - name: Commit and push changes + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add ${{ env.K8S_DEPLOYMENT_FILE }} + git diff --cached --quiet && echo "No changes to commit" && exit 0 + git commit -m "chore: update K8s deployment image to ${{ inputs.docker_tag }}" + git push origin DevOps + + notify: + name: "Notify" + runs-on: ubuntu-latest + needs: update-k8s-manifest + if: always() + + steps: + - name: Deployment summary + run: | + echo "## BankApp CD Summary" >> $GITHUB_STEP_SUMMARY + echo "- **Docker Tag**: ${{ inputs.docker_tag }}" >> $GITHUB_STEP_SUMMARY + echo "- **Image**: ${{ env.DOCKER_IMAGE }}:${{ inputs.docker_tag }}" >> $GITHUB_STEP_SUMMARY + echo "- **K8s Manifest**: ${{ env.K8S_DEPLOYMENT_FILE }}" >> $GITHUB_STEP_SUMMARY + echo "- **Status**: ${{ needs.update-k8s-manifest.result }}" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..a23809b9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,180 @@ +name: BankApp CI + +on: + push: + branches: [DevOps, main] + pull_request: + branches: [DevOps, main] + +env: + DOCKER_IMAGE: ${{ vars.DOCKERHUB_USERNAME }}/bankapp + DOCKER_TAG: ${{ github.sha }} + +jobs: + build: + name: Build & Test + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - 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 install -DskipTests=true + + - name: Run Tests + run: mvn test + continue-on-error: true + + trivy-scan: + name: "Trivy: Filesystem Scan" + runs-on: ubuntu-latest + needs: build + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run Trivy filesystem scan + uses: aquasecurity/trivy-action@master + with: + scan-type: 'fs' + scan-ref: '.' + format: 'table' + severity: 'CRITICAL,HIGH' + + owasp-dependency-check: + name: "OWASP: Dependency Check" + runs-on: ubuntu-latest + needs: build + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Run OWASP Dependency-Check + uses: dependency-check/Dependency-Check_Action@main + with: + project: 'bankapp' + path: '.' + format: 'HTML' + args: '--failOnCVSS 7' + continue-on-error: true + + - name: Upload OWASP report + uses: actions/upload-artifact@v4 + with: + name: owasp-dependency-check-report + path: reports/ + + sonarqube-analysis: + name: "SonarQube: Code Analysis" + runs-on: ubuntu-latest + needs: build + if: vars.SONAR_HOST_URL != '' + + 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 for analysis + run: mvn clean install -DskipTests=true + + - name: SonarQube Scan + uses: SonarSource/sonarqube-scan-action@v5 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ vars.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: 5 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + docker-build-push: + name: "Docker: Build & Push" + runs-on: ubuntu-latest + needs: [trivy-scan, owasp-dependency-check] + if: github.event_name == 'push' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and Push Docker image + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: | + ${{ env.DOCKER_IMAGE }}:${{ env.DOCKER_TAG }} + ${{ env.DOCKER_IMAGE }}:latest + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Trivy image scan + uses: aquasecurity/trivy-action@master + with: + image-ref: '${{ env.DOCKER_IMAGE }}:${{ env.DOCKER_TAG }}' + format: 'table' + severity: 'CRITICAL,HIGH' + continue-on-error: true + + deploy: + name: "Trigger CD" + runs-on: ubuntu-latest + needs: docker-build-push + if: github.ref == 'refs/heads/DevOps' && github.event_name == 'push' + + steps: + - name: Trigger CD workflow + uses: actions/github-script@v7 + with: + script: | + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'cd.yml', + ref: 'DevOps', + inputs: { + docker_tag: '${{ env.DOCKER_TAG }}' + } + })