CI/CD Pipeline Setup with GitHub Actions: Automate Your Workflow from Code to Deployment

6.53K 0 0 0 0

✅ Chapter 3: Building, Testing, and Deploying Applications

🔍 Introduction

Now that you’ve learned how to create a basic GitHub Actions workflow, it’s time to move toward real-world workflows: building, testing, and deploying actual applications.

In this chapter, you will learn:

  • How to automate the build process
  • How to run various types of tests (unit, integration, e2e)
  • How to deploy to cloud providers, servers, or serverless platforms
  • Best practices for build/test/deploy stages
  • Real-world examples across different stacks

This chapter is where your pipelines come alive and start delivering real value.


🏗️ Part 1: Building Applications with GitHub Actions

Building an application involves compiling source code, bundling assets, preparing Docker images, or any preparatory steps before deployment.


🔹 Common Build Tasks by Application Type

Application Type

Build Process Example

Node.js App

npm install && npm run build

React/Vue Frontend

npm run build to create optimized static files

Java Application

maven clean install or gradle build

Python Project

Package creation with setup.py

Dockerized App

docker build commands


📋 Basic Build Job Example

yaml

 

name: Build Node App

 

on: [push]

 

jobs:

  build:

    runs-on: ubuntu-latest

    steps:

    - uses: actions/checkout@v3

    - uses: actions/setup-node@v3

      with:

        node-version: '16'

    - run: npm install

    - run: npm run build

Checks out code, installs dependencies, builds the project.


🧪 Part 2: Testing Applications with GitHub Actions

Running tests automatically is a core part of CI pipelines.


🔹 Types of Tests

Test Type

Purpose

Unit Tests

Test small pieces of code independently

Integration Tests

Test interactions between components

End-to-End (E2E)

Test entire user flows, often using tools like Cypress or Selenium


📋 Example: Running Unit Tests for Node.js

yaml

 

- name: Run unit tests

  run: npm test


🔥 Parallel Testing and Matrix Builds

Sometimes, you want to test across multiple environments:

Example

Why Important

Node.js 14/16/18

Ensure app compatibility

Python 3.8/3.9/3.10

Validate across versions

OS: Linux/Windows/MacOS

Cross-platform validation


📋 Example: Matrix Strategy

yaml

 

strategy:

  matrix:

    node-version: [14, 16, 18]

 

steps:

  - uses: actions/setup-node@v3

    with:

      node-version: ${{ matrix.node-version }}

  - run: npm test

Tests run in parallel across multiple Node versions!


🚀 Part 3: Deploying Applications with GitHub Actions

Once an application is built and tested, the next step is deployment.


🔹 Common Deployment Targets

Target

Deployment Method

AWS EC2

SSH + deployment script

AWS S3 + CloudFront

Static website deployment

Kubernetes Cluster (EKS/GKE/AKS)

kubectl apply or Helm charts

Vercel, Netlify

Dedicated GitHub Actions integrations

DockerHub

Push Docker images

Azure App Services

Publish using Azure CLI

Google Cloud Run

Deploy containerized apps


📋 Example: Deploying to an EC2 Server

yaml

 

- name: Deploy to EC2

  run: |

    ssh -o StrictHostKeyChecking=no ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }} "

      cd /var/www/app &&

      git pull origin main &&

      npm install &&

      pm2 restart app

    "

Important:

  • Use GitHub Secrets to store credentials (EC2_USER, EC2_HOST).
  • Ensure SSH keys are correctly set up.

🔹 Deploying to AWS S3 (Static Sites)

yaml

 

- name: Deploy to S3

  uses: jakejarvis/s3-sync-action@master

  with:

    args: --acl public-read --delete

  env:

    AWS_S3_BUCKET: ${{ secrets.S3_BUCKET }}

    AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}

    AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

    SOURCE_DIR: './build'

Uploads static assets to S3 automatically after a build!


📦 Best Practices for Build/Test/Deploy Stages

Best Practice

Why Important

Separate Build/Test/Deploy Jobs

Better visibility and error isolation

Use Secrets for API keys and credentials

Prevent leaks

Fail early on build or test failures

Avoid deploying broken apps

Add retry strategies for flaky deploys

Improve stability

Monitor deployment status with notifications

Faster incident response


📋 Typical Three-Stage Pipeline

text

 

[ Build ] --> [ Test ] --> [ Deploy ]

Each stage is isolated into its own job and depends on success from the previous.


🌍 Real-World Example: Full CI/CD Pipeline for Node.js App

yaml

 

name: Full Node CI/CD

 

on:

  push:

    branches: [main]

 

jobs:

  build:

    runs-on: ubuntu-latest

    steps:

    - uses: actions/checkout@v3

    - uses: actions/setup-node@v3

      with:

        node-version: 16

    - run: npm install

    - run: npm run build

 

  test:

    needs: build

    runs-on: ubuntu-latest

    steps:

    - uses: actions/checkout@v3

    - run: npm test

 

  deploy:

    needs: test

    runs-on: ubuntu-latest

    steps:

    - name: Deploy to production

      run: ssh ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }} 'bash deploy.sh'

Simple, clear, scalable pipeline.


📚 Common Pitfalls and How to Avoid Them

Pitfall

Problem

Solution

Pushing broken code to main

Deploys failures

Use protected branches and mandatory CI passing

Not caching build artifacts

Slow builds

Use actions/cache

Missing error handling in deploy scripts

Downtime risks

Implement error catching and rollback plans

Hardcoding secrets in YAML

Security vulnerability

Always use GitHub Secrets


🛤️ Recommended Next Steps After Mastering Build/Test/Deploy

  • Learn caching strategies for dependencies
  • Implement progressive deployment (blue/green, canary)
  • Integrate notifications (Slack, Teams)
  • Use approval gates before production deployment
  • Add security scanning during builds

🚀 Summary: What You Learned in Chapter 3

  • How to automate building applications using GitHub Actions
  • How to run tests (unit, integration, e2e) across environments
  • How to deploy applications to servers, cloud platforms, or static hosts
  • Best practices for robust CI/CD pipelines
  • Real-world full CI/CD example for Node.js apps


Building, testing, and deploying your application automatically isn’t just a dream anymore — it's reality with GitHub Actions!

Back

FAQs


❓1. What is GitHub Actions?

Answer: GitHub Actions is a built-in automation tool on GitHub that allows you to build, test, and deploy code directly from your repositories by defining workflows triggered by events like pushes, pull requests, and schedules.

❓2. What are the basic components of a GitHub Actions workflow?

Answer: A GitHub Actions workflow consists of workflows, jobs, steps, and actions:

  • Workflows define the entire pipeline.
  • Jobs are sets of steps that run sequentially or in parallel.
  • Steps are individual tasks like running commands.
  • Actions are pre-built reusable tasks.

❓3. How do I trigger a workflow in GitHub Actions?

Answer: Workflows can be triggered by:

  • Events (e.g., push, pull_request)
  • Scheduled times (cron jobs)
  • Manual triggers (workflow_dispatch)
  • Repository dispatches from external systems

❓4. Can I deploy applications automatically using GitHub Actions?

Answer: Yes! GitHub Actions can automate deployments to servers, Kubernetes clusters, serverless platforms, or cloud providers like AWS, Azure, and GCP after successful builds and tests.

❓5. How do I securely manage secrets like API keys or passwords in GitHub Actions?

Answer: GitHub provides a Secrets management system where sensitive data (like API keys, credentials) can be stored and injected into workflows securely without exposing them in code.

❓6. What types of environments can I run GitHub Actions workflows on?

Answer: GitHub Actions supports runners on:

  • Ubuntu Linux (ubuntu-latest)
  • Windows (windows-latest)
  • macOS (macos-latest) You can also set up self-hosted runners on your own infrastructure.

❓7. What is the benefit of using caching in GitHub Actions workflows?

Answer: Caching (using actions/cache) helps store and reuse dependencies between workflow runs, significantly reducing build times and improving pipeline efficiency.

❓8. How can I create multi-environment CI/CD workflows (e.g., dev, staging, prod)?

Answer: You can create separate jobs or workflows for each environment and control them with conditions (e.g., branch filters like if: github.ref == 'refs/heads/prod') or use manual approvals for deployment jobs.

❓9. Can I run tests across multiple versions of a programming language simultaneously?

Answer: Yes! You can use matrix builds in GitHub Actions to test your application across multiple versions (e.g., Node.js 14, 16, and 18) at the same time, improving compatibility and quality assurance.

❓10. Is GitHub Actions free to use?

Answer: GitHub Actions offers free usage with limits based on your account type:

  • Public repositories: Free unlimited usage
  • Private repositories: Free minutes with limits depending on GitHub plan (Free, Pro, Team, Enterprise); extra usage may incur costs.