Git and GitHub course menu
GitHub Actions Tutorial: Run Tests Automatically with CI
Learn CI with GitHub Actions: write your first workflow file, run tests on every pull request, understand jobs, steps and triggers, use secrets safely, and block failing merges.
On this page
Continuous integration (CI) means that every change is built and tested automatically. GitHub Actions is GitHub's built-in CI service. When you push, GitHub starts a fresh virtual machine, runs your commands, and shows a green tick or a red cross on the commit and on the pull request.
That catches problems early, and it means that reviewers do not have to run the tests by hand.
Your first workflow#
A workflow is a YAML file in the .github/workflows/ folder of your repository. This one runs the tests of a Node.js project:
name: CI
on:
push:
branches: [main]
pull_request:
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 testCommit the file and push it. GitHub finds it automatically.
git add .github/workflows/ci.yml
git commit -m "Run tests in CI"
git pushOpen the Actions tab of your repository to watch it run. Click a job to read the log of each step.
What each part means#
actions/checkout copies your repository onto the machine. Without it, there are no files to test. The @v7 is the version of the action, and you can check the action's page for the latest one.
A Python example#
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.13"
- run: pip install -r requirements.txt
- run: pytestCommon triggers#
on:
push:
branches: [main]
pull_request:
schedule:
- cron: "0 2 * * *" # every day at 02:00 UTC
workflow_dispatch: # adds a Run workflow buttonTest on several versions#
A matrix runs the same job with different settings:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node: [22, 24]
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm testSecrets#
Never put passwords or API keys in a workflow file. Store them under Settings, then Secrets and variables, then Actions, and read them like this:
- run: npm run deploy
env:
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}GitHub hides the value in the logs, and it does not pass secrets to workflows started by pull requests from forks.
Block merges when checks fail#
Red crosses are only a warning until you enforce them. In the repository's branch rules, turn on Require status checks to pass before merging for main, and choose your CI job. A pull request with failing tests can then no longer be merged.
Cost#
GitHub Actions is free on public repositories using GitHub's standard machines. Private repositories get a monthly allowance of free minutes, and you can check the current limits in GitHub's documentation.
Common mistakes#
Practice#
Practice exercise
Write the on: section for a workflow that runs on pull requests, on pushes to main, and every Monday at 06:00 UTC.
Show hint
In a cron expression, the fields are minute, hour, day of month, month, and day of week. Monday is 1.
Show solution
on:
pull_request:
push:
branches: [main]
schedule:
- cron: "0 6 * * 1"Key takeaway#
Next: Rebasing.
Finished this lesson?