This guide is for teams that do not use Fastlane or want a single, flexible way to upload mobile builds and trigger test runs from any CI system.Use the QA Wolf CI SDK if your mobile builds are produced directly in CI scripts; you want the same integration approach for mobile and web testing; you are not using GitHub Actions or prefer not to rely on prebuilt actions; or you need fine-grained control over when artifacts are uploaded, and runs are triggered.This guide assumes only that your CI system can run Node.js.
Before using the CI SDK:
Make sure you have a CI pipeline that produces a mobile build artifact (APK, AAB, or IPA)
Node.js 18 or later is available in your CI environment.
A QA Wolf API key is stored as a CI secret (QAWOLF_API_KEY),
If this step completes successfully, the artifact is uploaded and available for test runs.
Javascript
Copy
Ask AI
import { type DeployConfig, makeQaWolfSdk } from "@qawolf/ci-sdk";import fs from "fs/promises";import path from "path";const { generateSignedUrlForRunInputsExecutablesStorage, attemptNotifyDeploy } = makeQaWolfSdk({ apiKey: "qawolf_xxxxx", });(async () => { const playgroundFileLocation = await uploadRunArtifact("/FileLocation"); if (playgroundFileLocation) { const deployConfig: DeployConfig = { branch: undefined, commitUrl: undefined, deduplicationKey: undefined, deploymentType: undefined, deploymentUrl: undefined, ephemeralEnvironment: undefined, hostingService: undefined, sha: undefined, variables: { RUN_INPUT_PATH: playgroundFileLocation, // for mobile apps, the team may request that you use a different // variable name here, such as ANDROID_APP }, }; const result = await attemptNotifyDeploy(deployConfig); if (result.outcome !== "success") { // Fail the job. process.exit(1); } const runId = result.runId; }})();async function uploadRunArtifact(filePath: string): Promise<string> { const fileName = path.basename(filePath); const signedUrlResponse = await generateSignedUrlForRunInputsExecutablesStorage({ // for mobile apps, we prefer static filenames based on the environment name // for example, use `app_staging.apk` for the Staging environment destinationFilePath: fileName, }); if ( signedUrlResponse?.success && signedUrlResponse.playgroundFileLocation && signedUrlResponse.uploadUrl ) { const fileBuffer = await fs.readFile(filePath); const url = signedUrlResponse.uploadUrl; try { const response = await fetch(url, { method: "PUT", body: fileBuffer, headers: { "Content-Type": "application/octet-stream", }, }); if (!response.ok) { return ""; } } catch (error) { return ""; } // for mobile apps, we request that you include this prefix path // return `/home/wolf/run-inputs-executables/${signedUrlResponse.playgroundFileLocation}`; // for other apps return signedUrlResponse.playgroundFileLocation; } return "";}
If uploads succeed but no runs start: Mobile triggers may not yet be enabled. Contact QA Wolf to complete platform configuration.
If the artifact is not found during execution: Verify that the artifact basename matches your naming conventions, and the returned path is used when triggering the run.
If you see authentication errors: Verify that QAWOLF_API_KEY is configured correctly in your CI environment.
If you encounter Node.js errors: Ensure Node.js 18 or later is available in the CI job.