Skip to content

CI integration

Nijam is built to run in CI. You don’t pass commit, branch, PR, or author by hand - the pytest plugin detects them automatically from your CI provider, so each pytest run lands in history with full context.

Commit, branch, PR number, CI run id, CI run URL, and the git author (email + name). Resolution order, per field:

  1. CI-specific environment variables (see below)
  2. Generic GIT_* / BRANCH / COMMIT_SHA variables
  3. A git log / git rev-parse shell-out
  4. Empty (branch is left unset → the dashboard shows “No Branch Info”)

Detected from GITHUB_SHA, GITHUB_REF_NAME, GITHUB_HEAD_REF, GITHUB_RUN_ID, GITHUB_REPOSITORY, GITHUB_SERVER_URL.

.github/workflows/tests.yml
name: tests
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
env:
NIJAM_API_KEY: ${{ secrets.NIJAM_API_KEY }}
NIJAM_PROJECT_ID: ${{ vars.NIJAM_PROJECT_ID }}

If you split your suite across several CI jobs (for example with pytest-xdist distribution or a job matrix), they all club into one Nijam run when they share the CI run id, and a failure in any job flips that run to Failing right away. The dashboard shows running / failing live until the run completes.

When each job runs a different subset of tests, there’s no known total, so each job must not finalize on its own. Set nijam_auto_complete = false (or the NIJAM_AUTO_COMPLETE=false env var), then add one post-matrix step that calls POST /v1/runs/complete to mark the run done - passing the CI run id the jobs shared (GITHUB_RUN_ID, CI_PIPELINE_ID, …) so it targets the right run.

pytest has no native --shard (unlike the Playwright and Vitest reporters), so there’s no NIJAM_SHARD_INDEX / NIJAM_SHARD_TOTAL shortcut: this matrix plus the completion step is how you fan a pytest suite out across jobs.

.github/workflows/tests.yml
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
suite: [unit, integration, api, web] # one subset per job
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- run: pip install -r requirements.txt
- run: pytest tests/${{ matrix.suite }}
env:
NIJAM_API_KEY: ${{ secrets.NIJAM_API_KEY }}
NIJAM_PROJECT_ID: ${{ vars.NIJAM_PROJECT_ID }}
NIJAM_AUTO_COMPLETE: "false" # don't finalize per job
summary:
needs: [test] # after every suite job
if: always() # complete even if some failed
runs-on: ubuntu-latest
steps:
- run: |
curl -sf -X POST "https://api.nijam.dev/v1/runs/complete" \
-H "Authorization: Bearer ${{ secrets.NIJAM_API_KEY }}" \
-H "Content-Type: application/json" \
-d "{\"projectId\":\"<your-project-id>\",\"ciRunId\":\"$GITHUB_RUN_ID\",\"ciRunAttempt\":\"$GITHUB_RUN_ATTEMPT\"}"

A single pytest run needs none of this - it completes on its own.

On a provider not listed above, set the generic variables and the plugin picks them up:

VariableMaps to
COMMIT_SHAcommit
BRANCHbranch
CI_RUN_IDCI run id
CI_URLCI run URL

If none are set, the plugin still falls back to git, so local runs are attributed too. The full variable list lives in the CI variables reference.

To send runs and reports to Nijam, the plugin needs two things:

  • nijam_project_id - which project to push to. Not a secret; it just identifies the project. Usually set in pytest.ini (or via NIJAM_PROJECT_ID).
  • API key - the only secret. Store it as NIJAM_API_KEY in your CI secrets and reference it via the environment.

Everything else - commit, branch, PR, CI link, author - is detected automatically.