Navigation
CI/CD Pipelines
How to set up automated build, testing, and deployment in GitRiver
GitRiver has a built-in CI/CD system. You don’t need to install external tools - everything works out of the box.
Configuration is described in YAML files in the .gitriver/workflows/ directory describing jobs and steps.
How It Works
- You create a YAML file in
.gitriver/workflows/in your repository - On push, pull request creation, or on a schedule - GitRiver checks all workflow files
- If the trigger matches - the pipeline starts
- Each job runs in a separate Docker container
- The result is displayed in the “CI/CD” tab of the repository
First Workflow
Create the file .gitriver/workflows/ci.yml:
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
image: node:22
steps:
- run: npm ci
- run: npm test
What’s here:
- name - the display name of the pipeline
- on - when to run: on push to
mainand on pull request creation/update - jobs - a set of tasks. We have one:
test - image - the Docker image in which steps are executed
- steps - a sequence of commands
Push the file to the repository (git push) - the pipeline will start automatically.
Triggers - When to Run
On Push to a Branch
Run on push to specific branches:
on:
push:
branches: [main, develop, 'release/**']
Only when certain files change:
on:
push:
branches: [main]
paths: ['src/**', 'Cargo.toml']
paths_ignore: ['docs/**', '*.md']
On Tag Push
For building releases:
on:
push:
tags: ['v*']
On Pull Request Creation/Update
on:
pull_request:
types: [opened, synchronize, reopened]
branches: [main]
On Schedule
For nightly builds or periodic checks:
on:
schedule:
- cron: '0 2 * * *'
Minimum interval is 15 minutes. Runs on the default branch.
Manual Trigger
To run a pipeline manually from the interface (“Run” button):
on:
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
type: choice
options: [staging, production]
Jobs
By default, jobs run in parallel. To set an order, use needs:
jobs:
build:
image: rust:1.93
steps:
- run: cargo build --release
test:
needs: [build]
image: rust:1.93
steps:
- run: cargo test
deploy:
needs: [test]
if: $CI_COMMIT_BRANCH == "main"
steps:
- run: ./deploy.sh
Here test waits for build to complete, and deploy waits for test and only runs for the main branch.
Docker Image
Each job runs in a Docker container. Specify the image:
jobs:
lint:
image: golangci/golangci-lint:latest
steps:
- run: golangci-lint run
Timeout
By default, a job is terminated after 1 hour. You can change this:
jobs:
long-test:
timeout: 2h
steps:
- run: make integration-tests
Formats: 30s, 10m, 1h, 1h30m. Maximum is 6 hours.
Service Containers
If your tests need a database, Redis, or another service - run them alongside:
jobs:
test:
image: python:3.12
services:
- image: postgres:16
alias: db
env:
POSTGRES_DB: test
POSTGRES_USER: test
POSTGRES_PASSWORD: test
- image: redis:7
alias: cache
env:
DATABASE_URL: postgres://test:test@db:5432/test
REDIS_URL: redis://cache:6379
steps:
- run: pip install -r requirements.txt
- run: pytest
Services are accessible by alias (db, cache) within the same Docker network.
Artifacts
Artifacts are files that need to be saved after a job completes (binaries, reports, logs):
jobs:
build:
image: rust:1.93
steps:
- run: cargo build --release
artifacts:
paths:
- target/release/myapp
expire_in: 7 days
Artifacts are available:
- In dependent jobs (via
needs) - For download through the interface (“CI/CD” tab -> click on the job -> “Artifacts” button)
Test Reports
artifacts:
paths:
- target/release/myapp
reports:
junit: test-results.xml
coverage_report: coverage.xml
GitRiver will display test results and coverage directly in the interface.
Caching
Cache speeds up repeated builds by saving dependencies between runs:
jobs:
test:
image: node:22
cache:
key: npm-$CI_COMMIT_BRANCH
paths:
- node_modules/
policy: pull-push
steps:
- run: npm ci
- run: npm test
| Policy | What it does |
|---|---|
pull-push |
Restore cache before the job + save after (default) |
pull |
Only restore (don’t update) |
push |
Only save (useful for jobs that generate cache) |
You can use CI variables in the key (key): $CI_COMMIT_BRANCH, $CI_COMMIT_REF_SLUG.
Environment Variables
In the Workflow File
Variables can be set at three levels:
env:
GLOBAL_VAR: hello
jobs:
test:
env:
JOB_VAR: world
steps:
- run: echo $GLOBAL_VAR $JOB_VAR $STEP_VAR
env:
STEP_VAR: "!"
In Repository Settings
For secrets (passwords, tokens), don’t store values in YAML. Add them through the interface:
- Open the repository -> “Settings” (gear icon) -> “CI/CD Variables”
- Click “Add Variable”
- Enter the name and value
- Check “Mask” - the value will be hidden in logs as
[MASKED]
Variables from repository settings are available in all jobs of that repository. They can also be set at the group and instance level (via Administration).
A pipeline from a fork waits for approval
Added in 1.1.0.
Anyone who can write to their own fork may open a pull request from it - no rights on the base repository are needed. But checks occupy runners, so code from outside has a second gate besides secrets.
A pipeline of a pull request whose author has no write access to the base repository is created but not started. It is visible in the pipeline list and on the request page marked “waiting for approval”; the jobs stand still. Any participant with write access approves the run - with the “Approve run” button on the pipeline page or with a request:
POST /api/v1/repos/{owner}/{name}/pipelines/{id}/approve
Approval is one-off and applies to a single pipeline: the next push to the request’s branch creates a new one, which has to be approved as well. Trust is not recalculated on approval - it is taken from the pipeline, so secrets stay closed after the button is pressed, even if the author has gained rights by then.
A pull request from a fork opened by a participant of the base repository does not wait for approval: the gate is on foreign code, not on forks as such. Such a pipeline is still not given secrets - the code comes from another repository.
The wait survives a server restart: the pipeline stays in the queue instead of being lost.
Viewing Results
- Open the repository in GitRiver
- Go to the “CI/CD” tab (rocket icon)
- You’ll see a list of pipeline runs with status icons
- Click on a run - a DAG visualization opens (which jobs depend on which)
- Click on a specific job - real-time logs open
Buttons:
- Cancel - abort execution
- Restart All - run the pipeline again
- Restart Failed - retry only failed jobs
Status Badge
Add to README.md to display CI status:

What’s Next
- CI/CD - Advanced - matrix builds, retry, concurrency, runners, K8s
- CI/CD - Reference - full list of variables, fields, and limits