From be5947db447111303aad04b77079b95edfa6047f Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 11 Feb 2026 22:05:47 +0000 Subject: [PATCH 1/2] Add GitHub Actions CI/CD workflows migrated from Jenkins Co-Authored-By: Angela Lin --- .github/workflows/cd.yml | 76 +++++++++++++++++++++++++++++ .github/workflows/ci.yml | 102 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 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..626e4b5a --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,76 @@ +name: CD Pipeline + +on: + workflow_call: + inputs: + DOCKER_TAG: + description: 'Docker tag of the image built by the CI job' + required: true + type: string + workflow_dispatch: + inputs: + DOCKER_TAG: + description: 'Docker tag of the image built by the CI job' + required: true + type: string + +permissions: + contents: write + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.ref }} + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Verify Docker image tag + run: echo "DOCKER TAG RECEIVED - ${{ inputs.DOCKER_TAG }}" + + - name: Update Kubernetes manifest + run: | + sed -i -e 's|trainwithshubham/bankapp-eks:.*|trainwithshubham/bankapp-eks:${{ inputs.DOCKER_TAG }}|g' kubernetes/bankapp-deployment.yml + + - name: Commit and push changes + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + echo "Checking repository status:" + git status + echo "Adding changes to git:" + git add kubernetes/bankapp-deployment.yml + echo "Committing changes:" + git commit -m "Updated K8s Deployment Docker Image Version to ${{ inputs.DOCKER_TAG }}" || echo "No changes to commit" + echo "Pushing changes to github:" + git push + + - name: Send deployment notification email + if: always() + uses: dawidd6/action-send-mail@v3 + with: + server_address: ${{ secrets.MAIL_SERVER }} + server_port: ${{ secrets.MAIL_PORT }} + username: ${{ secrets.MAIL_USERNAME }} + password: ${{ secrets.MAIL_PASSWORD }} + subject: "BankApp Application has been updated and deployed - ${{ job.status }}" + to: ${{ secrets.NOTIFICATION_EMAIL }} + from: ${{ secrets.MAIL_USERNAME }} + content_type: text/html + body: | + + +
+

Project: ${{ github.repository }}

+
+
+

Build Number: ${{ github.run_number }}

+
+
+

URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

+
+ + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..7f7509cc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,102 @@ +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 + type: string + +permissions: + contents: write + +jobs: + build: + runs-on: ubuntu-latest + outputs: + docker_tag: ${{ steps.set-tag.outputs.docker_tag }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set Docker tag + id: set-tag + run: | + if [ -n "${{ github.event.inputs.DOCKER_TAG }}" ]; then + echo "docker_tag=${{ github.event.inputs.DOCKER_TAG }}" >> "$GITHUB_OUTPUT" + else + echo "docker_tag=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT" + fi + + - name: Trivy filesystem scan + uses: aquasecurity/trivy-action@master + with: + scan-type: 'fs' + scan-ref: '.' + + - name: OWASP Dependency Check + uses: dependency-check/Dependency-Check_Action@main + with: + project: 'bankapp' + path: '.' + format: 'XML' + out: '.' + + - name: Upload OWASP Dependency Check report + uses: actions/upload-artifact@v4 + if: always() + with: + name: dependency-check-report + path: dependency-check-report.xml + + - 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.projectName=bankapp + -Dsonar.projectKey=bankapp + + - name: SonarQube Quality Gate + uses: sonarsource/sonarqube-quality-gate-action@master + timeout-minutes: 1 + continue-on-error: true + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + + - name: Log in to Docker Hub + 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@v5 + with: + context: . + push: true + tags: ${{ secrets.DOCKERHUB_USERNAME }}/bankapp:${{ steps.set-tag.outputs.docker_tag }} + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + if: success() + with: + name: build-artifacts + path: '**/*.xml' + + deploy: + needs: build + if: success() && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + uses: ./.github/workflows/cd.yml + with: + DOCKER_TAG: ${{ needs.build.outputs.docker_tag }} + secrets: inherit From 08ea1ab1f00448c172b191c1d93ed14e1fcedbca Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 11 Feb 2026 22:09:21 +0000 Subject: [PATCH 2/2] Make SonarQube and Docker steps skip gracefully when secrets are not configured Co-Authored-By: Angela Lin --- .github/workflows/ci.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f7509cc..78406d3f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,8 @@ jobs: path: dependency-check-report.xml - name: SonarQube Analysis - uses: sonarsource/sonarqube-scan-action@v5 + if: ${{ secrets.SONAR_TOKEN != '' && secrets.SONAR_HOST_URL != '' }} + uses: sonarsource/sonarqube-scan-action@v6 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} @@ -66,6 +67,7 @@ jobs: -Dsonar.projectKey=bankapp - name: SonarQube Quality Gate + if: ${{ secrets.SONAR_TOKEN != '' && secrets.SONAR_HOST_URL != '' }} uses: sonarsource/sonarqube-quality-gate-action@master timeout-minutes: 1 continue-on-error: true @@ -74,12 +76,14 @@ jobs: SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} - name: Log in to Docker Hub + 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 + if: ${{ secrets.DOCKERHUB_USERNAME != '' && secrets.DOCKERHUB_TOKEN != '' }} uses: docker/build-push-action@v5 with: context: .