Skip to content

CI for workflow projects

Install npm ci Type check tsc --noEmit Workflow Tests identity-flow-test on success on success
Install npm ci Type check tsc --noEmit Workflow Tests identity-flow-test on success on success
The job runs three separate steps in order, each with its own status: install from the lockfile, type-check, then run the Workflow Tests through the Workflow Test distribution.

This page sets up a CI job for your workflow project. A green job shows that the code type-checks and that your Workflow Tests passed against a real PostgreSQL database, and it archives which tools ran them.

Before you start: a Linux x64 runner (glibc, not Alpine) with Node.js and npm, Docker, and the Workflow Test distribution for your release. What the runner needs has the details, including a runner without Docker. First step: copy the job below into your CI definition.

The script shows the commands in order. Run them from the project root, and make each command its own step in your CI definition. IDENTITY_FLOW_TEST_DIR points at the unpacked Workflow Test distribution.

#!/usr/bin/env bash
# CI job for an IdentityFlow workflow project, run from the project root.
# IDENTITY_FLOW_TEST_DIR is the unpacked Workflow Test distribution, for example
# /opt/identity-flow-test-v0.3.1-linux-x64.
set -euo pipefail
mkdir -p ci-output
# Record which Workflow Test distribution ran the tests.
"$IDENTITY_FLOW_TEST_DIR/identity-flow-test" --version --json > ci-output/workflow-test-version.json
# Install exactly the package versions the lockfile records.
npm ci 2>&1 | tee ci-output/install.log
# Type-check workflows, hooks and tests.
npx --no-install tsc --noEmit 2>&1 | tee ci-output/typecheck.log
# Run every Workflow Test that vitest.config.ts selects. In the default mode
# each run starts and removes its own PostgreSQL container through Docker.
"$IDENTITY_FLOW_TEST_DIR/identity-flow-test" --run 2>&1 | tee ci-output/workflow-tests.log

The test step calls the distribution, not Vitest:

"$IDENTITY_FLOW_TEST_DIR/identity-flow-test" --run
  1. the unpacked distribution
  2. not npx vitest
  3. runs once, then exits

The Workflow Test distribution runs Vitest with your project’s vitest.config.ts. The tests it runs are the files that config selects:

import { defineConfig } from 'vitest/config';
// Workflow Tests use the `*.case.ts` suffix, which Vitest's default `include`
// does not match. Declaring it here is the only supported way to select them.
export default defineConfig({
test: { include: ['**/*.case.ts'], globalSetup: ['./workflow-test.setup.ts'] },
});

Keep all suites in one flat config. Vitest projects do not work with the Workflow Test distribution.

Plain npx vitest run does not run Workflow Tests: the public @identity-flow/testing package only type-checks them and fails at runtime with The Workflow Test runtime is not included in the public @identity-flow/testing package. If a CI log shows that message, the job called Vitest instead of the distribution.

  • Node.js and npm to install the project and run the type check. The starter requires Node.js 26.8.1. The project needs typescript and vitest as dev dependencies, as in the starter.
  • The Workflow Test distribution for your release, unpacked on the runner, for example at /opt/identity-flow-test-v0.3.1-linux-x64. Keep its six files together. It brings its own Node.js and needs a glibc-based Linux x64 image; Alpine and other musl-based images cannot run it. The distribution is delivered with the release, not through npm, so store it where your runners can fetch it, such as an internal artifact store or the runner image.
  • Docker, in the default mode: each test run starts its own PostgreSQL 18.6 container (postgres:18.6-alpine) and removes it afterwards. The runner must be able to reach a Docker daemon. If your registry policy requires a mirror, set IDENTITY_FLOW_TEST_POSTGRES_IMAGE to the mirrored image.
Runner without Docker

If the runner cannot use Docker, point the tests at a PostgreSQL server that the job provides, such as a CI service container. Set postgres: { mode: 'supplied', connection: … } in the project’s workflow-test.setup.ts. Supplied mode never falls back to a container, ignores the generic PG* variables, and needs allowRemote: true for any host on another machine. Every test runs in its own schema. The options are in the Testing API reference.

Run the type check and the Workflow Tests as separate steps, so each one reports its own status. A passing type check next to a failed test run is easy to misread as a pass.

Hook tests written with createHookTestHost need no database and no distribution; plain Vitest runs them. If you keep them in a separate Vitest config, run them as a third step.

Keep enough to tell later which code was tested with which tools:

  • the commit of your project and its package-lock.json;
  • ci-output/workflow-test-version.json, the version and source commit of the Workflow Test distribution;
  • the Node.js version (node --version);
  • the PostgreSQL image, postgres:18.6-alpine by default, or the value of IDENTITY_FLOW_TEST_POSTGRES_IMAGE;
  • the logs of the type check and the test run.

A green CI job shows that the tests passed against this code. It does not deploy anything; deployment is described in Install and run IdentityFlow.