CI/CD Pipeline with GitHub Actions: Complete Setup Guide
CI/CD Pipeline with GitHub Actions: Complete Setup Guide
In modern software development, manually testing code and running deployment scripts after every change is a bottleneck that slows delivery and introduces human error. A CI/CD pipeline automates this entire process, from testing code to deploying it to production. This guide will teach you how to set up ci cd pipeline with github actions, a powerful and integrated automation platform, using practical, real-world YAML examples so you can ship code faster and more reliably.
What You'll Learn
By the end of this guide, you'll understand the core concepts of Continuous Integration and Continuous Deployment (CI/CD) and be able to implement a multi-stage pipeline using GitHub Actions. You'll learn how to write workflows for automated testing, building Docker images, and deploying applications. You'll walk away with working YAML code for testing, building, and deploying your own projects, whether they're Python, Node.js, or containerized applications.
Understanding GitHub Actions Fundamentals
GitHub Actions is an event-driven automation platform integrated directly into GitHub repositories. It allows you to run automated workflows triggered by events like push, pull_request, or release . At its core, a workflow is defined in a YAML file located in the .github/workflows/ directory and consists of one or more jobs that run in parallel by default, each containing a series of steps .
Core Components
- Event (
on): The trigger that initiates the workflow, such aspushto a specific branch or apull_request. - Runner (
runs-on): The machine where the job executes.ubuntu-latestis the most common and recommended choice for its performance and wide software availability . - Steps: Individual tasks within a job. These can be shell scripts (
run) or pre-built Actions (uses) from the GitHub Marketplace . - Actions: Reusable units of code, like
actions/checkout@v4to clone your repository oractions/setup-node@v4to install Node.js .
A Basic Workflow to Get Started
The simplest workflow can be triggered with every push. Create a file at .github/workflows/main.yml to run a basic "Hello World" command .
name: example
on: push
jobs:
greeting:
runs-on: ubuntu-latest
steps:
- run: echo "Hello, CI/CD World!"
After committing and pushing this file to your repository, you can view the job's output in the "Actions" tab of your GitHub repository.
Building a Comprehensive CI Pipeline
The "CI" part of a pipeline ensures that code changes are automatically tested and verified before they are merged. This typically involves linting, type-checking, and running unit tests.
The CI Workflow File
Create .github/workflows/ci.yml. This workflow triggers on every push and pull_request to the main branch . The example below demonstrates a complete pipeline for a Node.js project, but the pattern applies to other languages, such as Python with actions/setup-python .
name: CI Pipeline
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm test
build:
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
Key Features Explained
- Dependency Caching: The
cache: 'npm'option inactions/setup-nodesignificantly speeds up the workflow by reusing dependencies from previous runs . - Job Dependencies: The
needskeyword defines the order of execution. For example, thebuildjob only runs if thelintandtestjobs succeed . This prevents wasting time building broken code. - Environment Variables: For services like databases, you can define environment variables. For instance, a
testjob can spin up a PostgreSQL service container and useenvto connect to it .
Advanced Scenarios: Containerized and Multi-Environment Deployments
For modern applications, the pipeline often involves building container images and deploying them. The following table outlines common deployment strategies and their triggers.
Comparison of Deployment Triggers
| Strategy | Deployment Triggers | Best For |
|---|---|---|
| Branch-Based | push to main |
Continuous deployment of the latest development code . |
| Tag-Based | push of a new tag (e.g., v1.0.0) |
Releasing stable, versioned software to production . |
| Release-Based | release published on GitHub |
Official product releases that also generate release notes . |
Example: Deploying a Docker Container with a CI/CD Workflow
This comprehensive example demonstrates a pipeline that tests a Python application, builds a Docker image, and pushes it to a registry . It uses a series of official Docker Actions for a secure, high-performance build.
Create .github/workflows/deploy.yml:
name: Complete CI/CD Pipeline
on:
push:
branches: [ main ]
release:
types: [published]
env:
DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }}
DOCKER_HUB_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }}
IMAGE_NAME: my-app
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.9'
- run: pip install -r requirements.txt
- run: pytest
build-and-push:
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'push' || github.event_name == 'release'
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ env.DOCKER_HUB_USERNAME }}
password: ${{ env.DOCKER_HUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.DOCKER_HUB_USERNAME }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy:
runs-on: ubuntu-latest
needs: build-and-push
if: github.event_name == 'release'
steps:
- name: Execute Deployment Script
run: |
echo "Deploying image ${{ env.DOCKER_HUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }}"
Important: Secrets Management
For the workflow above to work, you must store your credentials securely in your GitHub repository. Navigate to Settings > Secrets and variables > Actions and add the following secrets :
DOCKER_HUB_USERNAME: Your Docker Hub username.DOCKER_HUB_TOKEN: A Docker Hub Personal Access Token with read/write permissions.
⚠️ Security Warning: Never hardcode passwords, tokens, or other sensitive data directly in your YAML files. Always use GitHub secrets, which are encrypted and only accessible during workflow runs.
Sources
- Set up GitHub Actions CI/CD pipeline · Issue #176 (Practical YAML examples for CI, E2E, and deploy)
- DevOps: Set up GitHub Actions CI/CD pipeline · Issue #19 (Demonstrates linting, type-checking, and build verification)
- GitHub - kamrun111/GitHubActionTest (A simple, beginner-friendly Python CI/CD example)
- @jamesives/github-pages-deploy-action (Documentation for deploying to GitHub Pages)
- GitHub - CarlosQuintero8/cicdsimulation (Demonstrates a multi-stage pipeline with testing, building, and deployment to GitHub Pages)
- GitHub - anuragstark/Py-app-CI-CD-Pipeline- (Comprehensive guide including Docker and Minikube deployment)
- Automated CI/CD with GitHub Actions, starting from scratch (A walkthrough on incrementally building CI/CD workflows)
- Extend App with GitHub Actions · AccelByte Documentation (Example of deployment triggered by a release event)
- Configure CI/CD for your C++ application · Docker Docs (Demonstrates setting up GitHub Actions with Docker Hub)
- Hello CI World · HSF Training (A basic tutorial for creating and running a first workflow)
— Editorial Team
No comments yet.