GitHub Actions: Your First CI Workflow
Introduction
GitHub Actions is a built-in automation service: it runs workflows in response to events in your repository, such as a push or a pull request. The most common first workflow is continuous integration, which installs dependencies and runs your tests automatically. This lesson builds one from scratch.
Prerequisites
- A GitHub repository with a project that has tests (Node.js is used here)
- Git basics
Step-by-Step Guide
Step 1: Learn the vocabulary
A workflow is an automated process defined in a YAML file. It is triggered by events and contains one or more jobs. A job is a set of steps that runs on one runner, a machine provided by GitHub. A step either runs a shell command or uses an action, a reusable unit published by others. Jobs run in parallel by default.
Step 2: Create the workflow file
Workflow files live in the .github/workflows folder of your repository and must end in .yml or .yaml. Create ci.yml with this content. The runner label ubuntu-latest currently points at Ubuntu 24.04. GitHub announces changes to what -latest means ahead of time, but you can pin an exact label such as ubuntu-24.04 if you need to avoid surprises.
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm testStep 3: Understand each part
The on section lists the triggers: here, pushes to main and any pull request. The permissions block limits what the automatic GITHUB_TOKEN may do, and read access to contents is enough for a test job. actions/checkout downloads your code onto the runner, setup-node installs Node.js and caches npm downloads, and npm ci installs exact dependency versions from your lock file. A failing step fails the job, and the commit gets a red mark.
Step 4: Push and read the results
Commit and push the file. Open the Actions tab of your repository to see the run, click it to see the job, and expand each step to read its log. On a pull request, the result appears as a check next to the merge button, and combined with branch protection you can require it to pass before merging.
git add .github/workflows/ci.yml
git commit -m "Add CI workflow"
git pushStep 5: Do the same for Python
The structure is identical for other languages: check out the code, set up the language with caching, install dependencies, and run the tests. Always check the action's README for the current major version tag, because actions release new majors regularly, and consider letting Dependabot propose updates.
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.13"
cache: pip
- run: pip install -r requirements.txt
- run: pytestFAQs
- How much does GitHub Actions cost?
- Public repositories get free usage on GitHub-hosted runners, and private repositories get an included monthly allowance that depends on your plan. Check GitHub's current pricing page for the exact limits.
- Why did my workflow not run?
- Common causes are the file being in the wrong folder, YAML indentation errors, or the trigger not matching the event, for example pushing to a branch that is not listed under push branches.
Summary
A CI workflow is a YAML file in .github/workflows with triggers, a job, and steps that check out code, set up the language, install dependencies, and run tests. Push it, read the logs, and require it before merging.
Comments
Log in or create a free account to join the discussion.