GitHub Actions
GitHub Actions is GitHub's built-in automation platform. It allows creation of automated workflows that run when specific events happen in a repository — such as when code is pushed, a pull request is opened, or a release is created.
The most common use of GitHub Actions is to implement CI/CD:
- CI (Continuous Integration) — Automatically test and build the code every time someone pushes changes, catching bugs early
- CD (Continuous Deployment) — Automatically deploy the application to a server or hosting service after successful tests
Real-life analogy: Think of GitHub Actions like a personal assistant who springs into action every time code is submitted. The assistant automatically checks the work (runs tests), builds the project (compiles), and if everything passes, delivers it to the customer (deploys). This happens without any manual effort.
Key Concepts
Workflow
A workflow is an automated process defined in a YAML file stored in the .github/workflows/ folder of the repository. A repository can have multiple workflow files for different purposes.
Event
An event is what triggers a workflow. Common events include: pushing code (push), opening a pull request (pull_request), creating a release (release), or running manually (workflow_dispatch).
Job
A workflow contains one or more jobs. Each job is a set of steps that run on a virtual machine (called a runner). Jobs run in parallel by default, but can be configured to run sequentially.
Step
Each job contains steps. A step either runs a shell command or uses a pre-built Action (a reusable piece of automation from the GitHub Marketplace).
Runner
A runner is a virtual machine provided by GitHub where jobs run. Available runners include Ubuntu, Windows, and macOS. GitHub provides free minutes on these runners for public repositories and a limited amount for free private repositories.
Workflow File Structure
Workflow files are written in YAML and placed in .github/workflows/:
.github/
└── workflows/
├── ci.yml ← Runs tests on every push
├── deploy.yml ← Deploys on merge to main
└── codecheck.yml ← Runs linter on pull requests
Basic Workflow Example — Run Tests on Every Push
# .github/workflows/ci.yml
name: Run Tests
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout the code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
Breaking Down This Workflow
| Section | Explanation |
|---|---|
name: | The display name of this workflow (shown in GitHub UI) |
on: | When this workflow triggers — on push to main/develop and on PRs to main |
jobs: | Defines the jobs in this workflow |
runs-on: ubuntu-latest | The job runs on the latest Ubuntu virtual machine |
uses: actions/checkout@v4 | A pre-built Action that clones the repository into the runner |
run: | Executes a shell command on the runner |
Workflow Example — Deploy to GitHub Pages
# .github/workflows/deploy.yml
name: Deploy to GitHub Pages
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install and Build
run: |
npm install
npm run build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
Common Trigger Events
| Event | When it Triggers |
|---|---|
push | When code is pushed to a branch |
pull_request | When a PR is opened, updated, or merged |
release | When a GitHub Release is published |
schedule | On a time-based schedule (cron syntax) |
workflow_dispatch | Manual trigger from the GitHub UI |
issues | When an issue is opened, closed, or labeled |
Using Secrets in Workflows
Sensitive information like API keys, passwords, and tokens should NEVER be hardcoded in workflow files. GitHub Secrets provide a secure way to store and access them:
Adding a Secret
- Go to the GitHub repository
- Click Settings → Secrets and variables → Actions
- Click "New repository secret"
- Enter a name and value
Using a Secret in a Workflow
- name: Deploy to server
run: ./deploy.sh
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
Jobs Running in Sequence (Dependency)
Jobs run in parallel by default. Use needs to make one job wait for another:
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: npm test
deploy:
runs-on: ubuntu-latest
needs: test ← Only runs if "test" job passes
steps:
- run: npm run deploy
Viewing Workflow Results
In the GitHub repository, click the "Actions" tab to see:
- All workflow runs and their status (passed/failed/in progress)
- Detailed logs for each step in every job
- How long each run took
- Artifacts (files) produced by workflows
If any step fails, a red ✗ appears. Clicking it shows the exact error output from the terminal.
Manually Triggering a Workflow
For workflows with workflow_dispatch:
- Go to the Actions tab
- Click the workflow name
- Click "Run workflow"
- Select the branch and click "Run workflow"
GitHub Actions Free Tier Limits
| Account Type | Free Minutes/Month |
|---|---|
| Public repositories | Unlimited |
| Free GitHub account (private repos) | 2,000 minutes |
| GitHub Pro (private repos) | 3,000 minutes |
Summary
GitHub Actions automates testing, building, and deployment directly within GitHub. Workflows are YAML files in .github/workflows/ that define when to run (events), where to run (runners), and what to do (jobs and steps). Use pre-built Actions from the GitHub Marketplace to avoid reinventing common tasks. Store sensitive data in GitHub Secrets. The Actions tab provides full visibility into every workflow run and its detailed logs.
