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
- Workflow: The complete automation described in a YAML file under
.github/workflows/. - Event: Something that triggers a workflow, such as a push, a pull request, or a schedule.
- Job: A group of steps executed on a runner. Jobs can run in parallel by default or be ordered with dependencies.
- Runner: The machine environment that executes a job, such as a GitHub-hosted Linux runner or a self-hosted runner you manage.
- Step: An individual command or reusable action run as part of a job.
- Action: A reusable unit of automation that a workflow step can call, often maintained in a repository or published for reuse.
Where GitHub Actions workflow files live
Add a YAML file with a .yml or .yaml extension to .github/workflows/. For example:
.github/workflows/ci.ymlEach 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 testSave 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
- An event matching the workflow's
onconfiguration occurs. - GitHub creates a workflow run and evaluates which jobs should run.
- Each job is assigned to a compatible runner. Jobs without dependencies can run at the same time.
- 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
- Set only the permissions a workflow needs. The example uses read-only repository content access for CI.
- Store credentials in GitHub Actions secrets or an appropriately protected environment, not directly in YAML or source code.
- Avoid printing secrets in logs, and do not assume masking makes unsafe handling acceptable.
- Review third-party actions before using them and keep dependencies maintained. For higher assurance, pin actions to reviewed immutable commit SHAs using your organization's update process.
- Be careful with workflows that handle untrusted pull request code. In particular, do not expose privileged secrets or write permissions to untrusted code.
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.