DevSecOps CI Pipeline with GitHub Actions

Automate security scanning and code quality checks into a CI pipeline.

Introduction

30 Second Summary

Every time you push code to a repository, there is a chance that change introduces a security vulnerability or a subtle bug. In most teams, catching these issues falls to manual reviews or last-minute scans that happen long after the code was written.

In this project, you will build a DevSecOps CI pipeline using GitHub Actions that automatically builds your Docker image, scans it for vulnerabilities, and analyzes your code quality on every push.

What You'll Build

You push a code change to your Tetris repository and watch a fully automated pipeline build your image, scan it for security issues, analyze your code quality, and push the result to Docker Hub within minutes.

By the end of this project, you'll have:

  • A GitHub Actions workflow that triggers on every push. You see a green (or red) run in the Actions tab as your Tetris image is built and pushed to Docker Hub.
  • Trivy vulnerability scanning that prints a security report directly in the workflow logs. Critical vulnerabilities fail the build before a bad image reaches production.
  • A SonarQube Cloud dashboard where you can see bugs, code smells, and security hotspots in your source code at a glance.
  • Secret Mission: A quality gate that blocks the pipeline when code quality standards are not met, enforcing DevSecOps as a hard requirement.

Are there any prerequisites?

This project builds on Project 1 (Containerize a Tetris App with Docker). You need a GitHub account, a Docker Hub account, and the shafiswapnil/tetris repository on GitHub with a working Dockerfile.

Before We Start

Before We Start...

Before we dive in, let's lock in what you're about to build and why it matters.

Set Up GitHub Secrets and SonarQube Cloud

Your CI pipeline will push Docker images to Docker Hub and run code analysis through SonarQube Cloud. Both services require credentials to authenticate.

Hardcoding credentials in a workflow file would expose them in your public repository for anyone to see. GitHub Secrets solve this by encrypting sensitive values and injecting them only at runtime. In this step, you'll store your Docker Hub and SonarQube Cloud credentials as encrypted repository secrets.

In this step, get ready to:
  • Create Docker Hub secrets in your GitHub repository.
  • Sign up for SonarQube Cloud and generate an authentication token.
  • Note your SonarQube Cloud organization and project keys for later use.
Create Docker Hub secrets

Your workflow needs your Docker Hub username and password to push images. You'll store both as encrypted secrets that GitHub Actions can read at runtime.

  • Open your shafiswapnil/tetris repository on GitHub.
  • Click Settings in the repository navigation bar.
  • In the left sidebar, under Security, click Secrets and variables.
  • Click Actions.
  • Click the Secrets tab.

What are GitHub Secrets?

GitHub Secrets are encrypted environment variables that your repository stores securely. They are never exposed in logs or to users who view the repository.

Your workflow accesses them using the ${{ secrets.SECRET_NAME }} syntax. GitHub decrypts them only when a workflow run needs them.

  • Click New repository secret.
  • In the Name field, enter DOCKER_USERNAME.
  • In the Secret field, enter your Docker Hub username.
  • Click Add secret.

You should see DOCKER_USERNAME appear in the repository secrets list.

  • Click New repository secret again.
  • In the Name field, enter DOCKER_PASSWORD.
  • In the Secret field, enter your Docker Hub password or access token.
  • Click Add secret.

You should now see both DOCKER_USERNAME and DOCKER_PASSWORD listed on the secrets page.

Don't see the Settings tab?

You need write access to the repository to manage secrets. If you forked the repo in Project 1, you are the owner and should see Settings in the top navigation bar. If you still cannot find it, look for the overflow menu next to the tab list.

Help me find Settings in my GitHub repository.

Sign up for SonarQube Cloud and create SONAR_TOKEN

SonarQube Cloud analyzes your source code for bugs, security hotspots, and code smells. You need to create an account, import your repository, and generate an authentication token.

  • Open https://sonarcloud.io in a new browser tab.
  • Click Log in with GitHub.
  • Authorize SonarQube Cloud to access your GitHub account when the OAuth popup appears.

What happens during authorization?

GitHub will show a popup asking you to grant SonarQube Cloud read access to your repositories. This lets SonarQube Cloud pull your code for analysis. Your credentials are never shared directly with SonarQube.

  • Follow the on-screen prompts to create your SonarQube Cloud organization from your GitHub account.
  • Select the Free plan when asked to choose a subscription.
  • Click Create Organization.
  • When prompted to import projects, select the tetris repository from the list.
  • Click Set up to import it as a new SonarQube Cloud project.

Your SonarQube Cloud project is now created. Next, generate the token your CI pipeline will use to authenticate.

  • Click your avatar in the top-right corner of SonarQube Cloud.
  • Click My Account.
  • Click the Security tab.
  • Under Generate Tokens, enter tetris-ci as the token name.
  • Click Generate.
  • Copy the token value immediately. You will not be able to see it again after you leave this page.

Copy the token before navigating away

SonarQube Cloud only shows the token value once at the moment of creation. Paste it somewhere safe (like a temporary text file) before switching tabs. If you lose it, you will need to generate a new one.

Now store this token as a GitHub Secret so your workflow can use it.

  • Switch back to your GitHub repository's Settings tab in the browser.
  • Navigate to Secrets and variables, then Actions, then the Secrets tab.
  • Click New repository secret.
  • In the Name field, enter SONAR_TOKEN.
  • In the Secret field, paste the token you just copied.
  • Click Add secret.

You should see SONAR_TOKEN join the other two secrets in the list.

SonarQube Cloud not showing your repository?

During organization setup, SonarQube Cloud installs a GitHub app that controls which repositories it can access. If you don't see the tetris repository during import, check that the SonarQube Cloud app has access to All repositories (or specifically the tetris repo) under your GitHub account's Installed GitHub Apps settings.

Help me connect my tetris repository to SonarQube Cloud.

Note your SonarQube Cloud organization key and project key

Your CI workflow will need two identifiers to tell SonarQube Cloud which project to analyze. You'll use these in a configuration file in the next step.

  • In SonarQube Cloud, click on your tetris project to open it.
  • Look at the URL in your browser. It follows the pattern sonarcloud.io/project/overview?id=shafiswapnil_tetris.
  • Note your organization key: shafiswapnil (your GitHub username).
  • Note your project key: shafiswapnil_tetris (the organization key, underscore, repository name).

Where do these keys come from?

When you import a GitHub repository, SonarQube Cloud automatically sets the organization key to your GitHub username and the project key to username_reponame. You can also find both keys in the project's Information page under Administration.

Time to verify that all three secrets are in place.

  • Switch back to your GitHub repository.
  • Navigate to Settings, then Secrets and variables, then Actions.
  • Confirm you see DOCKER_USERNAME, DOCKER_PASSWORD, and SONAR_TOKEN listed under Repository secrets.

Your credentials are locked in and encrypted. Next up, you'll create the CI workflow file that uses these secrets to build and push your Docker image automatically.

Create the CI Workflow and Push to GitHub

Your repository secrets are locked in and ready to be consumed by a pipeline. Now you need the pipeline itself.

Before layering on security tools, you need a working foundation that builds your Docker image on every push. In this step, you will write a GitHub Actions workflow that checks out your code, logs in to Docker Hub, builds the Tetris image, and pushes it tagged with the commit SHA.

In this step, get ready to:
  • Create a GitHub Actions workflow file that builds and pushes your Docker image.
  • Create a SonarQube Cloud configuration file for future code analysis.
  • Push both files and watch the pipeline run with a green checkmark.
Create the workflow directory and file

GitHub Actions discovers workflows by looking for YAML files inside a special .github/workflows/ directory at the root of your repository.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Terminal and press Enter to open it.
  • Navigate to your local tetris repository by running this command:
cd ~/Desktop/tetris
  • Create the workflow directory by running this command:
mkdir -p .github/workflows
  • Confirm the directory was created by running:
ls .github

You should see workflows listed in the output.

  • Create and open a new file called ci.yml inside the .github/workflows/ directory using your preferred text editor.
  • Paste the following YAML into ci.yml to define the pipeline trigger and checkout step:
name: DevSecOps CI Pipeline

on:
  push:
    branches:
      - master
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  build-scan-push:
    name: Build, Scan, and Push
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

What does this YAML do?

  • on: push triggers the workflow every time you push to the master branch.
  • on: pull_request also triggers on pull requests so changes are validated before merging.
  • runs-on: ubuntu-latest tells GitHub to run the job on a fresh Linux virtual machine.
  • fetch-depth: 0 clones the full Git history, which SonarQube Cloud needs later for accurate analysis.
  • Now add the Docker login and build-push steps directly below the checkout step in the same file:
      - name: Log in to Docker Hub
        uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and push Docker image
        uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
        with:
          context: .
          push: true
          tags: ${{ secrets.DOCKER_USERNAME }}/tetris-app:${{ github.sha }}

What do these steps do?

The login step authenticates with Docker Hub using the secrets you created in Step 1. The actions are pinned to commit SHAs instead of version tags for security.

The build-push step builds your Dockerfile and pushes the resulting image to Docker Hub. The tag uses ${{ github.sha }} so every image is traceable to the exact commit that produced it.

  • Save ci.yml.
  • Verify the full file by running:
cat .github/workflows/ci.yml

You should see all three steps listed: Check out code, Log in to Docker Hub, and Build and push Docker image.

File looks empty or has errors?

  • Make sure you saved the file after pasting each section.
  • YAML is whitespace-sensitive. Each level of nesting must use exactly 2 spaces, not tabs.
  • Confirm the file is at .github/workflows/ci.yml (not github/workflows/ci.yml without the leading dot).

Help me fix my ci.yml file

✔️ Awesome, I've got everything!

Great. Double check you saved the file, then move on to the next substep.

ⓧ I'd like to double check the full code

Scroll up and confirm your ci.yml contains these two sections in order:

  • The pipeline header, trigger configuration, and checkout step (starting with name: DevSecOps CI Pipeline).
  • The Docker login and build-push steps (starting with - name: Log in to Docker Hub).

The file should have 31 lines total when you include the blank lines between steps.

Create the SonarQube Cloud configuration file

SonarQube Cloud needs a properties file in your project root to know which organization and project to associate the analysis with.

  • In the root of your tetris repository, create a new file called sonar-project.properties and paste the following content:
sonar.organization=shafiswapnil
sonar.projectKey=shafiswapnil_tetris

sonar.sources=.
sonar.exclusions=**/node_modules/**,**/*.test.js

What do these properties mean?

  • sonar.organization matches the organization key you noted when setting up SonarQube Cloud.
  • sonar.projectKey links this repo to the project you imported in SonarQube Cloud.
  • sonar.sources tells the scanner to analyze everything from the current directory.
  • sonar.exclusions skips node_modules and test files so the analysis focuses on your actual source code.
  • Save sonar-project.properties.
  • Confirm both new files exist by running:
ls sonar-project.properties .github/workflows/ci.yml

You should see both file paths printed without errors.

File not found?

  • Make sure you are in the root of your tetris folder. Run pwd to check your current directory.
  • Confirm the properties file is named exactly sonar-project.properties (not sonar.properties or similar).

Help me find my missing file

Push and watch the pipeline run

Both files are ready locally. Pushing them to GitHub will trigger your new workflow automatically.

  • Stage, commit, and push the new files by running these commands:
git add .github/workflows/ci.yml sonar-project.properties
git commit -m "Add CI workflow and SonarQube config"
git push origin master

Before you check the Actions tab, predict: do you think GitHub will start building your image automatically, or will you need to trigger the workflow manually?

  • Open your repository on GitHub at https://github.com/shafiswapnil/tetris.
  • Click the Actions tab in the repository navigation bar.
  • Click on the running workflow (it shows your commit message).
  • Expand the Build and push Docker image step to see the live logs.

The workflow started automatically because you defined on: push in your YAML. After a minute or two, you should see a green checkmark next to the workflow run.

What should I see in Docker Hub?

Navigate to https://hub.docker.com and sign in. Under your repositories, you will see a new tetris-app repository with a tag matching your commit SHA. This proves the pipeline built and pushed the image successfully.

Workflow failed with a red X?

  • Click the failed step to read the error message.
  • If you see an authentication error, double check that your DOCKER_USERNAME and DOCKER_PASSWORD secrets match your Docker Hub credentials exactly.
  • If the error mentions invalid workflow file, check that your YAML indentation uses spaces (not tabs) and that each key aligns correctly.
  • Make sure you pushed to master (not main) since the trigger listens on master.

Help me diagnose my failed workflow

Your pipeline is live and building images on every push. Next up, you will add Trivy vulnerability scanning so every image gets checked for security issues before it ships.

Add Trivy Vulnerability Scanning

Your pipeline now builds and pushes Docker images automatically on every push to master. But you have zero visibility into whether those images contain known security vulnerabilities.

Trivy is an open-source vulnerability scanner that inspects container image layers and reports CVEs (Common Vulnerabilities and Exposures). In this step, you will add Trivy to your pipeline so every image is scanned before it can reach production.

In this step, get ready to:
  • Add a Trivy scan step to your CI workflow.
  • Observe the vulnerability report in the workflow logs.
  • Configure Trivy to fail the build on critical findings.
Add the Trivy scan step to the workflow

Right now your pipeline pushes images to Docker Hub without checking if those images have known exploits baked in. Trivy will scan the image right after the build step and print a vulnerability report directly in the workflow logs.

  • Open .github/workflows/ci.yml in your code editor.
  • Find the last step in the file (the Build and push Docker image step).
  • Add the following Trivy scan step below it:
      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@v0.36.0
        with:
          image-ref: ${{ secrets.DOCKER_USERNAME }}/tetris-app:${{ github.sha }}
          format: 'table'
          vuln-type: 'os,library'

What does this step do?

  • aquasecurity/trivy-action@v0.36.0 runs the Trivy scanner inside your GitHub Actions runner.
  • image-ref points Trivy at the exact image you just built and pushed, using the same tag pattern (your username plus the commit SHA).
  • format: 'table' prints a human-readable vulnerability table in the workflow logs.
  • vuln-type: 'os,library' tells Trivy to check both OS-level packages and application library dependencies.
  • Save .github/workflows/ci.yml.
Push and observe the vulnerability report

The only way to see Trivy in action is to trigger the pipeline. You will commit and push your updated workflow file, then watch the scan results appear in the Actions tab.

  • Stage, commit, and push your changes by running these commands:
git add .github/workflows/ci.yml
git commit -m "Add Trivy vulnerability scanning"
git push origin master

Before you check the results, what do you think Trivy will find in an image based on nginx:alpine? Do you expect zero vulnerabilities, or some?

  • Open your repository on GitHub and click the Actions tab.
  • Click on the running workflow (named after your commit message).
  • Click the Build, Scan, and Push job, then expand the Run Trivy vulnerability scanner step.

You will see a table listing vulnerabilities found in the nginx:alpine base image. You will likely see LOW and MEDIUM severity findings.

Why does the pipeline still pass?

Trivy defaults to exit code 0, which means it reports vulnerabilities without failing the workflow. The scan is informational only at this point. You will add enforcement in the next substep.

Don't see the Trivy step in the logs?

  • Make sure you pushed to the master branch. The workflow only triggers on pushes to master.
  • Check that the Trivy step is indented correctly under steps: in your YAML file. YAML is whitespace-sensitive.

Help me debug why my Trivy step is not appearing in the GitHub Actions logs.

Make Trivy fail the build on CRITICAL/HIGH vulnerabilities

The scan runs, but the pipeline still shows a green checkmark regardless of what Trivy finds. A report nobody acts on is not real security. You need the pipeline to block the image from shipping if serious vulnerabilities exist.

  • Open .github/workflows/ci.yml and find the Trivy step you just added.
  • Find this with: block:
        with:
          image-ref: ${{ secrets.DOCKER_USERNAME }}/tetris-app:${{ github.sha }}
          format: 'table'
          vuln-type: 'os,library'
  • Replace the entire with: block with this updated version that adds failure enforcement:
        with:
          image-ref: ${{ secrets.DOCKER_USERNAME }}/tetris-app:${{ github.sha }}
          format: 'table'
          exit-code: '1'
          ignore-unfixed: true
          vuln-type: 'os,library'
          severity: 'CRITICAL,HIGH'

What do the new lines do?

  • exit-code: '1' makes Trivy return a non-zero exit code when it finds matching vulnerabilities. GitHub Actions treats any non-zero exit code as a failure, so the pipeline will go red.
  • severity: 'CRITICAL,HIGH' limits the failure trigger to only CRITICAL and HIGH severity CVEs. LOW and MEDIUM findings still appear in the report but will not block the build.
  • ignore-unfixed: true skips vulnerabilities that have no available patch yet. This prevents the pipeline from blocking on issues you cannot fix today.
  • Save .github/workflows/ci.yml.
  • Commit and push the updated workflow by running:
git add .github/workflows/ci.yml
git commit -m "Make Trivy fail on CRITICAL/HIGH vulnerabilities"
git push origin master

Do you think the pipeline will pass or fail this time? The answer depends on whether your nginx:alpine base image currently has any CRITICAL or HIGH CVEs with available fixes.

  • Return to the Actions tab on GitHub and open the latest workflow run.
  • Expand the Run Trivy vulnerability scanner step to see the filtered results.

If the pipeline passes (green checkmark), it means no CRITICAL/HIGH vulnerabilities with available fixes were found in your base image. If it fails (red X), Trivy caught something serious and blocked the build exactly as intended.

A red pipeline is a win here

A failing pipeline does not mean you did something wrong. It means your security scanning is working. The pipeline is doing its job by catching vulnerabilities before they reach production.

Pipeline failing but you want to continue?

If Trivy found CRITICAL/HIGH vulnerabilities in your nginx:alpine base image, the pipeline will fail. This is expected behavior. You can continue to Step 4 regardless. The SonarQube step will still run because you add it to the same job, and it executes in the order defined.

Help me understand whether a Trivy failure in my pipeline is expected or indicates a real problem.

✔️ Awesome, I've got everything!

Great. Make sure you have saved .github/workflows/ci.yml with the full Trivy step including exit-code, ignore-unfixed, and severity settings.

ⓧ I'd like to double check the full code

Your .github/workflows/ci.yml file should contain these sections in order. Scroll up and confirm each is present:

  • The workflow name (DevSecOps CI Pipeline) and trigger configuration for master branch pushes and pull requests.
  • The build-scan-push job running on ubuntu-latest.
  • Step 1: Check out code with fetch-depth: 0.
  • Step 2: Log in to Docker Hub using DOCKER_USERNAME and DOCKER_PASSWORD secrets.
  • Step 3: Build and push Docker image tagged with the commit SHA.
  • Step 4: Run Trivy vulnerability scanner using aquasecurity/trivy-action@v0.36.0 with exit-code: '1', ignore-unfixed: true, vuln-type: 'os,library', and severity: 'CRITICAL,HIGH'.

Your pipeline now has teeth. Every image is scanned for known vulnerabilities, and serious ones block the build. Next up, you will add SonarQube Cloud to analyze your actual source code for bugs, security hotspots, and code smells.

Add SonarQube Cloud Code Analysis

Your pipeline now catches known vulnerabilities in dependencies and base image layers. That protects you from shipping containers with exploitable packages.

But Trivy does not look at the code you actually wrote. Bugs, security hotspots, and messy patterns in your JavaScript and HTML slip right through. SonarQube Cloud fills this gap by running static analysis on your source code and surfacing the results in a web dashboard.

In this step, get ready to:
  • Add the SonarQube Cloud scan step to your CI workflow.
  • Push a commit and view your code quality results on the SonarQube Cloud dashboard.
Add the SonarQube scan step to the workflow

The sonar-project.properties file you created earlier tells SonarQube Cloud which organization and project to associate the scan with. Now you need the actual workflow step that triggers the scan.

  • Open .github/workflows/ci.yml in your editor.
  • Find the end of the Trivy vulnerability scanner step (the last line is severity: 'CRITICAL,HIGH').
  • Add the following SonarQube scan step below it:
      - name: SonarQube Scan
        uses: SonarSource/sonarqube-scan-action@v8.2.1
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

What does this step do?

  • SonarSource/sonarqube-scan-action@v8.2.1 is the official GitHub Action from SonarSource that runs the SonarQube scanner.
  • It reads your sonar-project.properties file automatically to know which organization and project key to report to.
  • The SONAR_TOKEN environment variable authenticates the scan against your SonarQube Cloud account.
  • Save ci.yml.

✔️ Awesome, I've got everything!

Great. Your workflow now has five steps: checkout, Docker login, build-and-push, Trivy scan, and SonarQube scan.

ⓧ I'd like to double check the full code

Your ci.yml should contain these steps in order. Scroll through your file and confirm each is present:

  • Check out code (using actions/checkout@v6 with fetch-depth: 0).
  • Log in to Docker Hub (using docker/login-action with your secrets).
  • Build and push Docker image (using docker/build-push-action with commit SHA tag).
  • Run Trivy vulnerability scanner (using aquasecurity/trivy-action@v0.36.0 with exit-code: '1' and severity: 'CRITICAL,HIGH').
  • SonarQube Scan (using SonarSource/sonarqube-scan-action@v8.2.1 with SONAR_TOKEN env var).

Indentation wrong?

YAML is sensitive to indentation. The - name: SonarQube Scan line must be at the same indent level as the other - name: lines above it (6 spaces from the left edge).

If your editor uses tabs instead of spaces, check that you have spaces-only enabled for YAML files. Help me fix YAML indentation errors in my GitHub Actions workflow.

Push and view results on SonarQube Cloud

With the scan step in place, push your changes and let the pipeline run the full sequence.

  • Commit and push your updated workflow by running these commands:
git add .github/workflows/ci.yml
git commit -m "Add SonarQube Cloud scan step"
git push origin master
  • Open your repository on GitHub.
  • Click the Actions tab.
  • Click on the running workflow to see the live logs.

Before you expand the SonarQube Scan step in the logs, predict: do you think this step will pass or fail?

  • Expand the SonarQube Scan step in the workflow logs.

You should see the scanner uploading analysis data to SonarQube Cloud and completing without error.

What does a successful scan look like?

The log output shows the scanner discovering your source files, analyzing them, and uploading results to SonarQube Cloud. The step finishes with a success status because the scan itself only reports findings. It does not fail the build on its own.

  • Open https://sonarcloud.io in your browser.
  • Navigate to your shafiswapnil/tetris project.

The dashboard displays your code quality metrics. You should see the quality gate status, open issues, and a duplications percentage for your project.

What am I looking at on this dashboard?

SonarQube Cloud categorizes findings into issues (bugs, code smells, security hotspots) and shows an overall quality gate status. Code smells are patterns that make your code harder to maintain. Security hotspots are areas that need manual review to confirm whether they are truly vulnerable.

Coverage and some metrics may show as zero until additional configuration is added. The important thing is that the analysis completed and your code is now being tracked.

Dashboard shows no analysis?

Make sure the workflow completed successfully in the Actions tab first. If the Trivy step failed on CRITICAL vulnerabilities, the SonarQube step never ran.

Also confirm your sonar-project.properties file is in the repository root with the correct sonar.organization and sonar.projectKey values. Help me debug why my SonarQube Cloud analysis is not showing results.

Secret mission

Add a SonarQube Quality Gate

Your pipeline scans for vulnerabilities and code smells, but it never actually blocks a merge when quality is poor. Can you add enforcement so the pipeline fails when your code does not meet SonarQube Cloud's quality standards?

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely on free-tier services for public repositories, so there are no ongoing costs. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Resources you used:

  • GitHub repository secrets (DOCKER_USERNAME, DOCKER_PASSWORD, SONAR_TOKEN).
  • Docker Hub image (tetris-app tagged with your commit SHA).
  • SonarQube Cloud project and analysis data.
  • Workflow file (.github/workflows/ci.yml) and sonar-project.properties in your repository.

Keep everything running

No action needed. Choose this if you are still actively building on your Tetris repository.

  • Your pipeline will continue to run on every push to the master branch.
  • Your GitHub secrets remain stored and encrypted.
  • SonarQube Cloud will continue analyzing your code on each pipeline run.
  • Docker Hub will accumulate new image tags with each push.

Pause - I'll come back to this later

Disable the workflow so it stops triggering on pushes. Your secrets and configuration files stay intact for when you return.

  • In your GitHub repository, click the Actions tab.
  • Click DevSecOps CI Pipeline in the left sidebar to select your workflow.
  • Click the ... menu (top-right of the workflow page) and select the option to disable the workflow.
  • Your secrets, workflow file, and SonarQube Cloud project all remain. Re-enable the workflow when you are ready to resume.

Delete - I don't want to use this again

Remove all project resources and start fresh. Follow each step below.

  • Delete your GitHub repository secrets:
  • Delete the Docker Hub image:
  • Delete the SonarQube Cloud project:
  • Remove the workflow and config files from your repository:

Nice Work!

Nice Work!

You just built a production-style DevSecOps CI pipeline that automatically builds, scans, and analyzes your Tetris Docker app on every code push. Security is now baked into your workflow, not bolted on after the fact.

You've learned how to:

  • Build a GitHub Actions CI workflow that automatically triggers on every push, building your Tetris Docker image and pushing it to Docker Hub tagged with the Git commit SHA.
  • Integrate Trivy vulnerability scanning that catches CRITICAL and HIGH severity CVEs in your container image and fails the pipeline when threats are found.
  • Connect SonarQube Cloud for static code analysis, giving you a live dashboard showing bugs, code smells, and security hotspots in your JavaScript code.
  • Secret Mission: Added a quality gate that blocks the pipeline when code quality standards are not met, enforcing DevSecOps as a hard requirement rather than an optional suggestion.

Ready to quiz yourself?