Continuous Integration Example
A complete CI workflow that installs dependencies, lints, and tests on every push.
Continuous Integration (CI) automatically builds and tests your code on every change, catching problems early. Here is a realistic CI pipeline.
If any step fails, the whole job fails and the PR shows a red X, blocking a merge on protected branches.
Example
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run lint
- run: npm test -- --coverageWhen to use it
- A Node.js team runs lint, unit tests, and code coverage checks on every pull request so reviewers see quality signals before approving.
- A Python project's CI workflow runs pytest, uploads coverage to Codecov, and fails the run if coverage drops below 80%.
- A monorepo CI workflow uses path filters to run only the affected service's tests when a PR changes files in that service's directory.
More examples
Node.js lint and test CI workflow
A complete Node.js CI workflow that caches npm dependencies, runs the linter, and executes the test suite with coverage on every PR.
name: CI
on:
pull_request:
push:
branches: [main]
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: npm
- run: npm ci
- run: npm run lint
- run: npm test -- --coveragePython CI with coverage upload
Runs pytest with coverage and fails the job if coverage falls below 80%, acting as a quality gate on every push.
name: Python CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install -r requirements.txt
- run: pytest --cov=src --cov-fail-under=80Upload test results as artifact
Uploads the JUnit XML report as a workflow artifact so test failure details are available for download even when the job fails.
steps:
- run: npm test -- --reporter=junit --reporter-option output=results.xml
- uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: results.xml
Discussion