CI/CD Basics: Building Your First Pipeline with GitHub Actions
Continuous Integration and Continuous Deployment (CI/CD) have become essential practices in modern software development. They help teams automate testing, streamline deployments, and deliver features faster with fewer issues. Among the many CI/CD tools available today, GitHub Actions stands out because it’s integrated directly into GitHub, easy to adopt, and flexible for nearly any workflow.
If you’re new to DevOps or just getting started with automation, this guide will walk you through CI/CD fundamentals and how to build your very first pipeline using GitHub Actions.
What Is CI/CD?
Continuous Integration (CI)
CI is the practice of automatically building and testing your code every time you push changes to your repository. The goal is to detect bugs early and ensure the codebase remains stable.
Continuous Deployment (CD)
CD extends CI by automatically deploying your application whenever changes pass all tests. This helps teams deliver new features quickly and reliably.
Together, CI/CD forms the backbone of modern DevOps workflows.
Why Use GitHub Actions for CI/CD?
GitHub Actions offers several advantages that make it a great choice for beginners:
- Native GitHub integration: Works directly with your repository—no extra setup needed.
- Easy to use: YAML-based workflows with clear structure.
- Reusable actions: Thousands of community and official actions are available in the GitHub Marketplace.
- Supports any language or framework: Node.js, Python, Java, Go, Docker, and more.
- Free usage limits: Great for personal projects or small teams.
Key Concepts in GitHub Actions
Before building your pipeline, it helps to understand the core components:
1. Workflows
A workflow is an automated process defined in a YAML file stored inside .github/workflows/.
Each workflow can contain multiple jobs and triggers.
2. Triggers (Events)
Workflows run in response to certain events, such as:
pushpull_requestschedule(cron)workflow_dispatch(manual trigger)
Example:
on: [push]
3. Jobs
A job is a group of steps that run on the same virtual machine.
Example:
jobs:
build:
runs-on: ubuntu-latest
4. Steps
Each job contains steps that execute commands or call ready-made actions.
Example:
steps:
- name: Checkout code
uses: actions/checkout@v4
Building Your First CI Pipeline with GitHub Actions
In this example, we’ll create a simple CI pipeline that:
- Runs whenever code is pushed
- Checks out the repository
- Sets up the programming environment
- Installs dependencies
- Runs tests
This workflow works for many standard projects.
Step 1: Create the Workflow File
Inside your GitHub repository, create this folder structure:
.github/
└── workflows/
└── ci.yml
Step 2: Add the Basic Workflow Content
Here is a simple but production-ready CI workflow:
name: CI Pipeline
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: "21"
- name: Build project
run: mvn -B package --file pom.xml
- name: Run tests
run: mvn test
This example uses a Java/Maven project, but the structure is similar for Node.js, Python, Go, or Docker-based projects.
Understanding the Workflow
Let’s break down what this pipeline actually does:
Trigger
The workflow runs on:
- Every push to the
mainbranch - Every pull request targeting
main
Runner
ubuntu-latest provides a hosted virtual machine with:
- Git
- Docker
- Java, Node.js, Python
- Build tools
Steps
- Checkout code
Pulls the latest version of your repository into the runner. - Setup environment
Here we configure Java 21 using official actions. - Build
Compiles the project using Maven. - Test
Runs unit tests to validate code quality.
Adding Continuous Deployment (CD)
If you want to extend your CI pipeline with deployment, GitHub Actions makes it simple.
Below is an example for deploying to a server using SSH:
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Copy files to server
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_KEY }}
source: "target/*.jar"
target: "/opt/app/"
By placing your server credentials inside GitHub Secrets, the pipeline can securely deploy your application.
Best Practices for GitHub Actions Pipelines
1. Use GitHub Secrets
Never hardcode passwords or keys—store them securely in:
Settings → Secrets → Actions
2. Cache Dependencies
Use caching to speed up builds:
- uses: actions/cache@v4
with:
path: ~/.m2
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
3. Use Separate Jobs
Split CI and CD stages for clarity and failure isolation.
4. Define Environment Protection Rules
Require approvals before deploying to production.
5. Add Status Badges
CI badges help team members see pipeline status at a glance.
Common Issues and How to Fix Them
1. Workflow Not Triggering
Check if your workflow file is inside:
.github/workflows/
2. Build Fails on Runner but Works Locally
Ensure:
- consistent Java/Node versions
- correct dependency installation
- working directory paths
3. Permission Errors
Verify that Secrets and SSH keys are correctly configured.
Conclusion
GitHub Actions makes CI/CD accessible, powerful, and tightly integrated with your source code. With just a few lines of YAML, you can automate builds, run tests, and deploy applications efficiently.
For developers and DevOps beginners, building your first CI pipeline with GitHub Actions opens the door to cleaner workflows, faster development cycles, and more reliable deployments.
Once you’ve mastered the basics, you can expand your pipelines with caching, matrix builds, Docker actions, environment approvals, and advanced deployment strategies.











