@qawolf/ci-sdk is a TypeScript package for notifying QA Wolf of a deploy from your CI pipeline and gating the pipeline on the result. It calls the same public API the Webhook page documents, with typed inputs taken from the published API contract.
SDK functions do not throw. Each returns a result object with an outcome field, and your pipeline branches on it to decide whether the step passes or fails.
The guide for wiring it into a pipeline is Node.js SDK. This page is the function-by-function reference.
This page documents 3.3.0. deployment.reportStatus and deployment.waitForVerdict need 3.1.0 or later, so a pipeline on an earlier version has only the legacy functions and upgrades before wiring one up.
Installation
Requires Node.js 24.14.1 or later, below 25. The package is published as ESM only: import it with
import, or from CommonJS with await import("@qawolf/ci-sdk"). require("@qawolf/ci-sdk") does not resolve.makeQaWolfSdk
The entry point for every function. Pass your API key to initialize.Options
A second argument injects dependencies. Each is optional:
Returns an object with these functions:
deployment.reportStatus— reports a deployment. A deployment’s firstsuccessreport is what evaluates triggers and starts a run.deployment.waitForVerdict— blocks until QA Wolf can say whether the deployment’s tests passed.notifyTerminatedEphemeralEnvironment— tells QA Wolf an ephemeral environment is gone.generateSignedUrlForRunInputsExecutablesStorageandgenerateSignedUrlForTempTeamStorage— signed upload URLs for files a run needs.attemptNotifyDeploy,pollCiGreenlightStatusandmakePollCiGreenlightStatusIterator— the legacy functions. They report through thedeploy_successwebhook, which triggers do not see.
detectProviderDeploymentId is a standalone export rather than a method; see below.
API keys and workspaceId
Every call acts on exactly one workspace.
- A workspace API key belongs to one workspace.
deployment.reportStatusstill requiresworkspaceId, and it has to name that workspace; naming another fails withunauthorized. - An organization API key or a user API key can reach several workspaces, so
workspaceIdpicks one.
workspaceId as an optional field; see each function for what happens when it is omitted.
deployment.reportStatus
Reports a deployment to QA Wolf through the publicdeployment.reportStatus API. The parameters are the API’s own input, so Webhook and Deployments describe how each field is read.
Example:
Parameters
The input is validated strictly: a field the contract does not know, or
environment carrying both id and name, is an invalid-request. ReportDeploymentParams is the exported type.
Result
Branch onoutcome:
The response carries the deployment only, never the resulting runs.
deployment.waitForVerdict is how a pipeline learns what the runs decided.
outcome: "reported" means QA Wolf recorded the deployment, not that a trigger matched it. Whether a run starts is decided afterwards, by your triggers.detectProviderDeploymentId
Composes aproviderDeploymentId from the variables your CI system already sets. The id is distinct for every job definition and every re-run, so a retried job or a second job deploying alongside the first gets its own deployment rather than reporting into one whose first success already evaluated triggers.
Example:
Options
Result
The helper is optional.
providerDeploymentId is always required on the report, and any value that changes on every re-run and differs between concurrent deploys works.
deployment.waitForVerdict
Blocks until QA Wolf can say whether a deployment’s tests passed. Give it thedeployment.id the report returned; resolving that to the runs the triggers created, and those runs to a status, happens inside.
Example:
Options
Every field exceptdeploymentId is optional. Durations are in milliseconds.
The stages
onProgress receives, in order:
waiting-for-evaluation— QA Wolf has not yet evaluated the deployment’s triggers.waiting-for-run— triggers matched and at least one is still creating a run. CarriesmatchedTriggerCount.waiting-for-verdict— every run is known and at least one is still executing. Carriesruns.
Result
Branch onoutcome:
not-tested is a separate answer from passed. A deployment no trigger matched was not tested, which is a different fact from tests passing, and your pipeline decides what it is worth. reason is "no-trigger-matched" when every trigger was evaluated and none matched, or "no-run-created" when a trigger matched and something stopped it from creating a run; each entry in triggers then carries triggerName, a message for the log and, for no-run-created, a stable reason code to branch on.
superseded is what a cancel-in-progress pipeline looks like from the older job: the newer deployment’s job carries the verdict. Reserve a distinct exit code for it when your CI should treat the job as skipped rather than failed.
Each entry in runs:
DeploymentVerdict, VerdictRun, VerdictStage, TriggerNote and NotTestedReason are the exported types. The same shape is published as deploymentVerdictSchema in @qawolf/api-contracts.
notifyTerminatedEphemeralEnvironment
Tells QA Wolf that an ephemeral environment has been terminated. QA Wolf stops the runs targeting it and promotes any flow changes to the base environment. See webhooks/environment_terminated for the underlying endpoint. With a connected GitHub or GitLab integration, QA Wolf hears about the pull request closing from the code host, and this call is redundant. Example:Input fields
Pass exactly one of the following to identify the environment:environmentAlias and deploymentUrl also take workspaceId. It is optional; an organization or user key that omits it acts on the organization’s first-created workspace, and the result carries a warning naming it. NotifyTerminatedEphemeralEnvironmentInput is the exported type.
Result fields
generateSignedUrlForRunInputsExecutablesStorage
Generates a signed URL for uploading a run input executable (APK, AAB, DEB, IPA, ZIP, CSV, PDF) to QA Wolf. See v0/run-inputs-executables-signed-urls for the underlying endpoint, and Mobile build testing for the pipeline it belongs to. Example:Input fields
Response fields
A failed request from this function reports
abortReason: "client-network-error" and httpStatus: 0 whatever the real status was. The SDK logs the real status on the line above, so read the log rather than branching on abortReason. A 400 from an organization or user key most often means workspaceId was not sent.generateSignedUrlForTempTeamStorage takes the same input and returns the same fields, for files that are not executables.
Legacy functions
Moving a pipeline off them:deploymentType becomes environment.name; branch and sha move into metadata; providerDeploymentId is new and required, and subsumes deduplicationKey; hostingService disappears, since the code host comes from your integration; variables becomes environmentVariables. There is no skipped outcome, because whether a trigger matched is not known at report time; deployment.waitForVerdict answers not-tested instead.
attemptNotifyDeploy
Notifies QA Wolf of a successful deployment through webhooks/deploy_success. Example:DeployConfig fields
DeployConfig is a union of GitHubDeployConfig, GitLabDeployConfig and EphemeralDeployConfig. Every field is declared on the type, so pass undefined for the ones you do not use.
Result fields
pollCiGreenlightStatus
Polls v0/ci-greenlight for a run id until the run completes. The run id comes fromattemptNotifyDeploy, so this function only works for pipelines on the legacy path.
Example:
Options
Result fields
makePollCiGreenlightStatusIterator
An async generator over the same poll, for a pipeline that needs to stop early on its own criteria. Takes the same options aspollCiGreenlightStatus except onRunStageChanged.
Example:
Versioning
The package follows SemVer.- Depend on it with the
^range operator. Patch and minor releases do not introduce breaking changes. - A major version bump marks a breaking change, announced in advance.
- Only top-level exports are covered. New fields in response types, and changes to log output, are not breaking changes.
The changelog is in the package’s README on npm.