Example: CI/CD Pipeline
Build a complete CI/CD pipeline with multiple stages, path-based triggering, and secrets.
Goal
- Run linting and unit tests only when source files change (skip for docs-only commits).
- Build a Docker image on pushes to
master. - Deploy to a staging environment on pushes to
master. - Store API keys as secrets, not in the config file.
- Use
skip_clonefor deployment steps that don't need source code.
Step 1: Create Secrets
Add the following secrets in your repository settings:
- DEPLOY_KEY — SSH key for deployment access.
- API_KEY — Third-party API key used during build.
Step 2: Write the Pipeline Config
# Skip clone for deployment steps that don't need source
skip_clone: true
steps:
lint:
image: node:20
environment:
IMAGE_NAME: myapp
commands:
- npm ci
- npm run lint
# Only run when source files change, not for docs-only commits
when:
path:
include:
- 'src/**'
- 'lib/**'
- 'package*.json'
exclude:
- '**/*.md'
- 'docs/**'
test:
image: node:20
commands:
- npm ci
- npm test
when:
path:
include:
- 'src/**'
- 'lib/**'
- '*_test.*'
- 'package*.json'
exclude:
- '**/*.md'
- 'docs/**'
build:
image: docker
environment:
IMAGE_NAME: myapp
API_KEY:
from_secret: API_KEY
commands:
- docker build -t $IMAGE_NAME:${CI_COMMIT_SHA:0:10} .
when:
branch: [master]
path:
include:
- 'src/**'
- 'lib/**'
- 'Dockerfile'
- 'package*.json'
deploy-staging:
image: alpine
# No clone needed for deployment
environment:
DEPLOY_KEY:
from_secret: DEPLOY_KEY
commands:
- ssh -i $DEPLOY_KEY deploy@staging.example.com "cd /app && docker compose pull && docker compose up -d"
when:
branch: [master] Step 3: Configure Triggers
The when: blocks with path: ensure tests and linting only run when relevant
source files change. Documentation-only commits (e.g., *.md files in docs/)
will skip these steps entirely.
Manual Re-run
If you need to force a pipeline run (e.g., after a flaky test failure or infrastructure issue), use the Re-run button in the Flows tab or pipeline detail page. The re-run uses the exact same configuration and commit.
Step 4: Set Up Merge Requirements
In repository settings, enable Require CI to pass so merges to master are blocked until the pipeline succeeds:
- Require CI to pass: Yes
Result
- Source changes trigger linting and testing; docs-only changes skip CI.
- Pushes to
masterbuild and deploy a Docker image. - Deployments skip clone for faster execution.
- Secrets are never exposed in logs or configuration files.
- Change requests require passing CI before merge.
- Failed pipelines can be re-run from the UI.