GitHub Actions Explained: A Practical Guide

GitHub Actions automates work around a repository, such as running tests when code changes or building an application after a push. This guide explains workflows, events, jobs, steps, actions, and runners, then walks through a small continuous integration (CI) example.

Practice Git workflows →

What is GitHub Actions?

GitHub Actions is a platform for automating repository workflows. You define automation in YAML files stored in the repository, and GitHub runs those workflows when configured events occur. The same system can run tests, check formatting, publish packages, or perform deployment tasks, depending on how it is configured.

A workflow is not automatically safe or correct just because it passes once. Its behavior depends on its triggers, permissions, environment, and the code it runs. Start with a small workflow and review what each step can access.

GitHub Actions concepts: workflows, jobs, and steps

Where GitHub Actions workflow files live

Add a YAML file with a .yml or .yaml extension to .github/workflows/. For example:

.github/workflows/ci.yml

Each workflow file should describe a focused automation. Keeping test, release, and deployment workflows understandable makes it easier to see why a run started and what it can do.

A simple GitHub Actions CI workflow example

This example runs when code is pushed to mainor a pull request targets that branch. It checks out the repository, sets up Node.js, installs dependencies with the lockfile, and runs the project's test script:

name: Node CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Check out repository
        uses: actions/checkout@v4
      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
      - name: Install dependencies
        run: npm ci
      - name: Run tests
        run: npm test

Save the file, commit it, and push it to GitHub. Open the repository's Actions tab to view the workflow run and its logs. Replace the Node.js version and commands with versions and scripts supported by your project. For a non-Node.js project, use the matching setup and test commands.

How GitHub Actions triggers and runs a workflow

  1. An event matching the workflow's on configuration occurs.
  2. GitHub creates a workflow run and evaluates which jobs should run.
  3. Each job is assigned to a compatible runner. Jobs without dependencies can run at the same time.
  4. The runner executes the job's steps in order and reports success or failure in the Actions interface.

By default, steps in one job share the same runner, while separate jobs can use separate runners. Use job dependencies when one job needs another to finish first; do not assume files created by one job are automatically available in another.

GitHub Actions best practices for secrets and permissions

Common GitHub Actions problems

The workflow does not start

Confirm the file is under .github/workflows/, has valid YAML, and includes an event that matches what happened. Check branch filters and the Actions tab for status or policy restrictions.

A command works locally but fails in CI

Compare the runner's operating system, runtime version, environment variables, and installed dependencies with your local setup. Prefer lockfile-based installation and document required configuration without committing secret values.

A job fails without a clear reason

Open the failed job and expand the step that reported an error. Read the first relevant failure in the logs; later errors may only be consequences of that earlier problem.

When should you use GitHub Actions?

Use Actions when an automated check or repeatable repository task saves time and reduces missed steps. A small CI workflow that validates every change is a useful starting point. For related GitHub repository basics, read how to write a GitHub README.

Learn Git Faster by Practicing

Reading is just the first step. Real learning happens when you practice.

Start Learning Git →