GitHub Actions Introduction
GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform built directly into GitHub. It lets you automate your software workflows — running tests on every pull request, building Docker images on merge, deploying to production on release — without leaving GitHub or paying for a separate CI service.
What problem does GitHub Actions solve?
Before CI/CD, teams would manually run tests before merging, forget to run them, or deploy untested code. GitHub Actions automates these repetitive processes: every time someone pushes code, a defined workflow runs automatically, giving instant feedback on whether the code is healthy.
Run tests on every push and pull request.
Block merging if tests fail.
Build and publish Docker images or npm packages on release.
Deploy to cloud providers (AWS, GCP, Azure, Vercel, Netlify) automatically.
Send Slack notifications when a deploy succeeds or fails.
Auto-label issues, assign reviewers, close stale PRs.
Key concepts
Concept | Description | Analogy |
|---|---|---|
Workflow | An automated process defined in a YAML file | A recipe |
Job | A set of steps that run on the same machine | A chapter in the recipe |
Step | A single command or action inside a job | One instruction in the recipe |
Action | A reusable plugin (shared step) from the marketplace | A pre-made ingredient |
Runner | The virtual machine that executes the job | The kitchen |
Event | What triggers the workflow (push, PR, schedule, etc.) | The alarm clock that starts cooking |
Artifact | Files uploaded during a workflow for later download | The finished dish |
Secret | Encrypted environment variable (API keys, tokens) | The safe in the kitchen |
The .github/workflows/ directory
GitHub Actions workflows live in .github/workflows/ in the root of your repository. Each YAML file in this directory is a separate workflow. You can have as many as you need.
Typical project structure
your-project/ ├── .github/ │ └── workflows/ │ ├── ci.yml ← runs tests on every push/PR │ ├── release.yml ← publishes package on tag push │ └── codeql.yml ← security scanning on schedule ├── src/ ├── package.json └── README.md
Trigger events
The on: key in a workflow file defines what events trigger it. You can combine multiple triggers in one workflow.
Common trigger events
on:
# Trigger on push to any branch
push:
branches: ['**']
# Trigger on push to main or release branches only
push:
branches: [main, 'release/**']
# Trigger on pull request targeting main
pull_request:
branches: [main]
# Run on a schedule (cron syntax — every day at 2am UTC)
schedule:
- cron: '0 2 * * *'
# Allow manual trigger from the GitHub UI or API
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
required: true
default: 'staging'
# Trigger when another workflow completes
workflow_run:
workflows: ['CI']
types: [completed]A minimal workflow example
.github/workflows/hello.yml
name: Hello World
on:
push:
branches: [main]
jobs:
greet:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Print a greeting
run: echo "Hello from GitHub Actions!"YAML syntax overview
Annotated workflow anatomy
name: CI # Display name in GitHub UI
on: # Trigger events
push:
branches: [main]
pull_request:
branches: [main]
env: # Workflow-level environment variables
NODE_VERSION: '20'
jobs:
test: # Job ID (can be any identifier)
name: Run tests # Display name in GitHub UI
runs-on: ubuntu-latest # Runner OS
steps:
- uses: actions/checkout@v4 # Built-in checkout action
- name: Setup Node.js
uses: actions/setup-node@v4 # Action from marketplace
with: # Action inputs
node-version: ${{ env.NODE_VERSION }}
- name: Install dependencies
run: npm ci # Shell command
- name: Run tests
run: npm test
- name: Upload coverage
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/Using marketplace actions
The GitHub Marketplace has thousands of pre-built actions. Search at github.com/marketplace?type=actions. Common ones you will use immediately:
Action | Purpose | Usage |
|---|---|---|
actions/checkout@v4 | Clone the repository into the runner | Every workflow needs this |
actions/setup-node@v4 | Install Node.js | Node.js projects |
actions/setup-python@v5 | Install Python | Python projects |
actions/setup-java@v4 | Install JDK | Java/Kotlin projects |
actions/cache@v4 | Cache dependencies between runs | Speed up installs |
actions/upload-artifact@v4 | Save files from the run | Test results, builds |
actions/download-artifact@v4 | Download saved files in another job | Multi-job pipelines |
github/codeql-action | Static security analysis | Security scanning |
GitHub Actions vs other CI/CD platforms
Feature | GitHub Actions | GitLab CI | CircleCI | Jenkins |
|---|---|---|---|---|
Hosting | github.com | gitlab.com or self-hosted | circleci.com | Self-hosted |
Config file | .github/workflows/*.yml | .gitlab-ci.yml | .circleci/config.yml | Jenkinsfile |
Free tier (private repos) | 2,000 min/month | 400 min/month | 6,000 min/month | Free (self-hosted) |
Public repo minutes | Unlimited | Unlimited | Unlimited | Unlimited |
Marketplace actions | Yes (GitHub Marketplace) | No (use scripts) | Orbs | Plugins |
Matrix builds | Yes | Yes | Yes | Yes (via plugins) |
Self-hosted runners | Yes | Yes (GitLab Runners) | Yes | Built-in |
Code review integration | Native GitHub PRs | Native GitLab MRs | GitHub/Bitbucket | Plugins required |
Learning curve | Low | Low-Medium | Medium | High |
Free tier details
Public repositories: unlimited minutes on GitHub-hosted runners.
Private repositories: 2,000 minutes/month on the Free plan.
Pro plan: 3,000 minutes/month.
Team plan: 3,000 minutes/month.
Storage for artifacts and packages: 500 MB on Free plan.
Ubuntu runners are billed at 1x, Windows at 2x, macOS at 10x minute multipliers.
Self-hosted runners are always free — you pay only for the hardware.
Viewing workflow results
Once a workflow runs, results appear in multiple places on GitHub:
Repository → Actions tab: full list of workflow runs with logs.
Pull request → Checks section: inline pass/fail status for each job.
Commit page → status icon (green check or red X) next to the commit hash.
Branch protection settings can require specific checks to pass before merging.
Next steps
Write your first workflow: see Writing GitHub Actions Workflows.
Store API keys safely: see GitHub Actions Secrets.
Deploy automatically: see Automated Deployment with Git.