GitHub Actions CI/CD Tutorial 2026: From Zero to Automated Deployments
GitHub Actions is the easiest and most integrated way to set up CI/CD in 2026. Built directly into GitHub, it lets you automate testing, building, and deployment using YAML workflow files stored in your repository. This tutorial takes you from zero — no prior CI/CD knowledge — to fully automated deployments in a production environment.
Continuous Integration and Continuous Deployment (CI/CD) is the backbone of modern software delivery. In 2026, teams that deploy manually are losing to teams that deploy 10–50 times per day with automation. GitHub Actions has become the default CI/CD choice for startups and mid-size companies, while enterprises increasingly adopt it alongside or instead of Jenkins. This tutorial is your complete guide.
What Is GitHub Actions?
GitHub Actions is an event-driven automation platform built directly into GitHub. When something happens in your repository — a push, a pull request, a tag — GitHub Actions can automatically run a series of steps: install dependencies, run tests, build a Docker image, deploy to a server. Everything is configured in YAML files stored in .github/workflows/ inside your repository.
Key Concepts You Must Understand
| Concept | What It Is | Example |
|---|---|---|
| Workflow | A YAML file defining automation | .github/workflows/ci.yml |
| Trigger (on:) | Event that starts the workflow | push, pull_request, schedule |
| Job | A group of steps running on one runner | test, build, deploy |
| Step | A single command or action within a job | npm install, pytest, docker push |
| Runner | The server that executes the workflow | ubuntu-latest, self-hosted |
| Action | Reusable step from the marketplace | actions/checkout@v4 |
| Secret | Encrypted variable stored in GitHub | ${{ secrets.AWS_SECRET_KEY }} |
Workflow 1: Run Tests on Every Pull Request
This is the most fundamental CI workflow — automatically run your test suite whenever someone opens or updates a pull request. This prevents broken code from being merged.
Python / pytest example
# .github/workflows/python-ci.yml
name: Python CI
on:
pull_request:
branches: [ main, develop ]
push:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-cov
- name: Run tests with coverage
run: |
pytest tests/ --cov=src --cov-report=xml --cov-fail-under=80
- name: Upload coverage report
uses: codecov/codecov-action@v4
with:
file: coverage.xml
Node.js / Jest example
# .github/workflows/node-ci.yml
name: Node.js CI
on:
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x, 20.x]
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run build --if-present
- run: npm test
Workflow 2: Deploy to Production on Merge to Main
This workflow runs only when code is merged to main — first running tests, then deploying if tests pass. This is the core CD pattern.
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install -r requirements.txt && pytest tests/
deploy:
needs: test # Only runs if test job succeeds
runs-on: ubuntu-latest
environment: production # Requires manual approval if configured
steps:
- uses: actions/checkout@v4
- name: Deploy to server via SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /var/www/myapp
git pull origin main
pip install -r requirements.txt
sudo systemctl restart myapp
echo "Deployment complete!"
Workflow 3: Build and Push Docker Image to Docker Hub
# .github/workflows/docker-build-push.yml
name: Build and Push Docker Image
on:
push:
branches: [ main ]
tags: [ 'v*.*.*' ] # Trigger on version tags like v1.2.3
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout
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: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: yourusername/your-app-name
- 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
Secrets Management: Storing Credentials Securely
Never hardcode API keys, passwords, or private keys in your workflow files. GitHub Actions Secrets encrypt values and make them available as environment variables in your workflow without exposing them in logs.
- Go to your GitHub repository → Settings → Secrets and variables → Actions
- Click “New repository secret”
- Enter a name (e.g.,
AWS_ACCESS_KEY_ID) and the value - Reference in workflow:
${{ secrets.AWS_ACCESS_KEY_ID }}
For environment-specific secrets (staging vs production), use GitHub Environments. This also enables required reviewer approvals before production deployments.
GitHub Actions vs Jenkins vs CircleCI vs GitLab CI
| Tool | Hosting | Setup Effort | Free Tier | Best For |
|---|---|---|---|---|
| GitHub Actions | GitHub cloud | Zero | 2,000 min/month | Teams already on GitHub |
| Jenkins | Self-hosted | High | Free (self-host costs) | Large enterprises, legacy |
| CircleCI | Cloud/self-hosted | Low | 6,000 min/month | Fast builds, Docker teams |
| GitLab CI | GitLab cloud/self-hosted | Low | 400 min/month | Teams on GitLab |
GitHub Actions wins on simplicity and integration for teams already hosting code on GitHub. Jenkins wins for total customisation in complex enterprise environments. For learning and building a portfolio, GitHub Actions is the clear starting point.
GitHub Actions Pricing in 2026
- Public repositories: Unlimited free minutes on GitHub-hosted runners
- Private repositories — Free plan: 2,000 minutes/month (Linux runners)
- Private repositories — Pro/Team plan: 3,000–50,000 minutes/month
- Self-hosted runners: Free — you provide the compute (EC2, VPS, on-prem)
- Linux runners are cheapest; Windows runners cost 2x; macOS runners cost 10x the Linux rate
CI/CD Knowledge and QA Career in India
CI/CD is now a core competency for QA engineers, not just DevOps engineers. In 2026, QA engineers who can write GitHub Actions workflows to automate their test suites command significantly higher salaries:
- QA Engineer without CI/CD skills: ₹6–10 LPA
- QA Automation Engineer with CI/CD (GitHub Actions / Jenkins): ₹12–18 LPA
- SDET with full CI/CD pipeline ownership: ₹18–28 LPA
The ability to integrate automated tests into a CI/CD pipeline — so that every PR is tested automatically before merge — is the skill that separates junior QA engineers from senior ones. It is a core module in GROWAI’s QA Automation course.
Learn CI/CD with GitHub Actions — GROWAI QA Automation Program
GROWAI’s QA Automation course covers GitHub Actions CI/CD end-to-end: writing workflows, running Playwright tests on PR, deploying on merge, managing secrets, and setting up test reporting. Build the pipeline skills every SDET role requires.
Frequently Asked Questions
1. Is GitHub Actions free?
GitHub Actions is free for public repositories with unlimited minutes. For private repositories, the free plan includes 2,000 minutes/month. Self-hosted runners are always free — you pay only for the server you run them on. Most small teams and individual developers can run CI/CD entirely within the free tier.
2. How do I trigger a deployment with GitHub Actions?
Use the push trigger with a specific branch in your workflow YAML: on: push: branches: [main]. When code is merged to main, the workflow fires. Add a needs: test dependency on your deploy job so deployment only happens if tests pass. For controlled deployments, use GitHub Environments with required reviewers.
3. GitHub Actions vs Jenkins — which is better in 2026?
GitHub Actions is better for most teams in 2026 because setup is zero, maintenance is zero (GitHub manages the infrastructure), and YAML syntax is beginner-friendly. Jenkins is better when you need complete control over build infrastructure, have existing Jenkins pipelines at scale, or work in an enterprise that cannot use cloud services for compliance reasons.
4. Can I run GitHub Actions on my own server?
Yes. Self-hosted runners allow you to run GitHub Actions workflows on your own servers — a VPS, an EC2 instance, or an on-premises machine. This is useful for accessing private networks, running GPU workloads, or saving costs on long-running jobs. Install the runner agent, register it with your repository, and specify runs-on: self-hosted in your workflow.
5. How do I run Playwright tests in GitHub Actions?
Add a step that installs Playwright and its browser binaries, then runs your tests. The official Playwright Docker image or the ms-playwright/playwright action handles browser installation automatically. Use the upload-artifact action to save HTML test reports as downloadable artifacts after the run for debugging failed tests.
6. What are GitHub Actions matrix builds and when should I use them?
Matrix builds let you run the same job across multiple configurations simultaneously — for example, testing against Python 3.10, 3.11, and 3.12 in parallel, or testing on Ubuntu and Windows at the same time. Use matrix builds when your software needs to support multiple versions of a language, framework, or operating system. They multiply your test coverage without manual duplication of workflow steps.