GitGitHub Actions Introduction

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

Bash
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

YAML
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

YAML
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!"
runs-on
`ubuntu-latest` is the most common runner. GitHub also provides `windows-latest` and `macos-latest`. You can also self-host runners on your own servers.
YAML syntax overview

Annotated workflow anatomy

YAML
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.

Tip
Pin the Actions tab in your browser and check it after every push while learning. The workflow logs are very detailed and will tell you exactly which step failed and why.
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.