@qawolf/ci-sdk 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -1
- package/dist/index.js +427 -4
- package/dist/index.js.map +4 -4
- package/dist/lib/sdk/defaults/clock.d.ts +2 -0
- package/dist/lib/sdk/dependencies.d.ts +9 -0
- package/dist/lib/sdk/domain/waitForVerdict/awaitRuns.d.ts +14 -0
- package/dist/lib/sdk/domain/waitForVerdict/awaitVerdict.d.ts +12 -0
- package/dist/lib/sdk/domain/waitForVerdict/consts.d.ts +13 -0
- package/dist/lib/sdk/domain/waitForVerdict/failures.d.ts +14 -0
- package/dist/lib/sdk/domain/waitForVerdict/index.d.ts +12 -0
- package/dist/lib/sdk/domain/waitForVerdict/logVerdict.d.ts +3 -0
- package/dist/lib/sdk/domain/waitForVerdict/poll.d.ts +20 -0
- package/dist/lib/sdk/domain/waitForVerdict/progress.d.ts +7 -0
- package/dist/lib/sdk/domain/waitForVerdict/readEvaluations.d.ts +20 -0
- package/dist/lib/sdk/domain/waitForVerdict/testHarness.d.ts +53 -0
- package/dist/lib/sdk/domain/waitForVerdict/types.d.ts +48 -0
- package/dist/lib/sdk/index.d.ts +95 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/sdk/domain/detectProviderDeploymentId/index.ts", "../src/lib/other.ts", "../src/lib/sdk/defaults/fetch.ts", "../src/lib/sdk/defaults/log.ts", "../src/lib/sdk/defaults/serviceBase.ts", "../package.json", "../src/lib/sdk/defaults/userAgent.ts", "../src/lib/api/log.ts", "../src/lib/sdk/domain/attemptDeploy/handleSuccessResponse.ts", "../src/lib/sdk/domain/attemptDeploy/mapDeploySuccessResponse.ts", "../src/lib/sdk/domain/attemptDeploy/parseDeploySuccessWireResponse.ts", "../src/lib/sdk/domain/attemptDeploy/index.ts", "../src/lib/api/signed-url.ts", "../src/lib/api/generate-signed-url-for-run-inputs-executables.ts", "../src/lib/sdk/domain/generateSignedUrls/generate-signed-url-for-run-inputs-executables.ts", "../src/lib/api/generate-signed-url-for-team-storage.ts", "../src/lib/sdk/domain/generateSignedUrls/generate-signed-url-for-team-storage.ts", "../src/lib/sdk/domain/notifyTerminatedEphemeralEnvironment/index.ts", "../src/lib/sdk/domain/pollCiGreenlight/buildCompletedRunResult.ts", "../src/lib/sdk/domain/pollCiGreenlight/consts.ts", "../src/lib/api/ci-greenlight.ts", "../src/lib/sdk/domain/pollCiGreenlight/iterator.ts", "../src/lib/sdk/domain/pollCiGreenlight/logging.ts", "../src/lib/sdk/domain/pollCiGreenlight/mapIteratorAbortToGreenlightStatus.ts", "../src/lib/sdk/domain/pollCiGreenlight/index.ts", "../src/lib/sdk/domain/reportDeployment/index.ts", "../src/lib/sdk/publicApi/callContract.ts", "../src/lib/sdk/index.ts"],
|
|
4
|
-
"sourcesContent": ["export type CiSystem =\n | \"bitbucket\"\n | \"buildkite\"\n | \"circleci\"\n | \"github\"\n | \"gitlab\"\n | \"jenkins\";\n\nexport type DetectedProviderDeploymentId =\n | {\n ci: CiSystem;\n /**\n * An identity that is distinct for every job definition and every\n * re-run, e.g. `18273645-2-deploy` on GitHub Actions, plus the\n * `discriminator` when one was given.\n */\n id: string;\n outcome: \"detected\";\n }\n | {\n ci: CiSystem;\n /**\n * The CI system was recognized but did not expose every variable the\n * identity is composed from.\n */\n missingVariables: string[];\n outcome: \"missing-variables\";\n }\n | { outcome: \"unsupported\" };\n\ntype CiEnvironment = Record<string, string | undefined>;\n\nexport type DetectProviderDeploymentIdOptions = {\n /**\n * Appended to the composed id. Required whenever one job definition deploys\n * more than once at a time \u2014 a GitHub Actions or Jenkins matrix, a CircleCI\n * job with `parallelism`, a loop over environment names \u2014 because no CI\n * system exposes the leg it is running as a variable. Pass the matrix\n * values, the environment name, or anything else that tells the concurrent\n * deployments apart. It is appended after a colon.\n */\n discriminator?: string;\n /** The variables to read, defaulting to `process.env`. */\n env?: CiEnvironment;\n};\n\ntype CiSystemDefinition = {\n ci: CiSystem;\n isActive: (env: CiEnvironment) => boolean;\n /** Joined in order into the id; all of them must be present. */\n variables: string[];\n};\n\nconst ciSystems: CiSystemDefinition[] = [\n {\n ci: \"github\",\n isActive: (env) => env.GITHUB_ACTIONS === \"true\",\n // GITHUB_RUN_ID is stable across re-runs and GITHUB_RUN_ATTEMPT increments,\n // and both are shared by every job in the workflow, so GITHUB_JOB separates\n // jobs that deploy in parallel. GITHUB_JOB names the job definition, which\n // every leg of a matrix shares, so those legs need a discriminator.\n variables: [\"GITHUB_RUN_ID\", \"GITHUB_RUN_ATTEMPT\", \"GITHUB_JOB\"],\n },\n {\n ci: \"gitlab\",\n isActive: (env) => env.GITLAB_CI === \"true\",\n // Retrying a job keeps the pipeline id and mints a new job id.\n variables: [\"CI_PIPELINE_ID\", \"CI_JOB_ID\"],\n },\n {\n ci: \"circleci\",\n isActive: (env) => env.CIRCLECI === \"true\",\n // A rerun keeps the workflow id and allocates a new build number. A job\n // run with `parallelism` shares both across its containers, so those need\n // a discriminator.\n variables: [\"CIRCLE_WORKFLOW_ID\", \"CIRCLE_BUILD_NUM\"],\n },\n {\n ci: \"buildkite\",\n isActive: (env) => env.BUILDKITE === \"true\",\n // BUILDKITE_BUILD_ID covers the whole build, so BUILDKITE_JOB_ID separates\n // the jobs within it and BUILDKITE_RETRY_COUNT separates a job's retries.\n variables: [\n \"BUILDKITE_BUILD_ID\",\n \"BUILDKITE_JOB_ID\",\n \"BUILDKITE_RETRY_COUNT\",\n ],\n },\n {\n ci: \"jenkins\",\n // JENKINS_URL is unset on some agent configurations.\n isActive: (env) =>\n env.JENKINS_URL !== undefined || env.JENKINS_HOME !== undefined,\n // BUILD_TAG is `jenkins-${JOB_NAME}-${BUILD_NUMBER}`, and Jenkins allocates\n // a fresh BUILD_NUMBER for every externally visible re-run \u2014 Rebuild,\n // Naginator, Replay and Restart from Stage \u2014 so it needs no attempt\n // counter. An in-pipeline `retry {}` reuses it, but reports nothing new.\n // A declarative `matrix` or `parallel` block runs its branches inside one\n // build and so shares BUILD_TAG; those branches need a discriminator.\n variables: [\"BUILD_TAG\"],\n },\n {\n ci: \"bitbucket\",\n isActive: (env) =>\n env.BITBUCKET_WORKSPACE !== undefined ||\n env.BITBUCKET_BUILD_NUMBER !== undefined,\n // Rerunning a whole pipeline mints a new build number, but rerunning only\n // the failed steps keeps it and increments the step's run number instead.\n // Parallel steps share both, so BITBUCKET_STEP_UUID separates them.\n variables: [\n \"BITBUCKET_BUILD_NUMBER\",\n \"BITBUCKET_STEP_UUID\",\n \"BITBUCKET_STEP_RUN_NUMBER\",\n ],\n },\n];\n\n/**\n * Derives a `providerDeploymentId` from the CI system's own environment\n * variables. Run ids are usually shared by a build's jobs and stable across\n * re-runs, so the id composes the run with the job and the attempt; without\n * that, a re-run or a sibling job would report into a deployment whose first\n * success report already evaluated triggers, and create no run.\n *\n * The id is distinct per job definition and per attempt only. Concurrent\n * deployments from one job definition \u2014 a matrix leg, a loop over\n * environments \u2014 are indistinguishable in the environment, so pass a\n * `discriminator` for them or compose the `providerDeploymentId` yourself.\n */\nexport function detectProviderDeploymentId({\n discriminator,\n env = process.env,\n}: DetectProviderDeploymentIdOptions = {}): DetectedProviderDeploymentId {\n const system = ciSystems.find((candidate) => candidate.isActive(env));\n if (!system) return { outcome: \"unsupported\" };\n\n const missingVariables = system.variables.filter((name) => !env[name]);\n if (missingVariables.length > 0)\n return { ci: system.ci, missingVariables, outcome: \"missing-variables\" };\n\n const composed = system.variables.map((name) => env[name]).join(\"-\");\n return {\n ci: system.ci,\n // A colon separates the discriminator because a job id can itself contain\n // a hyphen, so joining with one would let job \"deploy-web\" collide with\n // job \"deploy\" discriminated by \"web\".\n id: discriminator ? `${composed}:${discriminator}` : composed,\n outcome: \"detected\",\n };\n}\n", "import type { FetchDriver } from \"./sdk/dependencies.js\";\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function pluralize(count: number) {\n return count === 1 ? \"\" : \"s\";\n}\n\nexport function getBackoffMs(\n attemptNumber: number,\n minWaitMs = 1000,\n maxWaitMs = 10000,\n): number {\n return Math.min(maxWaitMs, minWaitMs * 1.2 ** attemptNumber);\n}\n\nexport const buildFetchWithTimeout =\n (fetch: FetchDriver, defaultTimeoutMs: number) =>\n async (...args: Parameters<FetchDriver>) => {\n // Allow signal to be overridden by the caller\n const signal = args[1]?.signal ?? AbortSignal.timeout(defaultTimeoutMs);\n\n return fetch(args[0], { ...args[1], signal });\n };\n", "export const defaultFetch = globalThis.fetch;\n", "import type { LogDriver } from \"../dependencies.js\";\n\nexport const defaultLogDriver: LogDriver = {\n error(message, error) {\n console.error(message, error);\n },\n info(message) {\n console.log(message);\n },\n warn(message) {\n console.warn(message);\n },\n};\n", "export const defaultServiceBase = \"https://app.qawolf.com/\";\n", "{\n \"name\": \"@qawolf/ci-sdk\",\n \"version\": \"3.1.0\",\n \"private\": false,\n \"description\": \"A simple SDK for interacting with QAWolf in CI scripts.\",\n \"keywords\": [],\n \"license\": \"MIT\",\n \"author\": \"Jules Sam. Randolph<jules@qawolf.com>\",\n \"files\": [\n \"/dist\",\n \"/README.md\"\n ],\n \"type\": \"module\",\n \"sideEffects\": false,\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n }\n },\n \"scripts\": {\n \"build\": \"platform-builder --config platformBuilder.config.ts\",\n \"lint:ci\": \"npm run lint:first-half; FIRST_HALF_EXIT=$?; npm run lint:second-half && exit $FIRST_HALF_EXIT\",\n \"lint:dev\": \"npm run lint:first-half\",\n \"lint:first-half\": \"oxlint . --fix --quiet --report-unused-disable-directives --type-aware && oxfmt --write .\",\n \"lint:second-half\": \"rev-dep config run\",\n \"prepublishOnly\": \"nx run ci-sdk:build\",\n \"test\": \"NODE_OPTIONS=\\\"--experimental-vm-modules\\\" NODE_NO_WARNINGS=1 jest\",\n \"tsc:check\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@qawolf/api-contracts\": \">=0.68.0\",\n \"@qawolf/ci-utils\": \"^2.0.0\",\n \"@sinonjs/fake-timers\": \"^10.3.0\",\n \"tslib\": \"^2.6.2\",\n \"zod\": \"^4.1.11\"\n },\n \"devDependencies\": {\n \"@qawolf/platform-builder\": \"^1.2.7\",\n \"tsx\": \"^4.19.4\",\n \"typescript\": \"^5.9.3\"\n },\n \"engines\": {\n \"node\": \">=24.14.1 <25\"\n }\n}\n", "import packageJson from \"../../../../package.json\" with { type: \"json\" };\n\nexport const defaultUserAgent = `ci-sdk/${packageJson.version}`;\n", "import type { LogDriver } from \"@qawolf/ci-utils\";\n\nexport async function logFetchError({\n log,\n methodName,\n response,\n}: {\n log: LogDriver;\n methodName: string;\n response: Response;\n}) {\n if (response.ok) return;\n\n const { eventId, failureMessage } = await (async () => {\n try {\n const body = (await response.json().catch(() => response.text())) as\n | Record<string, unknown>\n | string;\n if (typeof body === \"object\" && body !== null) {\n return {\n eventId: body.eventId,\n failureMessage: body.failureMessage,\n };\n }\n // If body is not an object (i.e., it's the text from catch)\n return {\n eventId: undefined,\n failureMessage: body,\n };\n } catch {\n // If both parsing attempts somehow fail\n return {\n eventId: undefined,\n failureMessage: undefined,\n };\n }\n })();\n\n const eventIdSuffix = eventId ? ` (Event ID: ${eventId})` : \"\";\n const messageSuffix = failureMessage ? `: ${failureMessage}` : \"\";\n\n const statusText =\n response.status >= 500\n ? \"Server Error\"\n : response.statusText || \"Unknown Error\";\n\n log.error(\n `\u274C [${methodName}] ${response.status} ${statusText}${eventIdSuffix}${messageSuffix}`,\n );\n}\n", "import type { LogDriver } from \"../../dependencies.js\";\n\nimport type { DeployStatus, NotifyDeployStatus } from \"./types.js\";\n\nexport async function handleSuccessResponse(\n data: DeployStatus,\n log: LogDriver,\n): Promise<NotifyDeployStatus> {\n const { environment, results } = data;\n const skippedTriggers = data.skippedTriggers ?? [];\n const skippedDeployment = data.skippedDeployment;\n const isPreviewDeployment = environment && !environment.isStatic;\n\n if (data.warning) log.warn(`\u26A0\uFE0F ${data.warning}`);\n\n if (environment) {\n const logPrefix = environment.isStatic\n ? \"Static environment\"\n : \"Preview environment\";\n log.info(`${logPrefix}: ${environment.alias} (id: ${environment.id})`);\n }\n\n // No suites were created for this deployment.\n if (results.length === 0) {\n const skipMessages = [\n ...skippedTriggers.map((trigger) => trigger.message),\n ...(skippedDeployment ? [skippedDeployment.message] : []),\n ];\n const skipDetail =\n skipMessages.length > 0 ? ` ${skipMessages.join(\" \")}` : \"\";\n\n // Preview deployments legitimately often produce no run; keep the success\n // outcome but surface any skip reason so it is not silently dropped.\n if (isPreviewDeployment) {\n log.info(\n `\u2705 Deployment notification was successful. No run was created for this deployment.${skipDetail}`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: undefined,\n };\n }\n\n // A trigger matched but could not run (e.g. environment still syncing).\n // Only a backend that still sends skipped_triggers reaches this arm. Current\n // backends omit the field, so those responses bypass it and fall to the\n // generic \"no trigger matched\" warning below even when a trigger did match.\n if (skippedTriggers.length > 0) {\n log.error(`\uD83D\uDEAB No run was created for this deployment.${skipDetail}`);\n return {\n failReason: \"trigger-skipped\",\n outcome: \"failed\",\n skippedTriggers,\n };\n }\n\n log.warn(\n skippedDeployment\n ? `\u26A0\uFE0F No run was created for this deployment.${skipDetail}`\n : `\u26A0\uFE0F No trigger matched the request. Please make sure there is at least one active test in the QA Wolf environment, or contact support.`,\n );\n return {\n outcome: \"skipped\",\n skippedDeployment,\n };\n }\n\n // If there are results, environment must be defined\n if (!environment) {\n log.error(`\uD83D\uDEAB No environment matched the request. Please contact support.`);\n return { failReason: \"no-environment\", outcome: \"failed\" };\n }\n\n // A result arm this SDK version does not recognize (newer backend). We cannot\n // classify the outcome, so surface it as a failure rather than guessing.\n const unrecognizedResult = results.find((result) => \"unrecognized\" in result);\n if (unrecognizedResult) {\n log.error(\n `\uD83D\uDEAB The deployment response contained an unrecognized result. Please upgrade @qawolf/ci-sdk.`,\n );\n return { failReason: \"unknown-result\", outcome: \"failed\" };\n }\n\n const failedTrigger = results.find((result) => \"failureReason\" in result);\n if (failedTrigger) {\n // Prefer the customer-facing message; older backends send only the internal\n // reason, which is all we can show in that case.\n log.error(\n `\uD83D\uDEAB Run could not be created. Reason: \"${failedTrigger.failureMessage ?? failedTrigger.failureReason}\". Please contact support.`,\n );\n return { failReason: \"run-could-not-be-created\", outcome: \"failed\" };\n }\n\n const duplicateSuite = results.find((result) => \"duplicateSuiteId\" in result);\n if (duplicateSuite) {\n log.info(\n `\u2705 Deployment notification was successful. Previous run ID: ${duplicateSuite.duplicateSuiteId} already exists for this deployment.`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: duplicateSuite.duplicateSuiteId,\n };\n }\n\n const successfulTrigger = results.find(\n (result) => \"createdSuiteId\" in result,\n );\n if (!successfulTrigger) {\n // results is non-empty here, so triggers did match \u2014 this is not the\n // deterministic no-trigger-match skip. Reaching this point means the\n // response carried results we could not turn into a run, so it is an\n // unexpected failure rather than a skip.\n log.error(`\uD83D\uDEAB Run could not be created. Please contact support.`);\n return { failReason: \"run-could-not-be-created\", outcome: \"failed\" };\n }\n log.info(\n `\u2705 Deployment notification was successful. Run created with ID: ${successfulTrigger.createdSuiteId}`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: successfulTrigger.createdSuiteId,\n };\n}\n", "import type { DeploySuccessWireResponse } from \"./deploySuccessWireResponse.js\";\nimport type { DeployStatus, DeploySuccessSuiteResult } from \"./types.js\";\n\n// An arm is classified by the outcome the backend declared, not by which keys\n// happen to be present.\nfunction mapSuiteResult(\n result: DeploySuccessWireResponse[\"results\"][number],\n): DeploySuccessSuiteResult {\n switch (result.outcome) {\n case \"created\":\n return {\n createdSuiteId: result.created_suite_id,\n triggerId: result.trigger_id,\n };\n case \"failed\":\n return {\n failureCode: result.failure_code,\n failureMessage: result.failure_message,\n failureReason: result.failure_reason,\n triggerId: result.trigger_id,\n };\n case \"skipped\":\n return {\n duplicateSuiteId: result.duplicate_suite_id,\n skipReason: result.skip_reason,\n triggerId: result.trigger_id,\n };\n default:\n // An outcome added by a newer backend: surface it explicitly rather than\n // forcing it into one of the known shapes.\n return { triggerId: result.trigger_id, unrecognized: true };\n }\n}\n\n// The deploy_success success body is the SDK's only snake_case wire shape; this\n// is the single place that renames it to the camelCase `DeployStatus` used\n// everywhere downstream.\nexport function mapDeploySuccessResponse(\n wire: DeploySuccessWireResponse,\n): DeployStatus {\n return {\n environment: wire.environment,\n results: wire.results.map(mapSuiteResult),\n skippedDeployment: wire.skipped_deployment && {\n message: wire.skipped_deployment.message,\n reason: wire.skipped_deployment.reason,\n },\n skippedTriggers: wire.skipped_triggers?.map((trigger) => ({\n environmentId: trigger.environment_id,\n message: trigger.message,\n reason: trigger.reason,\n triggerId: trigger.trigger_id,\n })),\n warning: wire.warning,\n };\n}\n", "import type { DeploySuccessWireResponse } from \"./deploySuccessWireResponse.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n // Arrays are objects too; a deploy_success body or any of its parts must be a\n // plain object, never an array. (JSON cannot produce other non-plain objects\n // such as Date or Map, so excluding arrays is sufficient here.)\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isOptionalString(value: unknown): boolean {\n return value === undefined || typeof value === \"string\";\n}\n\n// Validates each arm against the `outcome` the backend declared, matching how\n// mapSuiteResult discriminates. Keying both off the same field is what keeps an\n// outcome-based mapper from reading a missing payload field as undefined. It\n// also tightens `{ outcome: \"failed\" }` with no `failure_reason`: key-presence\n// classified that as unrecognized, and it is now an invalid body.\nfunction isWireSuiteResult(value: unknown): boolean {\n if (!isRecord(value)) return false;\n if (typeof value.trigger_id !== \"string\") return false;\n if (!isOptionalString(value.outcome)) return false;\n switch (value.outcome) {\n case \"created\":\n return typeof value.created_suite_id === \"string\";\n case \"failed\":\n return (\n typeof value.failure_reason === \"string\" &&\n isOptionalString(value.failure_code) &&\n isOptionalString(value.failure_message)\n );\n case \"skipped\":\n return (\n typeof value.duplicate_suite_id === \"string\" &&\n typeof value.skip_reason === \"string\"\n );\n default:\n // An outcome this SDK version does not know, or none at all. Accept it so\n // an older SDK does not reject the whole response; mapSuiteResult maps it\n // to an explicit unrecognized outcome.\n return true;\n }\n}\n\nfunction isEnvironment(value: unknown): boolean {\n if (!isRecord(value)) return false;\n if (typeof value.id !== \"string\") return false;\n if (typeof value.isStatic !== \"boolean\") return false;\n if (value.alias !== undefined && typeof value.alias !== \"string\")\n return false;\n return true;\n}\n\nfunction isSkippedDeployment(value: unknown): boolean {\n if (!isRecord(value)) return false;\n return typeof value.message === \"string\" && typeof value.reason === \"string\";\n}\n\nfunction isSkippedTrigger(value: unknown): boolean {\n if (!isRecord(value)) return false;\n return (\n typeof value.environment_id === \"string\" &&\n typeof value.message === \"string\" &&\n typeof value.reason === \"string\" &&\n typeof value.trigger_id === \"string\"\n );\n}\n\nfunction isDeploySuccessWireResponse(\n value: unknown,\n): value is DeploySuccessWireResponse {\n if (!isRecord(value)) return false;\n if (value.environment !== undefined && !isEnvironment(value.environment))\n return false;\n\n if (!Array.isArray(value.results) || !value.results.every(isWireSuiteResult))\n return false;\n\n if (\n value.skipped_deployment !== undefined &&\n !isSkippedDeployment(value.skipped_deployment)\n )\n return false;\n\n if (\n value.skipped_triggers !== undefined &&\n (!Array.isArray(value.skipped_triggers) ||\n !value.skipped_triggers.every(isSkippedTrigger))\n )\n return false;\n\n if (!isOptionalString(value.warning)) return false;\n\n return true;\n}\n\n// Validate the deploy_success success body at runtime instead of trusting a\n// cast. `environment` is required to be present-or-explicitly-undefined; the\n// two skip fields are optional (older servers omit them).\nexport function parseDeploySuccessWireResponse(\n value: unknown,\n): DeploySuccessWireResponse | \"invalid\" {\n return isDeploySuccessWireResponse(value) ? value : \"invalid\";\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { logFetchError } from \"../../../api/log.js\";\nimport type { LogDriver, SdkDependencies } from \"../../dependencies.js\";\n\nimport { handleSuccessResponse } from \"./handleSuccessResponse.js\";\nimport { mapDeploySuccessResponse } from \"./mapDeploySuccessResponse.js\";\nimport { parseDeploySuccessWireResponse } from \"./parseDeploySuccessWireResponse.js\";\nimport type {\n AttemptDeployHttpAbortReason,\n DeployConfig,\n NotifyDeployStatus,\n} from \"./types.js\";\n\n/**\n * @deprecated Reports through the legacy `deploy_success` webhook, which\n * triggers do not see. Use `deployment.reportStatus` instead.\n */\nexport async function attemptNotifyDeploy(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: Partial<DeployConfig>,\n): Promise<NotifyDeployStatus> {\n const { fetch: localFetch, log } = deps;\n\n let response: Response;\n let bodyText: string;\n try {\n response = await localFetch(\n new URL(\"/api/webhooks/deploy_success\", apiConfig.serviceBase),\n {\n body: JSON.stringify({\n branch: config.branch,\n commit_url: config.commitUrl,\n deduplication_key: config.deduplicationKey,\n deployment_type: config.deploymentType,\n deployment_url: config.deploymentUrl,\n ...(\"ephemeralEnvironment\" in config\n ? {\n ephemeral_environment: config.ephemeralEnvironment,\n }\n : \"hostingService\" in config && {\n hosting_service: config.hostingService,\n merge_request_number:\n config.hostingService === \"GitLab\"\n ? config.mergeRequestNumber\n : undefined,\n pull_request_number:\n config.hostingService === \"GitHub\"\n ? config.pullRequestNumber\n : undefined,\n repository: config.repository,\n }),\n sha: config.sha,\n variables: config.variables,\n workspaceId: config.workspaceId,\n }),\n headers: {\n Authorization: `Bearer ${apiConfig.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": apiConfig.userAgent,\n },\n method: \"POST\",\n // Override default timeout to 5 minutes. This gives extra room\n // for both (1) waiting for reconciliation (2) creating the run.\n signal: AbortSignal.timeout(5 * 60 * 1000),\n },\n );\n\n if (!response.ok) return handleErrorResponse(response, log);\n\n // Reading the body stream is still a network operation; a failure here is\n // a network error, not a bad payload.\n bodyText = await response.text();\n } catch {\n log.error(`\uD83D\uDEAB Network error from deploy_success, aborting.`);\n return {\n abortReason: \"network-error\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n }\n\n let rawBody: unknown;\n try {\n rawBody = JSON.parse(bodyText);\n } catch {\n return abortInvalidResponseBody(log, \"the response body was not JSON\");\n }\n\n const wire = parseDeploySuccessWireResponse(rawBody);\n if (wire === \"invalid\") {\n return abortInvalidResponseBody(\n log,\n \"the response body did not match the expected shape\",\n );\n }\n\n const data = mapDeploySuccessResponse(wire);\n return handleSuccessResponse(data, log);\n}\n\nfunction abortInvalidResponseBody(\n log: LogDriver,\n detail: string,\n): NotifyDeployStatus {\n log.error(`\uD83D\uDEAB Invalid response from deploy_success (${detail}), aborting.`);\n return {\n abortReason: \"invalid-response-body\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n}\n\nasync function handleErrorResponse(\n response: Response,\n log: LogDriver,\n): Promise<NotifyDeployStatus> {\n const status = response.status;\n let abortReason: AttemptDeployHttpAbortReason;\n if (status === undefined) abortReason = \"network-error\";\n else if (status === 401) abortReason = \"401-unauthorized\";\n else if (status === 403) abortReason = \"403-forbidden\";\n else if (status >= 500) abortReason = \"5XX-server-error\";\n else abortReason = \"4XX-client-error\";\n await logFetchError({\n log,\n methodName: \"attemptNotifyDeploy\",\n response,\n });\n return {\n abortReason,\n httpStatus: status,\n outcome: \"aborted\",\n };\n}\n", "const signedUrlPaths = {\n runInputsExecutables: \"/api/v0/run-inputs-executables-signed-urls\",\n teamStorage: \"/api/v0/team-storage-signed-url\",\n} as const;\n\nexport function buildSignedUrl({\n destinationFilePath,\n endpoint,\n serviceBase,\n workspaceId,\n}: {\n destinationFilePath: string | undefined;\n endpoint: keyof typeof signedUrlPaths;\n serviceBase: string;\n workspaceId: string | undefined;\n}): URL {\n const url = new URL(signedUrlPaths[endpoint], serviceBase);\n if (destinationFilePath !== undefined)\n url.searchParams.set(\"file\", destinationFilePath);\n if (workspaceId !== undefined)\n url.searchParams.set(\"workspaceId\", workspaceId);\n return url;\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\nimport type {\n GenerateSignedUrlConfig,\n GenerateSignedUrlResponse,\n} from \"../sdk/domain/generateSignedUrls/types.js\";\n\nimport { logFetchError } from \"./log.js\";\nimport { buildSignedUrl } from \"./signed-url.js\";\n\nexport async function callGenerateSignedUrlForRunInputsExecutablesStorage(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n { destinationFilePath, workspaceId }: GenerateSignedUrlConfig,\n { fetch: localFetch, log }: SdkDependencies,\n): Promise<GenerateSignedUrlResponse> {\n try {\n const response = await localFetch(\n buildSignedUrl({\n destinationFilePath,\n endpoint: \"runInputsExecutables\",\n serviceBase,\n workspaceId,\n }),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": userAgent,\n },\n method: \"GET\",\n },\n );\n\n if (response.status === 200) {\n const json =\n (await response.json()) as Partial<GenerateSignedUrlResponse>;\n return {\n fileLocation: json.fileLocation,\n httpStatus: response.status,\n interactiveRunFileLocation: json.interactiveRunFileLocation,\n playgroundFileLocation: json.playgroundFileLocation,\n signedUrl: json.signedUrl,\n success: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"callGenerateSignedUrlForRunInputsExecutablesStorage\",\n response,\n });\n return {\n errorMessage: await response.text(),\n httpStatus: response.status,\n success: false,\n } as const;\n } catch {\n return {\n errorMessage: \"Network error, aborting request to generate signed URL\",\n httpStatus: 0,\n success: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { callGenerateSignedUrlForRunInputsExecutablesStorage } from \"../../../api/generate-signed-url-for-run-inputs-executables.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n GenerateSignedUrlAbortReason,\n GenerateSignedUrlConfig,\n GenerateSignedUrlStatus,\n} from \"./types.js\";\n\nexport async function generateSignedUrlForRunInputsExecutablesStorage(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: GenerateSignedUrlConfig,\n): Promise<GenerateSignedUrlStatus> {\n const { log } = deps;\n\n if (!config.destinationFilePath) {\n log.error(`\uD83D\uDEAB destinationFilePath is a required config parameter`);\n return {\n abortReason: \"sdk-argument-validation-failed\",\n success: false,\n };\n }\n\n const responseState =\n await callGenerateSignedUrlForRunInputsExecutablesStorage(\n apiConfig,\n config,\n deps,\n );\n if (!responseState.success) {\n let abortReason: GenerateSignedUrlAbortReason = \"XXX-other-http-code\";\n\n if (responseState.httpStatus >= 500) {\n abortReason = \"5XX-server-error\";\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`,\n );\n } else {\n if (responseState.httpStatus === 400) abortReason = \"400-invalid-request\";\n else if (responseState.httpStatus === 401)\n abortReason = \"401-invalid-credentials\";\n else if (responseState.httpStatus === 403) abortReason = \"403-forbidden\";\n else if (responseState.httpStatus === 0)\n abortReason = \"client-network-error\";\n\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: ${responseState.errorMessage ? `${responseState.errorMessage}.` : \"\"} aborting.`,\n );\n }\n\n return {\n abortReason,\n httpStatus: responseState.httpStatus,\n success: false,\n };\n }\n\n log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);\n return {\n fileLocation: responseState.fileLocation,\n interactiveRunFileLocation: responseState.interactiveRunFileLocation,\n playgroundFileLocation: responseState.playgroundFileLocation,\n success: true,\n uploadUrl: responseState.signedUrl,\n };\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\nimport type {\n GenerateSignedUrlConfig,\n GenerateSignedUrlResponse,\n} from \"../sdk/domain/generateSignedUrls/types.js\";\n\nimport { logFetchError } from \"./log.js\";\nimport { buildSignedUrl } from \"./signed-url.js\";\n\nexport async function callGenerateSignedUrlForTempTeamStorage(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n { destinationFilePath, workspaceId }: Partial<GenerateSignedUrlConfig>,\n { fetch: localFetch, log }: SdkDependencies,\n): Promise<GenerateSignedUrlResponse> {\n try {\n const response = await localFetch(\n buildSignedUrl({\n destinationFilePath,\n endpoint: \"teamStorage\",\n serviceBase,\n workspaceId,\n }),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": userAgent,\n },\n method: \"GET\",\n },\n );\n\n if (response.status === 200) {\n const json =\n (await response.json()) as Partial<GenerateSignedUrlResponse>;\n return {\n fileLocation: json.fileLocation,\n httpStatus: response.status,\n interactiveRunFileLocation: json.interactiveRunFileLocation,\n playgroundFileLocation: json.playgroundFileLocation,\n signedUrl: json.signedUrl,\n success: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"callGenerateSignedUrlForTempTeamStorage\",\n response,\n });\n return {\n errorMessage: await response.text(),\n httpStatus: response.status,\n success: false,\n } as const;\n } catch {\n return {\n errorMessage: \"Network error, aborting request to generate signed URL\",\n httpStatus: 0,\n success: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { callGenerateSignedUrlForTempTeamStorage } from \"../../../api/generate-signed-url-for-team-storage.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type { GenerateSignedUrlConfig } from \"./types.js\";\n\ntype GenerateSignedUrlStatus =\n | {\n fileLocation?: string;\n interactiveRunFileLocation?: string;\n /** @deprecated Use `interactiveRunFileLocation` instead. Will be removed in a future major version. */\n playgroundFileLocation?: string;\n success: true;\n uploadUrl?: string;\n }\n | {\n abortReason: GenerateSignedUrlAbortReason;\n httpStatus?: number;\n success: false;\n };\n\nexport type GenerateSignedUrlAbortReason =\n | \"client-network-error\"\n | \"sdk-argument-validation-failed\"\n | \"400-invalid-request\"\n | \"401-invalid-credentials\"\n | \"403-forbidden\"\n | \"5XX-server-error\"\n | \"XXX-other-http-code\";\n\nexport async function generateSignedUrlForTempTeamStorage(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: GenerateSignedUrlConfig,\n): Promise<GenerateSignedUrlStatus> {\n const { log } = deps;\n\n if (!config.destinationFilePath) {\n log.error(`\uD83D\uDEAB destinationFilePath is a required config parameter`);\n return {\n abortReason: \"sdk-argument-validation-failed\",\n success: false,\n };\n }\n\n const responseState = await callGenerateSignedUrlForTempTeamStorage(\n apiConfig,\n config,\n deps,\n );\n if (!responseState.success) {\n let abortReason: GenerateSignedUrlAbortReason = \"XXX-other-http-code\";\n\n if (responseState.httpStatus >= 500) {\n abortReason = \"5XX-server-error\";\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`,\n );\n } else {\n if (responseState.httpStatus === 400) abortReason = \"400-invalid-request\";\n else if (responseState.httpStatus === 401)\n abortReason = \"401-invalid-credentials\";\n else if (responseState.httpStatus === 403) abortReason = \"403-forbidden\";\n else if (responseState.httpStatus === 0)\n abortReason = \"client-network-error\";\n\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: ${responseState.errorMessage ? `${responseState.errorMessage}.` : \"\"} aborting.`,\n );\n }\n\n return {\n abortReason,\n httpStatus: responseState.httpStatus,\n success: false,\n };\n }\n\n log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);\n return {\n fileLocation: responseState.fileLocation,\n interactiveRunFileLocation: responseState.interactiveRunFileLocation,\n playgroundFileLocation: responseState.playgroundFileLocation,\n success: true,\n uploadUrl: responseState.signedUrl,\n };\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { logFetchError } from \"../../../api/log.js\";\nimport type { LogDriver, SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n NotifyTerminatedEphemeralEnvironmentAbortReason,\n NotifyTerminatedEphemeralEnvironmentInput,\n NotifyTerminatedEphemeralEnvironmentResult,\n TerminatedEphemeralEnvironmentSuccessResult,\n} from \"./types.js\";\n\nexport const notifyTerminatedEphemeralEnvironment = async (\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: NotifyTerminatedEphemeralEnvironmentInput,\n): Promise<NotifyTerminatedEphemeralEnvironmentResult> => {\n const { fetch: localFetch, log } = deps;\n try {\n const response = await localFetch(\n new URL(\"/api/webhooks/environment_terminated\", apiConfig.serviceBase),\n {\n body: JSON.stringify(config),\n headers: {\n Authorization: `Bearer ${apiConfig.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": apiConfig.userAgent,\n },\n method: \"POST\",\n },\n );\n if (!response.ok) return handleErrorResponse(response, log);\n const { environmentId, warning } =\n (await response.json()) as TerminatedEphemeralEnvironmentSuccessResult;\n if (warning) log.warn(`\u26A0\uFE0F ${warning}`);\n return { environmentId, outcome: \"success\" };\n } catch {\n log.error(`\uD83D\uDEAB Network error from terminate_preview_environment, aborting.`);\n return {\n abortReason: \"network-error\",\n outcome: \"aborted\",\n };\n }\n};\n\nasync function handleErrorResponse(\n response: Response,\n log: LogDriver,\n): Promise<NotifyTerminatedEphemeralEnvironmentResult> {\n const status = response.status;\n let abortReason: NotifyTerminatedEphemeralEnvironmentAbortReason;\n if (status === undefined) abortReason = \"network-error\";\n else if (status === 401) abortReason = \"401-unauthorized\";\n else if (status === 403) abortReason = \"403-forbidden\";\n else if (status === 409) abortReason = \"409-conflict\";\n else if (status >= 500) abortReason = \"5XX-server-error\";\n else abortReason = \"4XX-client-error\";\n await logFetchError({\n log,\n methodName: \"notifyTerminatedEphemeralEnvironment\",\n response,\n });\n return {\n abortReason,\n httpStatus: status,\n outcome: \"aborted\",\n };\n}\n", "import type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\n\nimport type { PollCiGreenlightStatus } from \"./types.js\";\n\n/**\n * Build the result for a completed run\n */\nexport function buildCompletedRunResult(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): PollCiGreenlightStatus {\n if (status.greenlight)\n return { greenlightStatus: status, outcome: \"success\" };\n else return { greenlightStatus: status, outcome: \"failed\" };\n}\n", "import type { PollCiGreenlightPollConfig } from \"./types.js\";\n\n/**\n * Safe default values for polling configuration.\n * If you change these values, make sure you update the JSDoc\n * comments in the PollCiGreenlightPollConfig type.\n */\nexport const pollCiGreenlightDefaults: PollCiGreenlightPollConfig = {\n abortOnSuperseded: false,\n maxRetries: 10,\n pollTimeout: 120 * 60 * 1000, // 2 hours\n retryInterval: 10 * 1000, // 10 seconds\n runInProgressInterval: 30 * 1000, // 30 seconds\n runUnderReviewInterval: 60 * 1000, // 60 seconds\n};\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\n\nimport type { CiGreenlightBugData } from \"./ci-greenlight-bug-data.js\";\nimport { logFetchError } from \"./log.js\";\n\nexport type {\n CiGreenlightBugData,\n CiGreenlightBugDetails,\n} from \"./ci-greenlight-bug-data.js\";\n\nexport type CiGreenlightStatusBase = {\n relevantRunId: string;\n relevantRunUrl: string;\n rootRunId: string;\n rootRunUrl: string;\n};\n\nexport type CiGreenlightStatusExtended = {\n relevantRunWithBugsUrl: string;\n workflowsDisabledAfterRunCount: number;\n workflowsInRunCount: number;\n workflowsUnderInvestigationCount: number;\n};\n\n/**\n * The status of a CI greenlight run. See the API documentation here for\n * more details: https://qawolf.notion.site/1b170576efea411fa785842a71e7c99e\n */\nexport type CiGreenlightStatus = CiGreenlightStatusBase &\n (\n | ({\n greenlight: boolean;\n /**\n * Human-readable copy explaining the outcome, when the server provides\n * it. Sent when QA Wolf assessed the change and ran no flows.\n */\n message?: string;\n /**\n * Stable, machine-readable code for the outcome, when the server\n * provides it. Treat as an open set of values.\n */\n reason?: string;\n runStage: \"completed\";\n } & CiGreenlightBugData &\n CiGreenlightStatusExtended)\n | ({\n greenlight: false;\n runStage: \"underReview\";\n } & CiGreenlightBugData &\n CiGreenlightStatusExtended)\n | ({\n greenlight: false;\n runStage: \"initializing\";\n } & Partial<CiGreenlightStatusExtended>)\n | ({\n greenlight: false;\n /**\n * Human-readable copy explaining why the run was canceled, when the\n * server provides it.\n */\n message?: string;\n /**\n * Stable, machine-readable code for why the run was canceled, when the\n * server provides it. Treat as an open set of values.\n */\n reason?: string;\n runStage: \"canceled\";\n } & Partial<CiGreenlightStatusExtended>)\n );\n\nexport async function fetchCiGreenlightStatus(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n {\n runId,\n }: {\n runId: string;\n },\n { fetch: localFetch, log }: SdkDependencies,\n) {\n try {\n const resp = await localFetch(\n new URL(\n `/api/v0/ci-greenlight/${encodeURIComponent(runId)}`,\n serviceBase,\n ),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"User-Agent\": userAgent,\n },\n },\n );\n\n if (resp.ok) {\n const greenlightStatus = (await resp.json()) as CiGreenlightStatus;\n return {\n greenlightStatus,\n httpStatus: resp.status,\n ok: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"fetchCiGreenlightStatus\",\n response: resp,\n });\n if (resp.status === 404) {\n return {\n canRetry: true,\n errorType: \"not-found\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n }\n if (resp.status >= 500) {\n return {\n canRetry: true,\n errorType: \"server\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n }\n return {\n canRetry: false,\n errorType: \"client\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n } catch {\n return {\n canRetry: true,\n errorType: \"network\",\n httpStatus: 0,\n ok: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { fetchCiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { sleep } from \"../../../other.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport { pollCiGreenlightDefaults } from \"./consts.js\";\nimport type {\n MakePollCiGreenlightStatusIteratorParams,\n PollCiGreenlightIteration,\n} from \"./types.js\";\n\n/**\n * Creates an async generator that yields CI greenlight status updates or abort notifications.\n *\n * This low-level API gives you full control over the polling loop, allowing you to:\n * - Inspect status after each fetch\n * - Break out of the loop based on custom criteria\n * - Add custom logging or side effects\n * - Handle abort conditions without exceptions\n *\n * The iterator yields a discriminated union with `isAborted` property:\n * - `isAborted: false` - Normal status update with run information\n * - `isAborted: true` - Terminal condition (timeout, error, canceled, etc.)\n *\n * Note: This function does not throw errors. All error conditions are yielded as\n * abort results that you must check and handle.\n *\n * @example\n * ```typescript\n * const greenlightIterator = makePollCiGreenlightStatusIterator({ runId: \"my-run-id\" });\n *\n * for await (const lastPoll of greenlightIterator) {\n * // Check for abort conditions first\n * if (lastPoll.isAborted) {\n * console.error(`Aborted: ${lastPoll.abortReason}`);\n * process.exit(1);\n * }\n *\n * // Handle normal status updates\n * const { status } = lastPoll;\n * console.log(`Current stage: ${status.runStage}`);\n *\n * // Exit with error if run reached a terminal stage without greenlight\n * if (lastPoll.isFailedTerminalStage) {\n * process.exit(1);\n * }\n * }\n * ```\n *\n */\nexport async function* makePollCiGreenlightStatusIterator(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n { runId, ...pollConfig }: MakePollCiGreenlightStatusIteratorParams,\n): AsyncGenerator<PollCiGreenlightIteration, void, unknown> {\n const { log } = deps;\n\n const {\n maxRetries = pollCiGreenlightDefaults.maxRetries,\n pollTimeout = pollCiGreenlightDefaults.pollTimeout,\n retryInterval = pollCiGreenlightDefaults.retryInterval,\n runInProgressInterval = pollCiGreenlightDefaults.runInProgressInterval,\n runUnderReviewInterval = pollCiGreenlightDefaults.runUnderReviewInterval,\n } = pollConfig;\n\n let retries = 0;\n let previousStatus: CiGreenlightStatus | undefined = undefined;\n const startedAt = Date.now();\n\n while (Date.now() - startedAt <= pollTimeout) {\n const responseState = await fetchCiGreenlightStatus(\n apiConfig,\n { runId },\n deps,\n );\n\n const elapsedMs = Date.now() - startedAt;\n\n if (!responseState.ok && !responseState.canRetry) {\n yield {\n abortReason: \"4XX-client-error\",\n elapsedMs,\n httpStatus: responseState.httpStatus,\n isAborted: true,\n };\n return;\n }\n\n if (!responseState.ok) {\n retries += 1;\n const { errorType, httpStatus } = responseState;\n if (retries > maxRetries) {\n switch (errorType) {\n case \"network\":\n yield {\n abortReason: \"network-error\",\n elapsedMs,\n httpStatus: undefined,\n isAborted: true,\n };\n break;\n case \"not-found\":\n yield {\n abortReason: \"404-run-not-found\",\n elapsedMs,\n httpStatus: httpStatus ?? 404,\n isAborted: true,\n };\n break;\n case \"server\":\n yield {\n abortReason: \"5XX-server-error\",\n elapsedMs,\n httpStatus: httpStatus ?? 500,\n isAborted: true,\n };\n break;\n default:\n throw Error(`Unexpected error type: ${errorType satisfies never}`);\n }\n return;\n }\n\n const retryLabel = `${\n httpStatus ? ` (status ${httpStatus})` : \"\"\n }, will try again... (${retries}/${maxRetries})`;\n\n if (errorType === \"network\") log.warn(`\u274C Network error${retryLabel}`);\n else if (errorType === \"not-found\")\n log.info(`\u23F3 Run not found${retryLabel}`);\n else if (errorType === \"server\") log.warn(`\u274C Server error${retryLabel}`);\n\n await sleep(retryInterval);\n continue;\n }\n\n // Success - reset retry counter\n retries = 0;\n const { greenlightStatus } = responseState;\n const stageChanged =\n !previousStatus || previousStatus.runStage !== greenlightStatus.runStage;\n\n // Determine if this is a failed terminal stage\n const isFailedTerminalStage =\n greenlightStatus.runStage === \"canceled\" ||\n (greenlightStatus.runStage === \"completed\" &&\n greenlightStatus.greenlight === false);\n\n yield {\n elapsedMs,\n isAborted: false,\n isFailedTerminalStage,\n previousStatus,\n stageChanged,\n status: greenlightStatus,\n };\n\n // Update previous status for next iteration\n previousStatus = greenlightStatus;\n\n switch (greenlightStatus.runStage) {\n case \"canceled\": {\n yield {\n abortReason: \"run-canceled\",\n elapsedMs,\n httpStatus: undefined,\n isAborted: true,\n message: greenlightStatus.message,\n reason: greenlightStatus.reason,\n };\n return;\n }\n case \"completed\":\n return;\n case \"initializing\":\n await sleep(runInProgressInterval);\n break;\n case \"underReview\":\n await sleep(runUnderReviewInterval);\n break;\n default:\n throw Error(\n `Unexpected run stage: ${greenlightStatus satisfies never}`,\n );\n }\n }\n\n // Timeout\n yield {\n abortReason: \"poll-timed-out\",\n elapsedMs: Date.now() - startedAt,\n httpStatus: undefined,\n isAborted: true,\n };\n return;\n}\n", "import type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { pluralize } from \"../../../other.js\";\n\n/**\n * Build log message for successful completed run\n */\nexport function buildSuccessLogMessage(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const { message, nonBlockingBugsCount, relevantRunUrl, workflowsInRunCount } =\n status;\n const urlInfo = `See ${relevantRunUrl}`;\n\n // A green run that executed no flows was assessed rather than tested, so the\n // generic copy would claim a run that never happened. Prefer the server's\n // explanation, as the canceled path does.\n if (workflowsInRunCount === 0 && message) return `\u2705 ${message}\\n${urlInfo}`;\n\n return `\u2705 Run passed and no blocking bugs found${\n nonBlockingBugsCount > 0\n ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(\n nonBlockingBugsCount,\n )} found`\n : \"\"\n }.\\n${urlInfo}`;\n}\n\n/**\n * Build log message for failed completed run\n */\nexport function buildFailedLogMessage(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const {\n blockingBugsCount,\n nonBlockingBugsCount,\n relevantRunWithBugsUrl,\n reproducedBugs,\n } = status;\n\n const blockingBugUrls = reproducedBugs\n .filter((bug) => bug.isBlocking)\n .map((bug) => bug.applicationUrl);\n const nonBlockingBugUrls = reproducedBugs\n .filter((bug) => !bug.isBlocking)\n .map((bug) => bug.applicationUrl);\n\n const blockingBugList = blockingBugUrls.map((url) => `\\n\u2022 ${url}`).join(\"\");\n const nonBlockingBugList = nonBlockingBugUrls\n .map((url) => `\\n\u2022 ${url}`)\n .join(\"\");\n const bugsListInText = `${\n blockingBugUrls.length > 0 ? `\\nBLOCKING BUGS:${blockingBugList}` : \"\"\n }${\n nonBlockingBugUrls.length > 0\n ? `\\nNON BLOCKING BUGS:${nonBlockingBugList}`\n : \"\"\n }`;\n\n return (\n `\u274C Run failed and ${blockingBugsCount} blocking bug${pluralize(\n blockingBugsCount,\n )} found${\n nonBlockingBugsCount\n ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(\n nonBlockingBugsCount,\n )}`\n : \"\"\n }.\\nSee ${relevantRunWithBugsUrl}\\n` +\n \"You may review the priority of certain bugs to mark these non-blocking and retry the job.\\n\" +\n bugsListInText\n );\n}\n\n/**\n * Build log message for superseded run (aborting)\n */\nexport function buildSupersededAbortLogMessage(\n rootRunUrl: string,\n relevantRunUrl: string,\n): string {\n const supersedingDetails = `\n - Root: ${rootRunUrl}\n - Superseding: ${relevantRunUrl}`;\n\n return `\u274C Aborting due to superseded run (option 'abortOnSuperseded' is enabled).${supersedingDetails}`;\n}\n\n/**\n * Build log message for superseded run (continuing)\n */\nexport function buildSupersededContinueLogMessage(\n rootRunUrl: string,\n relevantRunUrl: string,\n): string {\n const supersedingDetails = `\n - Root: ${rootRunUrl}\n - Superseding: ${relevantRunUrl}`;\n\n return `Root run was superseded:${supersedingDetails}`;\n}\n\n/**\n * Build log messages for different run stages\n */\nexport function buildRunStageLogMessage(\n status: Exclude<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const { relevantRunUrl, runStage } = status;\n const urlInfo = `See ${relevantRunUrl}`;\n\n switch (runStage) {\n case \"canceled\":\n return `\uD83D\uDEAB Run was canceled. ${\n status.message || \"Aborting... Please contact support.\"\n }\\n${urlInfo}`;\n case \"initializing\":\n return `\u23F3 Run is in progress... ${urlInfo}`;\n case \"underReview\":\n return `\uD83D\uDD75\uFE0F Run is under review... ${urlInfo}`;\n default:\n throw Error(`Unexpected run stage: ${runStage satisfies never}`);\n }\n}\n", "import type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n PollCiGreenlightIteratorHttpAborted,\n PollCiGreenlightIteratorNonHttpAborted,\n PollCiGreenlightStatus,\n} from \"./types.js\";\n\n/**\n * Handles aborted iterations from the CI greenlight poll iterator\n * and converts them to appropriate result objects with logging\n */\nexport function mapIteratorAbortToGreenlightStatus(\n iteration:\n | PollCiGreenlightIteratorHttpAborted\n | PollCiGreenlightIteratorNonHttpAborted,\n pollTimeout: number,\n deps: SdkDependencies,\n): PollCiGreenlightStatus {\n const { log } = deps;\n const { abortReason, httpStatus } = iteration;\n\n switch (abortReason) {\n case \"4XX-client-error\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"5XX-server-error\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"404-run-not-found\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"network-error\":\n log.error(`\uD83D\uDEAB Unrecoverable network error from CI greenlight, aborting.`);\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"poll-timed-out\":\n log.warn(`\u274C Poll timed out after ${pollTimeout / 1000}s`);\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"run-canceled\":\n log.info(\n iteration.message\n ? `Run was canceled. ${iteration.message}`\n : `Run was canceled`,\n );\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"XXX-other-http-code\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n default:\n throw Error(`Unexpected abort reason: ${abortReason satisfies never}`);\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport { buildCompletedRunResult } from \"./buildCompletedRunResult.js\";\nimport { pollCiGreenlightDefaults } from \"./consts.js\";\nimport { makePollCiGreenlightStatusIterator } from \"./iterator.js\";\nimport {\n buildFailedLogMessage,\n buildRunStageLogMessage,\n buildSuccessLogMessage,\n buildSupersededAbortLogMessage,\n buildSupersededContinueLogMessage,\n} from \"./logging.js\";\nimport { mapIteratorAbortToGreenlightStatus } from \"./mapIteratorAbortToGreenlightStatus.js\";\nimport type {\n PollCiGreenlightParams,\n PollCiGreenlightStatus,\n} from \"./types.js\";\n\n/**\n * @deprecated Polls a run id that only `attemptNotifyDeploy` returns, so it\n * keeps the pipeline on the legacy `deploy_success` webhook.\n */\nexport async function pollCiGreenlightStatus(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n {\n onRunStageChanged = () => undefined,\n runId,\n ...pollConfig\n }: PollCiGreenlightParams,\n): Promise<PollCiGreenlightStatus> {\n const { log } = deps;\n const {\n abortOnSuperseded = pollCiGreenlightDefaults.abortOnSuperseded,\n pollTimeout = pollCiGreenlightDefaults.pollTimeout,\n } = pollConfig;\n\n const iterator = makePollCiGreenlightStatusIterator(deps, apiConfig, {\n runId,\n ...pollConfig,\n });\n\n for await (const lastPoll of iterator) {\n if (lastPoll.isAborted)\n return mapIteratorAbortToGreenlightStatus(lastPoll, pollTimeout, deps);\n\n // Handle status iterations\n const { previousStatus, stageChanged, status } = lastPoll;\n\n // Call onRunStageChanged callback when stage changes\n if (stageChanged) {\n try {\n await onRunStageChanged(status, previousStatus);\n } catch (e) {\n log.error(`Error in onRunStageChanged callback`, e);\n }\n }\n\n const { relevantRunId, relevantRunUrl, rootRunId, rootRunUrl, runStage } =\n status;\n\n // Superseded run handling\n const isSuperseded = rootRunId !== relevantRunId;\n const shouldAbortOnSuperseded = isSuperseded && abortOnSuperseded;\n if (shouldAbortOnSuperseded) {\n const message = buildSupersededAbortLogMessage(\n rootRunUrl,\n relevantRunUrl,\n );\n log.warn(message);\n return {\n abortReason: \"superseded-run\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n }\n if (isSuperseded) {\n const message = buildSupersededContinueLogMessage(\n rootRunUrl,\n relevantRunUrl,\n );\n log.info(message);\n }\n\n switch (runStage) {\n case \"canceled\":\n case \"initializing\":\n case \"underReview\": {\n log.info(buildRunStageLogMessage(status));\n break;\n }\n case \"completed\": {\n const result = buildCompletedRunResult(status);\n switch (result.outcome) {\n case \"aborted\": {\n break;\n }\n case \"failed\": {\n const message = buildFailedLogMessage(status);\n log.warn(message);\n break;\n }\n case \"success\": {\n const message = buildSuccessLogMessage(status);\n log.info(message);\n break;\n }\n default:\n throw Error(`Unexpected outcome: ${result satisfies never}`);\n }\n return result;\n }\n default:\n throw Error(`Unexpected run stage: ${runStage satisfies never}`);\n }\n }\n\n // This should never be reached as the iterator handles timeout\n throw Error(\"Iterator ended unexpectedly\");\n}\n", "import { publicContractsV1 } from \"@qawolf/api-contracts\";\n\nimport type { ApiConfig } from \"../../../api-types.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\nimport type { PublicApiCallFailure } from \"../../publicApi/callContract.js\";\nimport { callPublicContract } from \"../../publicApi/callContract.js\";\n\nimport type {\n ReportDeploymentParams,\n ReportDeploymentResult,\n} from \"./types.js\";\n\nexport async function reportDeployment(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n params: ReportDeploymentParams,\n): Promise<ReportDeploymentResult> {\n const result = await callPublicContract(deps, apiConfig, {\n contract: publicContractsV1.deployment.reportStatus,\n input: params,\n });\n if (result.outcome !== \"ok\") return mapFailure(result);\n\n const { deployment } = result.data;\n deps.log.info(\n `\u2705 Deployment ${deployment.id} reported as ${deployment.status}: ${deployment.url}`,\n );\n return { deployment, outcome: \"reported\" };\n}\n\nfunction mapFailure(result: PublicApiCallFailure): ReportDeploymentResult {\n if (result.outcome !== \"http-error\") return { outcome: result.outcome };\n const { httpStatus, message } = result;\n if (httpStatus === 400) return { message, outcome: \"invalid-request\" };\n if (httpStatus === 401 || httpStatus === 403)\n return { message, outcome: \"unauthorized\" };\n if (httpStatus === 404) return { message, outcome: \"not-found\" };\n if (httpStatus === 409) return { message, outcome: \"conflict\" };\n if (httpStatus >= 500) return { httpStatus, outcome: \"server-error\" };\n return { httpStatus, message, outcome: \"unexpected-status\" };\n}\n", "import type { z } from \"zod\";\n\nimport type { ApiConfig } from \"../../api-types.js\";\nimport type { LogDriver, SdkDependencies } from \"../dependencies.js\";\n\n/**\n * The structural shape of a `@qawolf/api-contracts` contract. Declared here\n * because the package exports the contracts but not the type describing them.\n */\nexport type PublicApiContract<InputData = unknown, OutputData = unknown> = {\n input: z.ZodType<unknown, InputData>;\n name: string;\n output: z.ZodType<OutputData>;\n};\n\nexport type PublicApiCallFailure =\n | {\n /** The QA Wolf incident id to quote to support, when the server sent one. */\n eventId: string | undefined;\n httpStatus: number;\n /** The server's explanation of the refusal, when it sent one. */\n message: string | undefined;\n outcome: \"http-error\";\n }\n | { outcome: \"network-error\" }\n /** The server answered 2xx with a body the contract's output rejects. */\n | { outcome: \"invalid-response-body\" };\n\nexport type PublicApiCallResult<Data> =\n | { data: Data; outcome: \"ok\" }\n | PublicApiCallFailure;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n// A superjson envelope is exactly `{ json }`, plus `meta` when the payload\n// carries a type JSON cannot express. Anything else is the payload itself, so a\n// contract whose own output has a `json` field is not unwrapped by mistake.\nfunction isSuperJsonEnvelope(data: Record<string, unknown>): boolean {\n return (\n \"json\" in data &&\n Object.keys(data).every((key) => key === \"json\" || key === \"meta\")\n );\n}\n\n// tRPC wraps a procedure's output as `{ result: { data } }`, and the server's\n// superjson transformer nests the payload one level further under `json`.\nfunction unwrapTrpcEnvelope(body: unknown): unknown {\n if (!isRecord(body) || !isRecord(body.result)) return undefined;\n const data = body.result.data;\n return isRecord(data) && isSuperJsonEnvelope(data) ? data.json : data;\n}\n\n// A tRPC error body is `{ error: { json: { message, data: { eventId } } } }`\n// under the server's superjson transformer, or the same without `json`.\nfunction readTrpcError(body: unknown): {\n eventId: string | undefined;\n message: string | undefined;\n} {\n const wrapped = isRecord(body) ? body.error : undefined;\n const error =\n isRecord(wrapped) && isRecord(wrapped.json) ? wrapped.json : wrapped;\n if (!isRecord(error)) return { eventId: undefined, message: undefined };\n const data = isRecord(error.data) ? error.data : undefined;\n return {\n eventId: typeof data?.eventId === \"string\" ? data.eventId : undefined,\n message: typeof error.message === \"string\" ? error.message : undefined,\n };\n}\n\nfunction parseJson(text: string | undefined): unknown {\n if (text === undefined) return undefined;\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\nasync function readHttpError(\n response: Response,\n contractName: string,\n log: LogDriver,\n): Promise<PublicApiCallFailure> {\n const bodyText = await response.text().catch(() => undefined);\n const { eventId, message } = readTrpcError(parseJson(bodyText));\n const statusText =\n response.status >= 500\n ? \"Server Error\"\n : response.statusText || \"Unknown Error\";\n const eventIdSuffix = eventId ? ` (Event ID: ${eventId})` : \"\";\n const messageSuffix = message ? `: ${message}` : \"\";\n log.error(\n `\u274C [${contractName}] ${response.status} ${statusText}${eventIdSuffix}${messageSuffix}`,\n );\n return {\n eventId,\n httpStatus: response.status,\n message,\n outcome: \"http-error\",\n };\n}\n\n/**\n * Calls one public API contract and validates the answer with that contract's\n * own output schema, so a caller reads the contract's types rather than a\n * hand-written copy of them.\n */\nexport async function callPublicContract<InputData, OutputData>(\n { fetch: localFetch, log }: SdkDependencies,\n apiConfig: ApiConfig,\n {\n contract,\n input,\n }: {\n contract: PublicApiContract<InputData, OutputData>;\n input: InputData;\n },\n): Promise<PublicApiCallResult<OutputData>> {\n // The public contracts are served under the `public` tRPC namespace.\n const procedurePath = `public.${contract.name}`;\n\n let bodyText: string;\n try {\n const response = await localFetch(\n new URL(`/api/trpc/${procedurePath}`, apiConfig.serviceBase),\n {\n // The server's superjson transformer reads the input from `json`.\n body: JSON.stringify({ json: input }),\n headers: {\n Authorization: `Bearer ${apiConfig.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": apiConfig.userAgent,\n },\n method: \"POST\",\n },\n );\n\n if (!response.ok) return readHttpError(response, contract.name, log);\n\n // Reading the body stream is still a network operation; a failure here is\n // a network error, not a bad payload.\n bodyText = await response.text();\n } catch {\n log.error(`\uD83D\uDEAB Network error from ${contract.name}, aborting.`);\n return { outcome: \"network-error\" };\n }\n\n const parsed = contract.output.safeParse(\n unwrapTrpcEnvelope(parseJson(bodyText)),\n );\n if (!parsed.success) {\n log.error(\n `\uD83D\uDEAB Invalid response from ${contract.name} (${parsed.error.issues[0]?.message ?? \"the response body did not match the contract\"}), aborting.`,\n );\n return { outcome: \"invalid-response-body\" };\n }\n\n return { data: parsed.data, outcome: \"ok\" };\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport { buildFetchWithTimeout } from \"../other.js\";\n\nimport { defaultFetch } from \"./defaults/fetch.js\";\nimport { defaultLogDriver } from \"./defaults/log.js\";\nimport { defaultServiceBase } from \"./defaults/serviceBase.js\";\nimport { defaultUserAgent } from \"./defaults/userAgent.js\";\nimport type { SdkDependencies } from \"./dependencies.js\";\nimport { attemptNotifyDeploy } from \"./domain/attemptDeploy/index.js\";\nimport { generateSignedUrlForRunInputsExecutablesStorage } from \"./domain/generateSignedUrls/generate-signed-url-for-run-inputs-executables.js\";\nimport { generateSignedUrlForTempTeamStorage } from \"./domain/generateSignedUrls/generate-signed-url-for-team-storage.js\";\nimport { notifyTerminatedEphemeralEnvironment } from \"./domain/notifyTerminatedEphemeralEnvironment/index.js\";\nimport { pollCiGreenlightStatus } from \"./domain/pollCiGreenlight/index.js\";\nimport { makePollCiGreenlightStatusIterator } from \"./domain/pollCiGreenlight/iterator.js\";\nimport { reportDeployment } from \"./domain/reportDeployment/index.js\";\n\nexport function makeQaWolfSdk(\n {\n apiKey,\n serviceBase = defaultServiceBase,\n userAgent = defaultUserAgent,\n }: {\n apiKey: string;\n serviceBase?: string;\n userAgent?: string;\n },\n {\n fetch = defaultFetch,\n log = defaultLogDriver,\n }: Partial<SdkDependencies> = {},\n) {\n if (typeof fetch !== \"function\") {\n throw Error(\n `QA Wolf CI-SDK requires fetch to be defined. Make sure you are using NodeJS 18+, OR pass a fetch polyfill to the makeQaWolfSdk function.\nWe recommend 'undici' package for that purpose. See the Requirement section of our README for more guidance.`,\n );\n }\n\n const deps: SdkDependencies = {\n // Versions of fetch may have different default timeouts. For consistency, we explicitly set it to 2 minutes here.\n // The increased timeout helps avoid edge cases where we need to search for a commit against multiple\n // code hosting service repositories as a fallback when not finding the repository based on organization/name.\n fetch: buildFetchWithTimeout(fetch, 120000),\n log,\n };\n const apiConfig: ApiConfig = { apiKey, serviceBase, userAgent };\n return {\n /**\n * @deprecated Reports through the legacy `deploy_success` webhook, which\n * triggers do not see. Use `deployment.reportStatus` instead.\n */\n attemptNotifyDeploy: attemptNotifyDeploy.bind(null, deps, apiConfig),\n deployment: {\n reportStatus: reportDeployment.bind(null, deps, apiConfig),\n },\n generateSignedUrlForRunInputsExecutablesStorage:\n generateSignedUrlForRunInputsExecutablesStorage.bind(\n null,\n deps,\n apiConfig,\n ),\n generateSignedUrlForTempTeamStorage:\n generateSignedUrlForTempTeamStorage.bind(null, deps, apiConfig),\n makePollCiGreenlightStatusIterator: makePollCiGreenlightStatusIterator.bind(\n null,\n deps,\n apiConfig,\n ),\n notifyTerminatedEphemeralEnvironment:\n notifyTerminatedEphemeralEnvironment.bind(null, deps, apiConfig),\n /**\n * @deprecated Polls a run id that only `attemptNotifyDeploy` returns, so it\n * keeps the pipeline on the legacy `deploy_success` webhook.\n */\n pollCiGreenlightStatus: pollCiGreenlightStatus.bind(null, deps, apiConfig),\n };\n}\n\nexport type * from \"./domain/attemptDeploy/index.js\";\nexport type * from \"./domain/generateSignedUrls/types.js\";\nexport type * from \"./domain/notifyTerminatedEphemeralEnvironment/types.js\";\nexport type * from \"./domain/pollCiGreenlight/types.js\";\nexport type * from \"./domain/reportDeployment/types.js\";\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["handleErrorResponse", "isRecord"]
|
|
3
|
+
"sources": ["../src/lib/sdk/domain/detectProviderDeploymentId/index.ts", "../src/lib/other.ts", "../src/lib/sdk/defaults/clock.ts", "../src/lib/sdk/defaults/fetch.ts", "../src/lib/sdk/defaults/log.ts", "../src/lib/sdk/defaults/serviceBase.ts", "../package.json", "../src/lib/sdk/defaults/userAgent.ts", "../src/lib/api/log.ts", "../src/lib/sdk/domain/attemptDeploy/handleSuccessResponse.ts", "../src/lib/sdk/domain/attemptDeploy/mapDeploySuccessResponse.ts", "../src/lib/sdk/domain/attemptDeploy/parseDeploySuccessWireResponse.ts", "../src/lib/sdk/domain/attemptDeploy/index.ts", "../src/lib/api/signed-url.ts", "../src/lib/api/generate-signed-url-for-run-inputs-executables.ts", "../src/lib/sdk/domain/generateSignedUrls/generate-signed-url-for-run-inputs-executables.ts", "../src/lib/api/generate-signed-url-for-team-storage.ts", "../src/lib/sdk/domain/generateSignedUrls/generate-signed-url-for-team-storage.ts", "../src/lib/sdk/domain/notifyTerminatedEphemeralEnvironment/index.ts", "../src/lib/sdk/domain/pollCiGreenlight/buildCompletedRunResult.ts", "../src/lib/sdk/domain/pollCiGreenlight/consts.ts", "../src/lib/api/ci-greenlight.ts", "../src/lib/sdk/domain/pollCiGreenlight/iterator.ts", "../src/lib/sdk/domain/pollCiGreenlight/logging.ts", "../src/lib/sdk/domain/pollCiGreenlight/mapIteratorAbortToGreenlightStatus.ts", "../src/lib/sdk/domain/pollCiGreenlight/index.ts", "../src/lib/sdk/domain/reportDeployment/index.ts", "../src/lib/sdk/publicApi/callContract.ts", "../src/lib/sdk/domain/waitForVerdict/awaitRuns.ts", "../src/lib/sdk/domain/waitForVerdict/failures.ts", "../src/lib/sdk/domain/waitForVerdict/poll.ts", "../src/lib/sdk/domain/waitForVerdict/progress.ts", "../src/lib/sdk/domain/waitForVerdict/readEvaluations.ts", "../src/lib/sdk/domain/waitForVerdict/awaitVerdict.ts", "../src/lib/sdk/domain/waitForVerdict/consts.ts", "../src/lib/sdk/domain/waitForVerdict/logVerdict.ts", "../src/lib/sdk/domain/waitForVerdict/index.ts", "../src/lib/sdk/index.ts"],
|
|
4
|
+
"sourcesContent": ["export type CiSystem =\n | \"bitbucket\"\n | \"buildkite\"\n | \"circleci\"\n | \"github\"\n | \"gitlab\"\n | \"jenkins\";\n\nexport type DetectedProviderDeploymentId =\n | {\n ci: CiSystem;\n /**\n * An identity that is distinct for every job definition and every\n * re-run, e.g. `18273645-2-deploy` on GitHub Actions, plus the\n * `discriminator` when one was given.\n */\n id: string;\n outcome: \"detected\";\n }\n | {\n ci: CiSystem;\n /**\n * The CI system was recognized but did not expose every variable the\n * identity is composed from.\n */\n missingVariables: string[];\n outcome: \"missing-variables\";\n }\n | { outcome: \"unsupported\" };\n\ntype CiEnvironment = Record<string, string | undefined>;\n\nexport type DetectProviderDeploymentIdOptions = {\n /**\n * Appended to the composed id. Required whenever one job definition deploys\n * more than once at a time \u2014 a GitHub Actions or Jenkins matrix, a CircleCI\n * job with `parallelism`, a loop over environment names \u2014 because no CI\n * system exposes the leg it is running as a variable. Pass the matrix\n * values, the environment name, or anything else that tells the concurrent\n * deployments apart. It is appended after a colon.\n */\n discriminator?: string;\n /** The variables to read, defaulting to `process.env`. */\n env?: CiEnvironment;\n};\n\ntype CiSystemDefinition = {\n ci: CiSystem;\n isActive: (env: CiEnvironment) => boolean;\n /** Joined in order into the id; all of them must be present. */\n variables: string[];\n};\n\nconst ciSystems: CiSystemDefinition[] = [\n {\n ci: \"github\",\n isActive: (env) => env.GITHUB_ACTIONS === \"true\",\n // GITHUB_RUN_ID is stable across re-runs and GITHUB_RUN_ATTEMPT increments,\n // and both are shared by every job in the workflow, so GITHUB_JOB separates\n // jobs that deploy in parallel. GITHUB_JOB names the job definition, which\n // every leg of a matrix shares, so those legs need a discriminator.\n variables: [\"GITHUB_RUN_ID\", \"GITHUB_RUN_ATTEMPT\", \"GITHUB_JOB\"],\n },\n {\n ci: \"gitlab\",\n isActive: (env) => env.GITLAB_CI === \"true\",\n // Retrying a job keeps the pipeline id and mints a new job id.\n variables: [\"CI_PIPELINE_ID\", \"CI_JOB_ID\"],\n },\n {\n ci: \"circleci\",\n isActive: (env) => env.CIRCLECI === \"true\",\n // A rerun keeps the workflow id and allocates a new build number. A job\n // run with `parallelism` shares both across its containers, so those need\n // a discriminator.\n variables: [\"CIRCLE_WORKFLOW_ID\", \"CIRCLE_BUILD_NUM\"],\n },\n {\n ci: \"buildkite\",\n isActive: (env) => env.BUILDKITE === \"true\",\n // BUILDKITE_BUILD_ID covers the whole build, so BUILDKITE_JOB_ID separates\n // the jobs within it and BUILDKITE_RETRY_COUNT separates a job's retries.\n variables: [\n \"BUILDKITE_BUILD_ID\",\n \"BUILDKITE_JOB_ID\",\n \"BUILDKITE_RETRY_COUNT\",\n ],\n },\n {\n ci: \"jenkins\",\n // JENKINS_URL is unset on some agent configurations.\n isActive: (env) =>\n env.JENKINS_URL !== undefined || env.JENKINS_HOME !== undefined,\n // BUILD_TAG is `jenkins-${JOB_NAME}-${BUILD_NUMBER}`, and Jenkins allocates\n // a fresh BUILD_NUMBER for every externally visible re-run \u2014 Rebuild,\n // Naginator, Replay and Restart from Stage \u2014 so it needs no attempt\n // counter. An in-pipeline `retry {}` reuses it, but reports nothing new.\n // A declarative `matrix` or `parallel` block runs its branches inside one\n // build and so shares BUILD_TAG; those branches need a discriminator.\n variables: [\"BUILD_TAG\"],\n },\n {\n ci: \"bitbucket\",\n isActive: (env) =>\n env.BITBUCKET_WORKSPACE !== undefined ||\n env.BITBUCKET_BUILD_NUMBER !== undefined,\n // Rerunning a whole pipeline mints a new build number, but rerunning only\n // the failed steps keeps it and increments the step's run number instead.\n // Parallel steps share both, so BITBUCKET_STEP_UUID separates them.\n variables: [\n \"BITBUCKET_BUILD_NUMBER\",\n \"BITBUCKET_STEP_UUID\",\n \"BITBUCKET_STEP_RUN_NUMBER\",\n ],\n },\n];\n\n/**\n * Derives a `providerDeploymentId` from the CI system's own environment\n * variables. Run ids are usually shared by a build's jobs and stable across\n * re-runs, so the id composes the run with the job and the attempt; without\n * that, a re-run or a sibling job would report into a deployment whose first\n * success report already evaluated triggers, and create no run.\n *\n * The id is distinct per job definition and per attempt only. Concurrent\n * deployments from one job definition \u2014 a matrix leg, a loop over\n * environments \u2014 are indistinguishable in the environment, so pass a\n * `discriminator` for them or compose the `providerDeploymentId` yourself.\n */\nexport function detectProviderDeploymentId({\n discriminator,\n env = process.env,\n}: DetectProviderDeploymentIdOptions = {}): DetectedProviderDeploymentId {\n const system = ciSystems.find((candidate) => candidate.isActive(env));\n if (!system) return { outcome: \"unsupported\" };\n\n const missingVariables = system.variables.filter((name) => !env[name]);\n if (missingVariables.length > 0)\n return { ci: system.ci, missingVariables, outcome: \"missing-variables\" };\n\n const composed = system.variables.map((name) => env[name]).join(\"-\");\n return {\n ci: system.ci,\n // A colon separates the discriminator because a job id can itself contain\n // a hyphen, so joining with one would let job \"deploy-web\" collide with\n // job \"deploy\" discriminated by \"web\".\n id: discriminator ? `${composed}:${discriminator}` : composed,\n outcome: \"detected\",\n };\n}\n", "import type { FetchDriver } from \"./sdk/dependencies.js\";\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function pluralize(count: number) {\n return count === 1 ? \"\" : \"s\";\n}\n\nexport function getBackoffMs(\n attemptNumber: number,\n minWaitMs = 1000,\n maxWaitMs = 10000,\n): number {\n return Math.min(maxWaitMs, minWaitMs * 1.2 ** attemptNumber);\n}\n\nexport const buildFetchWithTimeout =\n (fetch: FetchDriver, defaultTimeoutMs: number) =>\n async (...args: Parameters<FetchDriver>) => {\n // Allow signal to be overridden by the caller\n const signal = args[1]?.signal ?? AbortSignal.timeout(defaultTimeoutMs);\n\n return fetch(args[0], { ...args[1], signal });\n };\n", "import { sleep } from \"../../other.js\";\nimport type { ClockDriver } from \"../dependencies.js\";\n\nexport const defaultClock: ClockDriver = { now: () => Date.now(), sleep };\n", "export const defaultFetch = globalThis.fetch;\n", "import type { LogDriver } from \"../dependencies.js\";\n\nexport const defaultLogDriver: LogDriver = {\n error(message, error) {\n console.error(message, error);\n },\n info(message) {\n console.log(message);\n },\n warn(message) {\n console.warn(message);\n },\n};\n", "export const defaultServiceBase = \"https://app.qawolf.com/\";\n", "{\n \"name\": \"@qawolf/ci-sdk\",\n \"version\": \"3.2.0\",\n \"private\": false,\n \"description\": \"A simple SDK for interacting with QAWolf in CI scripts.\",\n \"keywords\": [],\n \"license\": \"MIT\",\n \"author\": \"Jules Sam. Randolph<jules@qawolf.com>\",\n \"files\": [\n \"/dist\",\n \"/README.md\"\n ],\n \"type\": \"module\",\n \"sideEffects\": false,\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n }\n },\n \"scripts\": {\n \"build\": \"platform-builder --config platformBuilder.config.ts\",\n \"lint:ci\": \"npm run lint:first-half; FIRST_HALF_EXIT=$?; npm run lint:second-half && exit $FIRST_HALF_EXIT\",\n \"lint:dev\": \"npm run lint:first-half\",\n \"lint:first-half\": \"oxlint . --fix --quiet --report-unused-disable-directives --type-aware && oxfmt --write .\",\n \"lint:second-half\": \"rev-dep config run\",\n \"prepublishOnly\": \"nx run ci-sdk:build\",\n \"test\": \"NODE_OPTIONS=\\\"--experimental-vm-modules\\\" NODE_NO_WARNINGS=1 jest\",\n \"tsc:check\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@qawolf/api-contracts\": \">=0.71.0\",\n \"@qawolf/ci-utils\": \"^2.0.0\",\n \"@sinonjs/fake-timers\": \"^10.3.0\",\n \"tslib\": \"^2.6.2\",\n \"zod\": \"^4.1.11\"\n },\n \"devDependencies\": {\n \"@qawolf/platform-builder\": \"^1.2.7\",\n \"tsx\": \"^4.19.4\",\n \"typescript\": \"^5.9.3\"\n },\n \"engines\": {\n \"node\": \">=24.14.1 <25\"\n }\n}\n", "import packageJson from \"../../../../package.json\" with { type: \"json\" };\n\nexport const defaultUserAgent = `ci-sdk/${packageJson.version}`;\n", "import type { LogDriver } from \"@qawolf/ci-utils\";\n\nexport async function logFetchError({\n log,\n methodName,\n response,\n}: {\n log: LogDriver;\n methodName: string;\n response: Response;\n}) {\n if (response.ok) return;\n\n const { eventId, failureMessage } = await (async () => {\n try {\n const body = (await response.json().catch(() => response.text())) as\n | Record<string, unknown>\n | string;\n if (typeof body === \"object\" && body !== null) {\n return {\n eventId: body.eventId,\n failureMessage: body.failureMessage,\n };\n }\n // If body is not an object (i.e., it's the text from catch)\n return {\n eventId: undefined,\n failureMessage: body,\n };\n } catch {\n // If both parsing attempts somehow fail\n return {\n eventId: undefined,\n failureMessage: undefined,\n };\n }\n })();\n\n const eventIdSuffix = eventId ? ` (Event ID: ${eventId})` : \"\";\n const messageSuffix = failureMessage ? `: ${failureMessage}` : \"\";\n\n const statusText =\n response.status >= 500\n ? \"Server Error\"\n : response.statusText || \"Unknown Error\";\n\n log.error(\n `\u274C [${methodName}] ${response.status} ${statusText}${eventIdSuffix}${messageSuffix}`,\n );\n}\n", "import type { LogDriver } from \"../../dependencies.js\";\n\nimport type { DeployStatus, NotifyDeployStatus } from \"./types.js\";\n\nexport async function handleSuccessResponse(\n data: DeployStatus,\n log: LogDriver,\n): Promise<NotifyDeployStatus> {\n const { environment, results } = data;\n const skippedTriggers = data.skippedTriggers ?? [];\n const skippedDeployment = data.skippedDeployment;\n const isPreviewDeployment = environment && !environment.isStatic;\n\n if (data.warning) log.warn(`\u26A0\uFE0F ${data.warning}`);\n\n if (environment) {\n const logPrefix = environment.isStatic\n ? \"Static environment\"\n : \"Preview environment\";\n log.info(`${logPrefix}: ${environment.alias} (id: ${environment.id})`);\n }\n\n // No suites were created for this deployment.\n if (results.length === 0) {\n const skipMessages = [\n ...skippedTriggers.map((trigger) => trigger.message),\n ...(skippedDeployment ? [skippedDeployment.message] : []),\n ];\n const skipDetail =\n skipMessages.length > 0 ? ` ${skipMessages.join(\" \")}` : \"\";\n\n // Preview deployments legitimately often produce no run; keep the success\n // outcome but surface any skip reason so it is not silently dropped.\n if (isPreviewDeployment) {\n log.info(\n `\u2705 Deployment notification was successful. No run was created for this deployment.${skipDetail}`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: undefined,\n };\n }\n\n // A trigger matched but could not run (e.g. environment still syncing).\n // Only a backend that still sends skipped_triggers reaches this arm. Current\n // backends omit the field, so those responses bypass it and fall to the\n // generic \"no trigger matched\" warning below even when a trigger did match.\n if (skippedTriggers.length > 0) {\n log.error(`\uD83D\uDEAB No run was created for this deployment.${skipDetail}`);\n return {\n failReason: \"trigger-skipped\",\n outcome: \"failed\",\n skippedTriggers,\n };\n }\n\n log.warn(\n skippedDeployment\n ? `\u26A0\uFE0F No run was created for this deployment.${skipDetail}`\n : `\u26A0\uFE0F No trigger matched the request. Please make sure there is at least one active test in the QA Wolf environment, or contact support.`,\n );\n return {\n outcome: \"skipped\",\n skippedDeployment,\n };\n }\n\n // If there are results, environment must be defined\n if (!environment) {\n log.error(`\uD83D\uDEAB No environment matched the request. Please contact support.`);\n return { failReason: \"no-environment\", outcome: \"failed\" };\n }\n\n // A result arm this SDK version does not recognize (newer backend). We cannot\n // classify the outcome, so surface it as a failure rather than guessing.\n const unrecognizedResult = results.find((result) => \"unrecognized\" in result);\n if (unrecognizedResult) {\n log.error(\n `\uD83D\uDEAB The deployment response contained an unrecognized result. Please upgrade @qawolf/ci-sdk.`,\n );\n return { failReason: \"unknown-result\", outcome: \"failed\" };\n }\n\n const failedTrigger = results.find((result) => \"failureReason\" in result);\n if (failedTrigger) {\n // Prefer the customer-facing message; older backends send only the internal\n // reason, which is all we can show in that case.\n log.error(\n `\uD83D\uDEAB Run could not be created. Reason: \"${failedTrigger.failureMessage ?? failedTrigger.failureReason}\". Please contact support.`,\n );\n return { failReason: \"run-could-not-be-created\", outcome: \"failed\" };\n }\n\n const duplicateSuite = results.find((result) => \"duplicateSuiteId\" in result);\n if (duplicateSuite) {\n log.info(\n `\u2705 Deployment notification was successful. Previous run ID: ${duplicateSuite.duplicateSuiteId} already exists for this deployment.`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: duplicateSuite.duplicateSuiteId,\n };\n }\n\n const successfulTrigger = results.find(\n (result) => \"createdSuiteId\" in result,\n );\n if (!successfulTrigger) {\n // results is non-empty here, so triggers did match \u2014 this is not the\n // deterministic no-trigger-match skip. Reaching this point means the\n // response carried results we could not turn into a run, so it is an\n // unexpected failure rather than a skip.\n log.error(`\uD83D\uDEAB Run could not be created. Please contact support.`);\n return { failReason: \"run-could-not-be-created\", outcome: \"failed\" };\n }\n log.info(\n `\u2705 Deployment notification was successful. Run created with ID: ${successfulTrigger.createdSuiteId}`,\n );\n return {\n environmentId: environment.id,\n outcome: \"success\",\n runId: successfulTrigger.createdSuiteId,\n };\n}\n", "import type { DeploySuccessWireResponse } from \"./deploySuccessWireResponse.js\";\nimport type { DeployStatus, DeploySuccessSuiteResult } from \"./types.js\";\n\n// An arm is classified by the outcome the backend declared, not by which keys\n// happen to be present.\nfunction mapSuiteResult(\n result: DeploySuccessWireResponse[\"results\"][number],\n): DeploySuccessSuiteResult {\n switch (result.outcome) {\n case \"created\":\n return {\n createdSuiteId: result.created_suite_id,\n triggerId: result.trigger_id,\n };\n case \"failed\":\n return {\n failureCode: result.failure_code,\n failureMessage: result.failure_message,\n failureReason: result.failure_reason,\n triggerId: result.trigger_id,\n };\n case \"skipped\":\n return {\n duplicateSuiteId: result.duplicate_suite_id,\n skipReason: result.skip_reason,\n triggerId: result.trigger_id,\n };\n default:\n // An outcome added by a newer backend: surface it explicitly rather than\n // forcing it into one of the known shapes.\n return { triggerId: result.trigger_id, unrecognized: true };\n }\n}\n\n// The deploy_success success body is the SDK's only snake_case wire shape; this\n// is the single place that renames it to the camelCase `DeployStatus` used\n// everywhere downstream.\nexport function mapDeploySuccessResponse(\n wire: DeploySuccessWireResponse,\n): DeployStatus {\n return {\n environment: wire.environment,\n results: wire.results.map(mapSuiteResult),\n skippedDeployment: wire.skipped_deployment && {\n message: wire.skipped_deployment.message,\n reason: wire.skipped_deployment.reason,\n },\n skippedTriggers: wire.skipped_triggers?.map((trigger) => ({\n environmentId: trigger.environment_id,\n message: trigger.message,\n reason: trigger.reason,\n triggerId: trigger.trigger_id,\n })),\n warning: wire.warning,\n };\n}\n", "import type { DeploySuccessWireResponse } from \"./deploySuccessWireResponse.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n // Arrays are objects too; a deploy_success body or any of its parts must be a\n // plain object, never an array. (JSON cannot produce other non-plain objects\n // such as Date or Map, so excluding arrays is sufficient here.)\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isOptionalString(value: unknown): boolean {\n return value === undefined || typeof value === \"string\";\n}\n\n// Validates each arm against the `outcome` the backend declared, matching how\n// mapSuiteResult discriminates. Keying both off the same field is what keeps an\n// outcome-based mapper from reading a missing payload field as undefined. It\n// also tightens `{ outcome: \"failed\" }` with no `failure_reason`: key-presence\n// classified that as unrecognized, and it is now an invalid body.\nfunction isWireSuiteResult(value: unknown): boolean {\n if (!isRecord(value)) return false;\n if (typeof value.trigger_id !== \"string\") return false;\n if (!isOptionalString(value.outcome)) return false;\n switch (value.outcome) {\n case \"created\":\n return typeof value.created_suite_id === \"string\";\n case \"failed\":\n return (\n typeof value.failure_reason === \"string\" &&\n isOptionalString(value.failure_code) &&\n isOptionalString(value.failure_message)\n );\n case \"skipped\":\n return (\n typeof value.duplicate_suite_id === \"string\" &&\n typeof value.skip_reason === \"string\"\n );\n default:\n // An outcome this SDK version does not know, or none at all. Accept it so\n // an older SDK does not reject the whole response; mapSuiteResult maps it\n // to an explicit unrecognized outcome.\n return true;\n }\n}\n\nfunction isEnvironment(value: unknown): boolean {\n if (!isRecord(value)) return false;\n if (typeof value.id !== \"string\") return false;\n if (typeof value.isStatic !== \"boolean\") return false;\n if (value.alias !== undefined && typeof value.alias !== \"string\")\n return false;\n return true;\n}\n\nfunction isSkippedDeployment(value: unknown): boolean {\n if (!isRecord(value)) return false;\n return typeof value.message === \"string\" && typeof value.reason === \"string\";\n}\n\nfunction isSkippedTrigger(value: unknown): boolean {\n if (!isRecord(value)) return false;\n return (\n typeof value.environment_id === \"string\" &&\n typeof value.message === \"string\" &&\n typeof value.reason === \"string\" &&\n typeof value.trigger_id === \"string\"\n );\n}\n\nfunction isDeploySuccessWireResponse(\n value: unknown,\n): value is DeploySuccessWireResponse {\n if (!isRecord(value)) return false;\n if (value.environment !== undefined && !isEnvironment(value.environment))\n return false;\n\n if (!Array.isArray(value.results) || !value.results.every(isWireSuiteResult))\n return false;\n\n if (\n value.skipped_deployment !== undefined &&\n !isSkippedDeployment(value.skipped_deployment)\n )\n return false;\n\n if (\n value.skipped_triggers !== undefined &&\n (!Array.isArray(value.skipped_triggers) ||\n !value.skipped_triggers.every(isSkippedTrigger))\n )\n return false;\n\n if (!isOptionalString(value.warning)) return false;\n\n return true;\n}\n\n// Validate the deploy_success success body at runtime instead of trusting a\n// cast. `environment` is required to be present-or-explicitly-undefined; the\n// two skip fields are optional (older servers omit them).\nexport function parseDeploySuccessWireResponse(\n value: unknown,\n): DeploySuccessWireResponse | \"invalid\" {\n return isDeploySuccessWireResponse(value) ? value : \"invalid\";\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { logFetchError } from \"../../../api/log.js\";\nimport type { LogDriver, SdkDependencies } from \"../../dependencies.js\";\n\nimport { handleSuccessResponse } from \"./handleSuccessResponse.js\";\nimport { mapDeploySuccessResponse } from \"./mapDeploySuccessResponse.js\";\nimport { parseDeploySuccessWireResponse } from \"./parseDeploySuccessWireResponse.js\";\nimport type {\n AttemptDeployHttpAbortReason,\n DeployConfig,\n NotifyDeployStatus,\n} from \"./types.js\";\n\n/**\n * @deprecated Reports through the legacy `deploy_success` webhook, which\n * triggers do not see. Use `deployment.reportStatus` instead.\n */\nexport async function attemptNotifyDeploy(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: Partial<DeployConfig>,\n): Promise<NotifyDeployStatus> {\n const { fetch: localFetch, log } = deps;\n\n let response: Response;\n let bodyText: string;\n try {\n response = await localFetch(\n new URL(\"/api/webhooks/deploy_success\", apiConfig.serviceBase),\n {\n body: JSON.stringify({\n branch: config.branch,\n commit_url: config.commitUrl,\n deduplication_key: config.deduplicationKey,\n deployment_type: config.deploymentType,\n deployment_url: config.deploymentUrl,\n ...(\"ephemeralEnvironment\" in config\n ? {\n ephemeral_environment: config.ephemeralEnvironment,\n }\n : \"hostingService\" in config && {\n hosting_service: config.hostingService,\n merge_request_number:\n config.hostingService === \"GitLab\"\n ? config.mergeRequestNumber\n : undefined,\n pull_request_number:\n config.hostingService === \"GitHub\"\n ? config.pullRequestNumber\n : undefined,\n repository: config.repository,\n }),\n sha: config.sha,\n variables: config.variables,\n workspaceId: config.workspaceId,\n }),\n headers: {\n Authorization: `Bearer ${apiConfig.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": apiConfig.userAgent,\n },\n method: \"POST\",\n // Override default timeout to 5 minutes. This gives extra room\n // for both (1) waiting for reconciliation (2) creating the run.\n signal: AbortSignal.timeout(5 * 60 * 1000),\n },\n );\n\n if (!response.ok) return handleErrorResponse(response, log);\n\n // Reading the body stream is still a network operation; a failure here is\n // a network error, not a bad payload.\n bodyText = await response.text();\n } catch {\n log.error(`\uD83D\uDEAB Network error from deploy_success, aborting.`);\n return {\n abortReason: \"network-error\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n }\n\n let rawBody: unknown;\n try {\n rawBody = JSON.parse(bodyText);\n } catch {\n return abortInvalidResponseBody(log, \"the response body was not JSON\");\n }\n\n const wire = parseDeploySuccessWireResponse(rawBody);\n if (wire === \"invalid\") {\n return abortInvalidResponseBody(\n log,\n \"the response body did not match the expected shape\",\n );\n }\n\n const data = mapDeploySuccessResponse(wire);\n return handleSuccessResponse(data, log);\n}\n\nfunction abortInvalidResponseBody(\n log: LogDriver,\n detail: string,\n): NotifyDeployStatus {\n log.error(`\uD83D\uDEAB Invalid response from deploy_success (${detail}), aborting.`);\n return {\n abortReason: \"invalid-response-body\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n}\n\nasync function handleErrorResponse(\n response: Response,\n log: LogDriver,\n): Promise<NotifyDeployStatus> {\n const status = response.status;\n let abortReason: AttemptDeployHttpAbortReason;\n if (status === undefined) abortReason = \"network-error\";\n else if (status === 401) abortReason = \"401-unauthorized\";\n else if (status === 403) abortReason = \"403-forbidden\";\n else if (status >= 500) abortReason = \"5XX-server-error\";\n else abortReason = \"4XX-client-error\";\n await logFetchError({\n log,\n methodName: \"attemptNotifyDeploy\",\n response,\n });\n return {\n abortReason,\n httpStatus: status,\n outcome: \"aborted\",\n };\n}\n", "const signedUrlPaths = {\n runInputsExecutables: \"/api/v0/run-inputs-executables-signed-urls\",\n teamStorage: \"/api/v0/team-storage-signed-url\",\n} as const;\n\nexport function buildSignedUrl({\n destinationFilePath,\n endpoint,\n serviceBase,\n workspaceId,\n}: {\n destinationFilePath: string | undefined;\n endpoint: keyof typeof signedUrlPaths;\n serviceBase: string;\n workspaceId: string | undefined;\n}): URL {\n const url = new URL(signedUrlPaths[endpoint], serviceBase);\n if (destinationFilePath !== undefined)\n url.searchParams.set(\"file\", destinationFilePath);\n if (workspaceId !== undefined)\n url.searchParams.set(\"workspaceId\", workspaceId);\n return url;\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\nimport type {\n GenerateSignedUrlConfig,\n GenerateSignedUrlResponse,\n} from \"../sdk/domain/generateSignedUrls/types.js\";\n\nimport { logFetchError } from \"./log.js\";\nimport { buildSignedUrl } from \"./signed-url.js\";\n\nexport async function callGenerateSignedUrlForRunInputsExecutablesStorage(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n { destinationFilePath, workspaceId }: GenerateSignedUrlConfig,\n { fetch: localFetch, log }: SdkDependencies,\n): Promise<GenerateSignedUrlResponse> {\n try {\n const response = await localFetch(\n buildSignedUrl({\n destinationFilePath,\n endpoint: \"runInputsExecutables\",\n serviceBase,\n workspaceId,\n }),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": userAgent,\n },\n method: \"GET\",\n },\n );\n\n if (response.status === 200) {\n const json =\n (await response.json()) as Partial<GenerateSignedUrlResponse>;\n return {\n fileLocation: json.fileLocation,\n httpStatus: response.status,\n interactiveRunFileLocation: json.interactiveRunFileLocation,\n playgroundFileLocation: json.playgroundFileLocation,\n signedUrl: json.signedUrl,\n success: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"callGenerateSignedUrlForRunInputsExecutablesStorage\",\n response,\n });\n return {\n errorMessage: await response.text(),\n httpStatus: response.status,\n success: false,\n } as const;\n } catch {\n return {\n errorMessage: \"Network error, aborting request to generate signed URL\",\n httpStatus: 0,\n success: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { callGenerateSignedUrlForRunInputsExecutablesStorage } from \"../../../api/generate-signed-url-for-run-inputs-executables.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n GenerateSignedUrlAbortReason,\n GenerateSignedUrlConfig,\n GenerateSignedUrlStatus,\n} from \"./types.js\";\n\nexport async function generateSignedUrlForRunInputsExecutablesStorage(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: GenerateSignedUrlConfig,\n): Promise<GenerateSignedUrlStatus> {\n const { log } = deps;\n\n if (!config.destinationFilePath) {\n log.error(`\uD83D\uDEAB destinationFilePath is a required config parameter`);\n return {\n abortReason: \"sdk-argument-validation-failed\",\n success: false,\n };\n }\n\n const responseState =\n await callGenerateSignedUrlForRunInputsExecutablesStorage(\n apiConfig,\n config,\n deps,\n );\n if (!responseState.success) {\n let abortReason: GenerateSignedUrlAbortReason = \"XXX-other-http-code\";\n\n if (responseState.httpStatus >= 500) {\n abortReason = \"5XX-server-error\";\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`,\n );\n } else {\n if (responseState.httpStatus === 400) abortReason = \"400-invalid-request\";\n else if (responseState.httpStatus === 401)\n abortReason = \"401-invalid-credentials\";\n else if (responseState.httpStatus === 403) abortReason = \"403-forbidden\";\n else if (responseState.httpStatus === 0)\n abortReason = \"client-network-error\";\n\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: ${responseState.errorMessage ? `${responseState.errorMessage}.` : \"\"} aborting.`,\n );\n }\n\n return {\n abortReason,\n httpStatus: responseState.httpStatus,\n success: false,\n };\n }\n\n log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);\n return {\n fileLocation: responseState.fileLocation,\n interactiveRunFileLocation: responseState.interactiveRunFileLocation,\n playgroundFileLocation: responseState.playgroundFileLocation,\n success: true,\n uploadUrl: responseState.signedUrl,\n };\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\nimport type {\n GenerateSignedUrlConfig,\n GenerateSignedUrlResponse,\n} from \"../sdk/domain/generateSignedUrls/types.js\";\n\nimport { logFetchError } from \"./log.js\";\nimport { buildSignedUrl } from \"./signed-url.js\";\n\nexport async function callGenerateSignedUrlForTempTeamStorage(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n { destinationFilePath, workspaceId }: Partial<GenerateSignedUrlConfig>,\n { fetch: localFetch, log }: SdkDependencies,\n): Promise<GenerateSignedUrlResponse> {\n try {\n const response = await localFetch(\n buildSignedUrl({\n destinationFilePath,\n endpoint: \"teamStorage\",\n serviceBase,\n workspaceId,\n }),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": userAgent,\n },\n method: \"GET\",\n },\n );\n\n if (response.status === 200) {\n const json =\n (await response.json()) as Partial<GenerateSignedUrlResponse>;\n return {\n fileLocation: json.fileLocation,\n httpStatus: response.status,\n interactiveRunFileLocation: json.interactiveRunFileLocation,\n playgroundFileLocation: json.playgroundFileLocation,\n signedUrl: json.signedUrl,\n success: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"callGenerateSignedUrlForTempTeamStorage\",\n response,\n });\n return {\n errorMessage: await response.text(),\n httpStatus: response.status,\n success: false,\n } as const;\n } catch {\n return {\n errorMessage: \"Network error, aborting request to generate signed URL\",\n httpStatus: 0,\n success: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { callGenerateSignedUrlForTempTeamStorage } from \"../../../api/generate-signed-url-for-team-storage.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type { GenerateSignedUrlConfig } from \"./types.js\";\n\ntype GenerateSignedUrlStatus =\n | {\n fileLocation?: string;\n interactiveRunFileLocation?: string;\n /** @deprecated Use `interactiveRunFileLocation` instead. Will be removed in a future major version. */\n playgroundFileLocation?: string;\n success: true;\n uploadUrl?: string;\n }\n | {\n abortReason: GenerateSignedUrlAbortReason;\n httpStatus?: number;\n success: false;\n };\n\nexport type GenerateSignedUrlAbortReason =\n | \"client-network-error\"\n | \"sdk-argument-validation-failed\"\n | \"400-invalid-request\"\n | \"401-invalid-credentials\"\n | \"403-forbidden\"\n | \"5XX-server-error\"\n | \"XXX-other-http-code\";\n\nexport async function generateSignedUrlForTempTeamStorage(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: GenerateSignedUrlConfig,\n): Promise<GenerateSignedUrlStatus> {\n const { log } = deps;\n\n if (!config.destinationFilePath) {\n log.error(`\uD83D\uDEAB destinationFilePath is a required config parameter`);\n return {\n abortReason: \"sdk-argument-validation-failed\",\n success: false,\n };\n }\n\n const responseState = await callGenerateSignedUrlForTempTeamStorage(\n apiConfig,\n config,\n deps,\n );\n if (!responseState.success) {\n let abortReason: GenerateSignedUrlAbortReason = \"XXX-other-http-code\";\n\n if (responseState.httpStatus >= 500) {\n abortReason = \"5XX-server-error\";\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: aborting.`,\n );\n } else {\n if (responseState.httpStatus === 400) abortReason = \"400-invalid-request\";\n else if (responseState.httpStatus === 401)\n abortReason = \"401-invalid-credentials\";\n else if (responseState.httpStatus === 403) abortReason = \"403-forbidden\";\n else if (responseState.httpStatus === 0)\n abortReason = \"client-network-error\";\n\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${responseState.httpStatus}) when generating signed upload url: ${responseState.errorMessage ? `${responseState.errorMessage}.` : \"\"} aborting.`,\n );\n }\n\n return {\n abortReason,\n httpStatus: responseState.httpStatus,\n success: false,\n };\n }\n\n log.info(`\u2705 Generated Signed Upload URL: ${responseState.signedUrl}.`);\n return {\n fileLocation: responseState.fileLocation,\n interactiveRunFileLocation: responseState.interactiveRunFileLocation,\n playgroundFileLocation: responseState.playgroundFileLocation,\n success: true,\n uploadUrl: responseState.signedUrl,\n };\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport { logFetchError } from \"../../../api/log.js\";\nimport type { LogDriver, SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n NotifyTerminatedEphemeralEnvironmentAbortReason,\n NotifyTerminatedEphemeralEnvironmentInput,\n NotifyTerminatedEphemeralEnvironmentResult,\n TerminatedEphemeralEnvironmentSuccessResult,\n} from \"./types.js\";\n\nexport const notifyTerminatedEphemeralEnvironment = async (\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n config: NotifyTerminatedEphemeralEnvironmentInput,\n): Promise<NotifyTerminatedEphemeralEnvironmentResult> => {\n const { fetch: localFetch, log } = deps;\n try {\n const response = await localFetch(\n new URL(\"/api/webhooks/environment_terminated\", apiConfig.serviceBase),\n {\n body: JSON.stringify(config),\n headers: {\n Authorization: `Bearer ${apiConfig.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": apiConfig.userAgent,\n },\n method: \"POST\",\n },\n );\n if (!response.ok) return handleErrorResponse(response, log);\n const { environmentId, warning } =\n (await response.json()) as TerminatedEphemeralEnvironmentSuccessResult;\n if (warning) log.warn(`\u26A0\uFE0F ${warning}`);\n return { environmentId, outcome: \"success\" };\n } catch {\n log.error(`\uD83D\uDEAB Network error from terminate_preview_environment, aborting.`);\n return {\n abortReason: \"network-error\",\n outcome: \"aborted\",\n };\n }\n};\n\nasync function handleErrorResponse(\n response: Response,\n log: LogDriver,\n): Promise<NotifyTerminatedEphemeralEnvironmentResult> {\n const status = response.status;\n let abortReason: NotifyTerminatedEphemeralEnvironmentAbortReason;\n if (status === undefined) abortReason = \"network-error\";\n else if (status === 401) abortReason = \"401-unauthorized\";\n else if (status === 403) abortReason = \"403-forbidden\";\n else if (status === 409) abortReason = \"409-conflict\";\n else if (status >= 500) abortReason = \"5XX-server-error\";\n else abortReason = \"4XX-client-error\";\n await logFetchError({\n log,\n methodName: \"notifyTerminatedEphemeralEnvironment\",\n response,\n });\n return {\n abortReason,\n httpStatus: status,\n outcome: \"aborted\",\n };\n}\n", "import type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\n\nimport type { PollCiGreenlightStatus } from \"./types.js\";\n\n/**\n * Build the result for a completed run\n */\nexport function buildCompletedRunResult(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): PollCiGreenlightStatus {\n if (status.greenlight)\n return { greenlightStatus: status, outcome: \"success\" };\n else return { greenlightStatus: status, outcome: \"failed\" };\n}\n", "import type { PollCiGreenlightPollConfig } from \"./types.js\";\n\n/**\n * Safe default values for polling configuration.\n * If you change these values, make sure you update the JSDoc\n * comments in the PollCiGreenlightPollConfig type.\n */\nexport const pollCiGreenlightDefaults: PollCiGreenlightPollConfig = {\n abortOnSuperseded: false,\n maxRetries: 10,\n pollTimeout: 120 * 60 * 1000, // 2 hours\n retryInterval: 10 * 1000, // 10 seconds\n runInProgressInterval: 30 * 1000, // 30 seconds\n runUnderReviewInterval: 60 * 1000, // 60 seconds\n};\n", "import type { ApiConfig } from \"../api-types.js\";\nimport type { SdkDependencies } from \"../sdk/dependencies.js\";\n\nimport type { CiGreenlightBugData } from \"./ci-greenlight-bug-data.js\";\nimport { logFetchError } from \"./log.js\";\n\nexport type {\n CiGreenlightBugData,\n CiGreenlightBugDetails,\n} from \"./ci-greenlight-bug-data.js\";\n\nexport type CiGreenlightStatusBase = {\n relevantRunId: string;\n relevantRunUrl: string;\n rootRunId: string;\n rootRunUrl: string;\n};\n\nexport type CiGreenlightStatusExtended = {\n relevantRunWithBugsUrl: string;\n workflowsDisabledAfterRunCount: number;\n workflowsInRunCount: number;\n workflowsUnderInvestigationCount: number;\n};\n\n/**\n * The status of a CI greenlight run. See the API documentation here for\n * more details: https://qawolf.notion.site/1b170576efea411fa785842a71e7c99e\n */\nexport type CiGreenlightStatus = CiGreenlightStatusBase &\n (\n | ({\n greenlight: boolean;\n /**\n * Human-readable copy explaining the outcome, when the server provides\n * it. Sent when QA Wolf assessed the change and ran no flows.\n */\n message?: string;\n /**\n * Stable, machine-readable code for the outcome, when the server\n * provides it. Treat as an open set of values.\n */\n reason?: string;\n runStage: \"completed\";\n } & CiGreenlightBugData &\n CiGreenlightStatusExtended)\n | ({\n greenlight: false;\n runStage: \"underReview\";\n } & CiGreenlightBugData &\n CiGreenlightStatusExtended)\n | ({\n greenlight: false;\n runStage: \"initializing\";\n } & Partial<CiGreenlightStatusExtended>)\n | ({\n greenlight: false;\n /**\n * Human-readable copy explaining why the run was canceled, when the\n * server provides it.\n */\n message?: string;\n /**\n * Stable, machine-readable code for why the run was canceled, when the\n * server provides it. Treat as an open set of values.\n */\n reason?: string;\n runStage: \"canceled\";\n } & Partial<CiGreenlightStatusExtended>)\n );\n\nexport async function fetchCiGreenlightStatus(\n { apiKey, serviceBase, userAgent }: ApiConfig,\n {\n runId,\n }: {\n runId: string;\n },\n { fetch: localFetch, log }: SdkDependencies,\n) {\n try {\n const resp = await localFetch(\n new URL(\n `/api/v0/ci-greenlight/${encodeURIComponent(runId)}`,\n serviceBase,\n ),\n {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"User-Agent\": userAgent,\n },\n },\n );\n\n if (resp.ok) {\n const greenlightStatus = (await resp.json()) as CiGreenlightStatus;\n return {\n greenlightStatus,\n httpStatus: resp.status,\n ok: true,\n } as const;\n }\n await logFetchError({\n log,\n methodName: \"fetchCiGreenlightStatus\",\n response: resp,\n });\n if (resp.status === 404) {\n return {\n canRetry: true,\n errorType: \"not-found\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n }\n if (resp.status >= 500) {\n return {\n canRetry: true,\n errorType: \"server\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n }\n return {\n canRetry: false,\n errorType: \"client\",\n httpStatus: resp.status,\n ok: false,\n } as const;\n } catch {\n return {\n canRetry: true,\n errorType: \"network\",\n httpStatus: 0,\n ok: false,\n } as const;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { fetchCiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { sleep } from \"../../../other.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport { pollCiGreenlightDefaults } from \"./consts.js\";\nimport type {\n MakePollCiGreenlightStatusIteratorParams,\n PollCiGreenlightIteration,\n} from \"./types.js\";\n\n/**\n * Creates an async generator that yields CI greenlight status updates or abort notifications.\n *\n * This low-level API gives you full control over the polling loop, allowing you to:\n * - Inspect status after each fetch\n * - Break out of the loop based on custom criteria\n * - Add custom logging or side effects\n * - Handle abort conditions without exceptions\n *\n * The iterator yields a discriminated union with `isAborted` property:\n * - `isAborted: false` - Normal status update with run information\n * - `isAborted: true` - Terminal condition (timeout, error, canceled, etc.)\n *\n * Note: This function does not throw errors. All error conditions are yielded as\n * abort results that you must check and handle.\n *\n * @example\n * ```typescript\n * const greenlightIterator = makePollCiGreenlightStatusIterator({ runId: \"my-run-id\" });\n *\n * for await (const lastPoll of greenlightIterator) {\n * // Check for abort conditions first\n * if (lastPoll.isAborted) {\n * console.error(`Aborted: ${lastPoll.abortReason}`);\n * process.exit(1);\n * }\n *\n * // Handle normal status updates\n * const { status } = lastPoll;\n * console.log(`Current stage: ${status.runStage}`);\n *\n * // Exit with error if run reached a terminal stage without greenlight\n * if (lastPoll.isFailedTerminalStage) {\n * process.exit(1);\n * }\n * }\n * ```\n *\n */\nexport async function* makePollCiGreenlightStatusIterator(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n { runId, ...pollConfig }: MakePollCiGreenlightStatusIteratorParams,\n): AsyncGenerator<PollCiGreenlightIteration, void, unknown> {\n const { log } = deps;\n\n const {\n maxRetries = pollCiGreenlightDefaults.maxRetries,\n pollTimeout = pollCiGreenlightDefaults.pollTimeout,\n retryInterval = pollCiGreenlightDefaults.retryInterval,\n runInProgressInterval = pollCiGreenlightDefaults.runInProgressInterval,\n runUnderReviewInterval = pollCiGreenlightDefaults.runUnderReviewInterval,\n } = pollConfig;\n\n let retries = 0;\n let previousStatus: CiGreenlightStatus | undefined = undefined;\n const startedAt = Date.now();\n\n while (Date.now() - startedAt <= pollTimeout) {\n const responseState = await fetchCiGreenlightStatus(\n apiConfig,\n { runId },\n deps,\n );\n\n const elapsedMs = Date.now() - startedAt;\n\n if (!responseState.ok && !responseState.canRetry) {\n yield {\n abortReason: \"4XX-client-error\",\n elapsedMs,\n httpStatus: responseState.httpStatus,\n isAborted: true,\n };\n return;\n }\n\n if (!responseState.ok) {\n retries += 1;\n const { errorType, httpStatus } = responseState;\n if (retries > maxRetries) {\n switch (errorType) {\n case \"network\":\n yield {\n abortReason: \"network-error\",\n elapsedMs,\n httpStatus: undefined,\n isAborted: true,\n };\n break;\n case \"not-found\":\n yield {\n abortReason: \"404-run-not-found\",\n elapsedMs,\n httpStatus: httpStatus ?? 404,\n isAborted: true,\n };\n break;\n case \"server\":\n yield {\n abortReason: \"5XX-server-error\",\n elapsedMs,\n httpStatus: httpStatus ?? 500,\n isAborted: true,\n };\n break;\n default:\n throw Error(`Unexpected error type: ${errorType satisfies never}`);\n }\n return;\n }\n\n const retryLabel = `${\n httpStatus ? ` (status ${httpStatus})` : \"\"\n }, will try again... (${retries}/${maxRetries})`;\n\n if (errorType === \"network\") log.warn(`\u274C Network error${retryLabel}`);\n else if (errorType === \"not-found\")\n log.info(`\u23F3 Run not found${retryLabel}`);\n else if (errorType === \"server\") log.warn(`\u274C Server error${retryLabel}`);\n\n await sleep(retryInterval);\n continue;\n }\n\n // Success - reset retry counter\n retries = 0;\n const { greenlightStatus } = responseState;\n const stageChanged =\n !previousStatus || previousStatus.runStage !== greenlightStatus.runStage;\n\n // Determine if this is a failed terminal stage\n const isFailedTerminalStage =\n greenlightStatus.runStage === \"canceled\" ||\n (greenlightStatus.runStage === \"completed\" &&\n greenlightStatus.greenlight === false);\n\n yield {\n elapsedMs,\n isAborted: false,\n isFailedTerminalStage,\n previousStatus,\n stageChanged,\n status: greenlightStatus,\n };\n\n // Update previous status for next iteration\n previousStatus = greenlightStatus;\n\n switch (greenlightStatus.runStage) {\n case \"canceled\": {\n yield {\n abortReason: \"run-canceled\",\n elapsedMs,\n httpStatus: undefined,\n isAborted: true,\n message: greenlightStatus.message,\n reason: greenlightStatus.reason,\n };\n return;\n }\n case \"completed\":\n return;\n case \"initializing\":\n await sleep(runInProgressInterval);\n break;\n case \"underReview\":\n await sleep(runUnderReviewInterval);\n break;\n default:\n throw Error(\n `Unexpected run stage: ${greenlightStatus satisfies never}`,\n );\n }\n }\n\n // Timeout\n yield {\n abortReason: \"poll-timed-out\",\n elapsedMs: Date.now() - startedAt,\n httpStatus: undefined,\n isAborted: true,\n };\n return;\n}\n", "import type { CiGreenlightStatus } from \"../../../api/ci-greenlight.js\";\nimport { pluralize } from \"../../../other.js\";\n\n/**\n * Build log message for successful completed run\n */\nexport function buildSuccessLogMessage(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const { message, nonBlockingBugsCount, relevantRunUrl, workflowsInRunCount } =\n status;\n const urlInfo = `See ${relevantRunUrl}`;\n\n // A green run that executed no flows was assessed rather than tested, so the\n // generic copy would claim a run that never happened. Prefer the server's\n // explanation, as the canceled path does.\n if (workflowsInRunCount === 0 && message) return `\u2705 ${message}\\n${urlInfo}`;\n\n return `\u2705 Run passed and no blocking bugs found${\n nonBlockingBugsCount > 0\n ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(\n nonBlockingBugsCount,\n )} found`\n : \"\"\n }.\\n${urlInfo}`;\n}\n\n/**\n * Build log message for failed completed run\n */\nexport function buildFailedLogMessage(\n status: Extract<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const {\n blockingBugsCount,\n nonBlockingBugsCount,\n relevantRunWithBugsUrl,\n reproducedBugs,\n } = status;\n\n const blockingBugUrls = reproducedBugs\n .filter((bug) => bug.isBlocking)\n .map((bug) => bug.applicationUrl);\n const nonBlockingBugUrls = reproducedBugs\n .filter((bug) => !bug.isBlocking)\n .map((bug) => bug.applicationUrl);\n\n const blockingBugList = blockingBugUrls.map((url) => `\\n\u2022 ${url}`).join(\"\");\n const nonBlockingBugList = nonBlockingBugUrls\n .map((url) => `\\n\u2022 ${url}`)\n .join(\"\");\n const bugsListInText = `${\n blockingBugUrls.length > 0 ? `\\nBLOCKING BUGS:${blockingBugList}` : \"\"\n }${\n nonBlockingBugUrls.length > 0\n ? `\\nNON BLOCKING BUGS:${nonBlockingBugList}`\n : \"\"\n }`;\n\n return (\n `\u274C Run failed and ${blockingBugsCount} blocking bug${pluralize(\n blockingBugsCount,\n )} found${\n nonBlockingBugsCount\n ? ` and ${nonBlockingBugsCount} non-blocking bug${pluralize(\n nonBlockingBugsCount,\n )}`\n : \"\"\n }.\\nSee ${relevantRunWithBugsUrl}\\n` +\n \"You may review the priority of certain bugs to mark these non-blocking and retry the job.\\n\" +\n bugsListInText\n );\n}\n\n/**\n * Build log message for superseded run (aborting)\n */\nexport function buildSupersededAbortLogMessage(\n rootRunUrl: string,\n relevantRunUrl: string,\n): string {\n const supersedingDetails = `\n - Root: ${rootRunUrl}\n - Superseding: ${relevantRunUrl}`;\n\n return `\u274C Aborting due to superseded run (option 'abortOnSuperseded' is enabled).${supersedingDetails}`;\n}\n\n/**\n * Build log message for superseded run (continuing)\n */\nexport function buildSupersededContinueLogMessage(\n rootRunUrl: string,\n relevantRunUrl: string,\n): string {\n const supersedingDetails = `\n - Root: ${rootRunUrl}\n - Superseding: ${relevantRunUrl}`;\n\n return `Root run was superseded:${supersedingDetails}`;\n}\n\n/**\n * Build log messages for different run stages\n */\nexport function buildRunStageLogMessage(\n status: Exclude<CiGreenlightStatus, { runStage: \"completed\" }>,\n): string {\n const { relevantRunUrl, runStage } = status;\n const urlInfo = `See ${relevantRunUrl}`;\n\n switch (runStage) {\n case \"canceled\":\n return `\uD83D\uDEAB Run was canceled. ${\n status.message || \"Aborting... Please contact support.\"\n }\\n${urlInfo}`;\n case \"initializing\":\n return `\u23F3 Run is in progress... ${urlInfo}`;\n case \"underReview\":\n return `\uD83D\uDD75\uFE0F Run is under review... ${urlInfo}`;\n default:\n throw Error(`Unexpected run stage: ${runStage satisfies never}`);\n }\n}\n", "import type { SdkDependencies } from \"../../dependencies.js\";\n\nimport type {\n PollCiGreenlightIteratorHttpAborted,\n PollCiGreenlightIteratorNonHttpAborted,\n PollCiGreenlightStatus,\n} from \"./types.js\";\n\n/**\n * Handles aborted iterations from the CI greenlight poll iterator\n * and converts them to appropriate result objects with logging\n */\nexport function mapIteratorAbortToGreenlightStatus(\n iteration:\n | PollCiGreenlightIteratorHttpAborted\n | PollCiGreenlightIteratorNonHttpAborted,\n pollTimeout: number,\n deps: SdkDependencies,\n): PollCiGreenlightStatus {\n const { log } = deps;\n const { abortReason, httpStatus } = iteration;\n\n switch (abortReason) {\n case \"4XX-client-error\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"5XX-server-error\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"404-run-not-found\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n case \"network-error\":\n log.error(`\uD83D\uDEAB Unrecoverable network error from CI greenlight, aborting.`);\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"poll-timed-out\":\n log.warn(`\u274C Poll timed out after ${pollTimeout / 1000}s`);\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"run-canceled\":\n log.info(\n iteration.message\n ? `Run was canceled. ${iteration.message}`\n : `Run was canceled`,\n );\n return {\n abortReason,\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n case \"XXX-other-http-code\":\n log.error(\n `\uD83D\uDEAB Unrecoverable error (status ${httpStatus}) from CI greenlight, aborting.`,\n );\n return {\n abortReason,\n httpStatus,\n outcome: \"aborted\",\n };\n default:\n throw Error(`Unexpected abort reason: ${abortReason satisfies never}`);\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport { buildCompletedRunResult } from \"./buildCompletedRunResult.js\";\nimport { pollCiGreenlightDefaults } from \"./consts.js\";\nimport { makePollCiGreenlightStatusIterator } from \"./iterator.js\";\nimport {\n buildFailedLogMessage,\n buildRunStageLogMessage,\n buildSuccessLogMessage,\n buildSupersededAbortLogMessage,\n buildSupersededContinueLogMessage,\n} from \"./logging.js\";\nimport { mapIteratorAbortToGreenlightStatus } from \"./mapIteratorAbortToGreenlightStatus.js\";\nimport type {\n PollCiGreenlightParams,\n PollCiGreenlightStatus,\n} from \"./types.js\";\n\n/**\n * @deprecated Polls a run id that only `attemptNotifyDeploy` returns, so it\n * keeps the pipeline on the legacy `deploy_success` webhook.\n */\nexport async function pollCiGreenlightStatus(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n {\n onRunStageChanged = () => undefined,\n runId,\n ...pollConfig\n }: PollCiGreenlightParams,\n): Promise<PollCiGreenlightStatus> {\n const { log } = deps;\n const {\n abortOnSuperseded = pollCiGreenlightDefaults.abortOnSuperseded,\n pollTimeout = pollCiGreenlightDefaults.pollTimeout,\n } = pollConfig;\n\n const iterator = makePollCiGreenlightStatusIterator(deps, apiConfig, {\n runId,\n ...pollConfig,\n });\n\n for await (const lastPoll of iterator) {\n if (lastPoll.isAborted)\n return mapIteratorAbortToGreenlightStatus(lastPoll, pollTimeout, deps);\n\n // Handle status iterations\n const { previousStatus, stageChanged, status } = lastPoll;\n\n // Call onRunStageChanged callback when stage changes\n if (stageChanged) {\n try {\n await onRunStageChanged(status, previousStatus);\n } catch (e) {\n log.error(`Error in onRunStageChanged callback`, e);\n }\n }\n\n const { relevantRunId, relevantRunUrl, rootRunId, rootRunUrl, runStage } =\n status;\n\n // Superseded run handling\n const isSuperseded = rootRunId !== relevantRunId;\n const shouldAbortOnSuperseded = isSuperseded && abortOnSuperseded;\n if (shouldAbortOnSuperseded) {\n const message = buildSupersededAbortLogMessage(\n rootRunUrl,\n relevantRunUrl,\n );\n log.warn(message);\n return {\n abortReason: \"superseded-run\",\n httpStatus: undefined,\n outcome: \"aborted\",\n };\n }\n if (isSuperseded) {\n const message = buildSupersededContinueLogMessage(\n rootRunUrl,\n relevantRunUrl,\n );\n log.info(message);\n }\n\n switch (runStage) {\n case \"canceled\":\n case \"initializing\":\n case \"underReview\": {\n log.info(buildRunStageLogMessage(status));\n break;\n }\n case \"completed\": {\n const result = buildCompletedRunResult(status);\n switch (result.outcome) {\n case \"aborted\": {\n break;\n }\n case \"failed\": {\n const message = buildFailedLogMessage(status);\n log.warn(message);\n break;\n }\n case \"success\": {\n const message = buildSuccessLogMessage(status);\n log.info(message);\n break;\n }\n default:\n throw Error(`Unexpected outcome: ${result satisfies never}`);\n }\n return result;\n }\n default:\n throw Error(`Unexpected run stage: ${runStage satisfies never}`);\n }\n }\n\n // This should never be reached as the iterator handles timeout\n throw Error(\"Iterator ended unexpectedly\");\n}\n", "import { publicContractsV1 } from \"@qawolf/api-contracts\";\n\nimport type { ApiConfig } from \"../../../api-types.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\nimport type { PublicApiCallFailure } from \"../../publicApi/callContract.js\";\nimport { callPublicContract } from \"../../publicApi/callContract.js\";\n\nimport type {\n ReportDeploymentParams,\n ReportDeploymentResult,\n} from \"./types.js\";\n\nexport async function reportDeployment(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n params: ReportDeploymentParams,\n): Promise<ReportDeploymentResult> {\n const result = await callPublicContract(deps, apiConfig, {\n contract: publicContractsV1.deployment.reportStatus,\n input: params,\n });\n if (result.outcome !== \"ok\") return mapFailure(result);\n\n const { deployment } = result.data;\n deps.log.info(\n `\u2705 Deployment ${deployment.id} reported as ${deployment.status}: ${deployment.url}`,\n );\n return { deployment, outcome: \"reported\" };\n}\n\nfunction mapFailure(result: PublicApiCallFailure): ReportDeploymentResult {\n if (result.outcome !== \"http-error\") return { outcome: result.outcome };\n const { httpStatus, message } = result;\n if (httpStatus === 400) return { message, outcome: \"invalid-request\" };\n if (httpStatus === 401 || httpStatus === 403)\n return { message, outcome: \"unauthorized\" };\n if (httpStatus === 404) return { message, outcome: \"not-found\" };\n if (httpStatus === 409) return { message, outcome: \"conflict\" };\n if (httpStatus >= 500) return { httpStatus, outcome: \"server-error\" };\n return { httpStatus, message, outcome: \"unexpected-status\" };\n}\n", "import type { z } from \"zod\";\n\nimport type { ApiConfig } from \"../../api-types.js\";\nimport type { LogDriver, SdkDependencies } from \"../dependencies.js\";\n\n/**\n * The structural shape of a `@qawolf/api-contracts` contract. Declared here\n * because the package exports the contracts but not the type describing them.\n */\nexport type PublicApiContract<InputData = unknown, OutputData = unknown> = {\n input: z.ZodType<unknown, InputData>;\n name: string;\n output: z.ZodType<OutputData>;\n};\n\nexport type PublicApiCallFailure =\n | {\n /** The QA Wolf incident id to quote to support, when the server sent one. */\n eventId: string | undefined;\n httpStatus: number;\n /** The server's explanation of the refusal, when it sent one. */\n message: string | undefined;\n outcome: \"http-error\";\n }\n | { outcome: \"network-error\" }\n /** The server answered 2xx with a body the contract's output rejects. */\n | { outcome: \"invalid-response-body\" };\n\nexport type PublicApiCallResult<Data> =\n | { data: Data; outcome: \"ok\" }\n | PublicApiCallFailure;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n// A superjson envelope is exactly `{ json }`, plus `meta` when the payload\n// carries a type JSON cannot express. Anything else is the payload itself, so a\n// contract whose own output has a `json` field is not unwrapped by mistake.\nfunction isSuperJsonEnvelope(data: Record<string, unknown>): boolean {\n return (\n \"json\" in data &&\n Object.keys(data).every((key) => key === \"json\" || key === \"meta\")\n );\n}\n\n// tRPC wraps a procedure's output as `{ result: { data } }`, and the server's\n// superjson transformer nests the payload one level further under `json`.\nfunction unwrapTrpcEnvelope(body: unknown): unknown {\n if (!isRecord(body) || !isRecord(body.result)) return undefined;\n const data = body.result.data;\n return isRecord(data) && isSuperJsonEnvelope(data) ? data.json : data;\n}\n\n// A tRPC error body is `{ error: { json: { message, data: { eventId } } } }`\n// under the server's superjson transformer, or the same without `json`.\nfunction readTrpcError(body: unknown): {\n eventId: string | undefined;\n message: string | undefined;\n} {\n const wrapped = isRecord(body) ? body.error : undefined;\n const error =\n isRecord(wrapped) && isRecord(wrapped.json) ? wrapped.json : wrapped;\n if (!isRecord(error)) return { eventId: undefined, message: undefined };\n const data = isRecord(error.data) ? error.data : undefined;\n return {\n eventId: typeof data?.eventId === \"string\" ? data.eventId : undefined,\n message: typeof error.message === \"string\" ? error.message : undefined,\n };\n}\n\nfunction parseJson(text: string | undefined): unknown {\n if (text === undefined) return undefined;\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\nasync function readHttpError(\n response: Response,\n contractName: string,\n log: LogDriver,\n): Promise<PublicApiCallFailure> {\n const bodyText = await response.text().catch(() => undefined);\n const { eventId, message } = readTrpcError(parseJson(bodyText));\n const statusText =\n response.status >= 500\n ? \"Server Error\"\n : response.statusText || \"Unknown Error\";\n const eventIdSuffix = eventId ? ` (Event ID: ${eventId})` : \"\";\n const messageSuffix = message ? `: ${message}` : \"\";\n log.error(\n `\u274C [${contractName}] ${response.status} ${statusText}${eventIdSuffix}${messageSuffix}`,\n );\n return {\n eventId,\n httpStatus: response.status,\n message,\n outcome: \"http-error\",\n };\n}\n\n/**\n * Calls one public API contract and validates the answer with that contract's\n * own output schema, so a caller reads the contract's types rather than a\n * hand-written copy of them.\n */\nexport async function callPublicContract<InputData, OutputData>(\n { fetch: localFetch, log }: SdkDependencies,\n apiConfig: ApiConfig,\n {\n contract,\n input,\n }: {\n contract: PublicApiContract<InputData, OutputData>;\n input: InputData;\n },\n): Promise<PublicApiCallResult<OutputData>> {\n // The public contracts are served under the `public` tRPC namespace.\n const procedurePath = `public.${contract.name}`;\n\n let bodyText: string;\n try {\n const response = await localFetch(\n new URL(`/api/trpc/${procedurePath}`, apiConfig.serviceBase),\n {\n // The server's superjson transformer reads the input from `json`.\n body: JSON.stringify({ json: input }),\n headers: {\n Authorization: `Bearer ${apiConfig.apiKey}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": apiConfig.userAgent,\n },\n method: \"POST\",\n },\n );\n\n if (!response.ok) return readHttpError(response, contract.name, log);\n\n // Reading the body stream is still a network operation; a failure here is\n // a network error, not a bad payload.\n bodyText = await response.text();\n } catch {\n log.error(`\uD83D\uDEAB Network error from ${contract.name}.`);\n return { outcome: \"network-error\" };\n }\n\n const parsed = contract.output.safeParse(\n unwrapTrpcEnvelope(parseJson(bodyText)),\n );\n if (!parsed.success) {\n log.error(\n `\uD83D\uDEAB Invalid response from ${contract.name} (${parsed.error.issues[0]?.message ?? \"the response body did not match the contract\"}), aborting.`,\n );\n return { outcome: \"invalid-response-body\" };\n }\n\n return { data: parsed.data, outcome: \"ok\" };\n}\n", "import { publicContractsV1 } from \"@qawolf/api-contracts\";\n\nimport { callPublicContract } from \"../../publicApi/callContract.js\";\n\nimport { pollUntil } from \"./poll.js\";\nimport { reportStage } from \"./progress.js\";\nimport type { TriggerEvaluations } from \"./readEvaluations.js\";\nimport { readEvaluations } from \"./readEvaluations.js\";\nimport type {\n DeploymentVerdict,\n MatchedRun,\n VerdictStage,\n WaitContext,\n} from \"./types.js\";\n\nexport type RunsFound = { kind: \"runs\"; runs: MatchedRun[] };\n\ntype Phase = DeploymentVerdict | RunsFound;\n\n/**\n * Polls the deployment's trigger evaluations until they name the runs that\n * answer for it, or until it is clear nothing will run. Bounded by\n * `runAppearanceTimeout`: a trigger that never resolves does not hold up the\n * runs that did start.\n */\nexport async function awaitRuns(ctx: WaitContext): Promise<Phase> {\n const { clock } = ctx.deps;\n const { deploymentId } = ctx;\n const { runAppearanceTimeout, timeout, triggerPollInterval } = ctx.config;\n const overallDeadlineAt = ctx.startedAt + timeout;\n\n let knownRuns: MatchedRun[] = [];\n let lastStage: VerdictStage = { stage: \"waiting-for-evaluation\" };\n let lastDescription: string | undefined = undefined;\n\n return pollUntil<TriggerEvaluations, Phase>(ctx, {\n deadlineAt: Math.min(\n overallDeadlineAt,\n ctx.startedAt + runAppearanceTimeout,\n ),\n async onData(evaluations) {\n const reading = readEvaluations(evaluations);\n\n if (reading.kind === \"runs\")\n return { kind: \"done\", result: { kind: \"runs\", runs: reading.runs } };\n\n if (reading.kind === \"not-tested\") {\n return {\n kind: \"done\",\n result: {\n deploymentId,\n outcome: \"not-tested\",\n reason: reading.reason,\n triggers: reading.triggers,\n },\n };\n }\n\n knownRuns = reading.kind === \"awaiting-run\" ? reading.runs : knownRuns;\n lastStage =\n reading.kind === \"awaiting-run\"\n ? {\n matchedTriggerCount: reading.matchedTriggerCount,\n stage: \"waiting-for-run\",\n }\n : { stage: \"waiting-for-evaluation\" };\n lastDescription = await reportStage(ctx, lastDescription, lastStage);\n return { intervalMs: triggerPollInterval, kind: \"continue\" };\n },\n onDeadline() {\n const now = clock.now();\n if (knownRuns.length > 0 && now < overallDeadlineAt)\n return { kind: \"runs\", runs: knownRuns };\n return {\n deploymentId,\n elapsedMs: now - ctx.startedAt,\n lastStage,\n outcome: \"timed-out\",\n runs: [],\n };\n },\n request: () =>\n callPublicContract(ctx.deps, ctx.apiConfig, {\n contract: publicContractsV1.deployment.listTriggerEvaluations,\n input: { deploymentId },\n }),\n });\n}\n", "import type { PublicApiCallFailure } from \"../../publicApi/callContract.js\";\n\nimport type { DeploymentVerdict } from \"./types.js\";\n\n/**\n * How the wait should answer a failed call: retry it until the budget runs\n * out, or stop on a refusal that retrying cannot change.\n */\nexport type FailureHandling =\n | { exhaustedVerdict: DeploymentVerdict; kind: \"retry\" }\n | { kind: \"stop\"; verdict: DeploymentVerdict };\n\nexport function handleCallFailure(\n failure: PublicApiCallFailure,\n deploymentId: string,\n): FailureHandling {\n if (failure.outcome === \"network-error\") {\n return {\n exhaustedVerdict: { deploymentId, outcome: \"network-error\" },\n kind: \"retry\",\n };\n }\n\n if (failure.outcome === \"invalid-response-body\") {\n return {\n kind: \"stop\",\n verdict: { deploymentId, outcome: \"invalid-response-body\" },\n };\n }\n\n const { httpStatus, message } = failure;\n if (httpStatus >= 500) {\n return {\n exhaustedVerdict: { deploymentId, httpStatus, outcome: \"server-error\" },\n kind: \"retry\",\n };\n }\n if (httpStatus === 401 || httpStatus === 403) {\n return {\n kind: \"stop\",\n verdict: { deploymentId, message, outcome: \"unauthorized\" },\n };\n }\n if (httpStatus === 404) {\n return {\n kind: \"stop\",\n verdict: { deploymentId, message, outcome: \"not-found\" },\n };\n }\n return {\n kind: \"stop\",\n verdict: {\n deploymentId,\n httpStatus,\n message,\n outcome: \"unexpected-status\",\n },\n };\n}\n", "import type { PublicApiCallResult } from \"../../publicApi/callContract.js\";\n\nimport { handleCallFailure } from \"./failures.js\";\nimport type { DeploymentVerdict, WaitContext } from \"./types.js\";\n\nexport type PollStep<Result> =\n | { intervalMs: number; kind: \"continue\" }\n | { kind: \"done\"; result: Result };\n\n/**\n * Repeats one public API call until it answers something terminal, the caller\n * hangs up, or the deadline passes. Nothing here throws: a refusal, a dead\n * network and an exhausted budget are all verdicts the caller receives.\n */\nexport async function pollUntil<Data, Result>(\n ctx: WaitContext,\n {\n deadlineAt,\n onData,\n onDeadline,\n request,\n }: {\n deadlineAt: number;\n onData: (data: Data) => Promise<PollStep<Result>>;\n onDeadline: () => DeploymentVerdict | Result;\n request: () => Promise<PublicApiCallResult<Data>>;\n },\n): Promise<DeploymentVerdict | Result> {\n const { clock, log } = ctx.deps;\n const { deploymentId } = ctx;\n const { maxRetries, retryInterval, signal } = ctx.config;\n let retries = 0;\n\n // Sleeping past the deadline would overshoot a budget the caller set below\n // the CI job's own ceiling.\n const sleepWithinBudget = (intervalMs: number) =>\n clock.sleep(Math.max(0, Math.min(intervalMs, deadlineAt - clock.now())));\n\n for (;;) {\n if (signal?.aborted)\n return { deploymentId, outcome: \"canceled-by-caller\" } as const;\n if (clock.now() >= deadlineAt) return onDeadline();\n\n const result = await request();\n\n if (result.outcome === \"ok\") {\n retries = 0;\n const step = await onData(result.data);\n if (step.kind === \"done\") return step.result;\n await sleepWithinBudget(step.intervalMs);\n continue;\n }\n\n const handling = handleCallFailure(result, deploymentId);\n if (handling.kind === \"stop\") return handling.verdict;\n\n retries += 1;\n if (retries > maxRetries) return handling.exhaustedVerdict;\n log.warn(\n `\u23F3 QA Wolf did not answer, trying again... (${retries}/${maxRetries})`,\n );\n await sleepWithinBudget(retryInterval);\n }\n}\n", "import { pluralize } from \"../../../other.js\";\n\nimport type { VerdictStage, WaitContext } from \"./types.js\";\n\nfunction describeStage(stage: VerdictStage): string {\n switch (stage.stage) {\n case \"waiting-for-evaluation\":\n return \"\u23F3 Waiting for QA Wolf to evaluate this deployment's triggers...\";\n case \"waiting-for-run\": {\n const { matchedTriggerCount } = stage;\n return `\u23F3 ${matchedTriggerCount} trigger${pluralize(matchedTriggerCount)} matched; waiting for a run to start...`;\n }\n case \"waiting-for-verdict\": {\n const urls = stage.runs.map((run) => run.runUrl).join(\" \");\n return `\u23F3 ${stage.runs.length} run${pluralize(stage.runs.length)} executing... ${urls}`;\n }\n default:\n throw Error(`Unexpected stage: ${stage satisfies never}`);\n }\n}\n\n/**\n * Reports a stage once, when it differs from the one before it. The log line\n * is the identity of a stage, so a run that keeps executing does not repeat\n * itself in the build log.\n */\nexport async function reportStage(\n ctx: WaitContext,\n previousDescription: string | undefined,\n stage: VerdictStage,\n): Promise<string> {\n const description = describeStage(stage);\n if (description === previousDescription) return description;\n ctx.deps.log.info(description);\n // The wait answers with a verdict, so a caller's own failure cannot end it.\n try {\n await ctx.config.onProgress?.(stage);\n } catch (error) {\n ctx.deps.log.error(\"The onProgress callback failed.\", error);\n }\n return description;\n}\n", "import type { PublicApiOutput, publicContractsV1 } from \"@qawolf/api-contracts\";\n\nimport type { MatchedRun, NotTestedReason, TriggerNote } from \"./types.js\";\n\nexport type TriggerEvaluations = PublicApiOutput<\n typeof publicContractsV1.deployment.listTriggerEvaluations\n>;\n\ntype Evaluation = Extract<\n TriggerEvaluations,\n { state: \"evaluated\" }\n>[\"evaluations\"][number];\n\nexport type EvaluationReading =\n | { kind: \"not-evaluated\" }\n /** Some trigger is still creating a run; `runs` are the ones already known. */\n | { kind: \"awaiting-run\"; matchedTriggerCount: number; runs: MatchedRun[] }\n | { kind: \"runs\"; runs: MatchedRun[] }\n | { kind: \"not-tested\"; reason: NotTestedReason; triggers: TriggerNote[] };\n\nconst notConsideredMessages = {\n \"not-a-deployment-trigger\":\n \"The trigger has no deployment conditions, so no deployment can fire it.\",\n \"trigger-paused\": \"The trigger was paused when the deployment was evaluated.\",\n};\n\ntype ConditionSets = Extract<\n Evaluation[\"verdict\"],\n { outcome: \"did-not-match\" }\n>[\"conditionSets\"];\n\nfunction readDidNotMatch(conditionSets: ConditionSets): string {\n const reasons = conditionSets.flatMap((set) =>\n set.conditions.flatMap((condition) =>\n condition.outcome === \"did-not-match\" ? [condition.reason] : [],\n ),\n );\n return reasons.length > 0\n ? reasons.join(\" \")\n : \"The trigger's conditions did not match this deployment.\";\n}\n\nfunction toTriggerNote(evaluation: Evaluation): TriggerNote | undefined {\n const { triggerName, verdict } = evaluation;\n if (verdict.outcome === \"did-not-match\")\n return { message: readDidNotMatch(verdict.conditionSets), triggerName };\n if (verdict.outcome === \"not-considered\") {\n return {\n message: notConsideredMessages[verdict.reason],\n triggerName,\n };\n }\n if (verdict.run.status === \"did-not-run\") {\n return {\n message: verdict.run.message,\n reason: verdict.run.reason,\n triggerName,\n };\n }\n return undefined;\n}\n\n// A matched trigger that created no run because an earlier delivery of the same\n// deployment already had one points at that run, which is the run that answers\n// for this deployment.\nfunction toMatchedRun(evaluation: Evaluation): MatchedRun | undefined {\n const { triggerName, verdict } = evaluation;\n if (verdict.outcome !== \"matched\") return undefined;\n if (verdict.run.status === \"ran\")\n return { runId: verdict.run.runId, triggerName };\n if (verdict.run.status === \"did-not-run\" && verdict.run.supersededByRunId)\n return { runId: verdict.run.supersededByRunId, triggerName };\n return undefined;\n}\n\nfunction isStillProducingARun(evaluation: Evaluation): boolean {\n const { verdict } = evaluation;\n return (\n verdict.outcome === \"matched\" &&\n (verdict.run.status === \"starting\" || verdict.run.status === \"unknown\")\n );\n}\n\nexport function readEvaluations(\n evaluations: TriggerEvaluations,\n): EvaluationReading {\n if (evaluations.state === \"not-evaluated\") return { kind: \"not-evaluated\" };\n\n const runs = evaluations.evaluations.flatMap((evaluation) => {\n const run = toMatchedRun(evaluation);\n return run ? [run] : [];\n });\n const matched = evaluations.evaluations.filter(\n (evaluation) => evaluation.verdict.outcome === \"matched\",\n );\n\n if (evaluations.evaluations.some(isStillProducingARun))\n return { kind: \"awaiting-run\", matchedTriggerCount: matched.length, runs };\n if (runs.length > 0) return { kind: \"runs\", runs };\n\n return {\n kind: \"not-tested\",\n reason: matched.length > 0 ? \"no-run-created\" : \"no-trigger-matched\",\n triggers: evaluations.evaluations.flatMap((evaluation) => {\n const note = toTriggerNote(evaluation);\n return note ? [note] : [];\n }),\n };\n}\n", "import { publicContractsV1 } from \"@qawolf/api-contracts\";\n\nimport type { PublicApiCallResult } from \"../../publicApi/callContract.js\";\nimport { callPublicContract } from \"../../publicApi/callContract.js\";\n\nimport { pollUntil } from \"./poll.js\";\nimport { reportStage } from \"./progress.js\";\nimport type {\n DeploymentVerdict,\n MatchedRun,\n VerdictRun,\n WaitContext,\n} from \"./types.js\";\n\nconst settledStatuses = [\"passed\", \"failed\", \"canceled\"];\n\nfunction isSettled(run: VerdictRun): boolean {\n return settledStatuses.includes(run.status);\n}\n\n/**\n * The whole-deployment answer: one failing run fails the deployment, and a\n * cancellation means QA Wolf reached no verdict rather than that it passed.\n *\n * A deployment is expected to resolve to exactly one run; the fold over several\n * is a guard, so that a violation of that expectation cannot be reported as\n * passing. It assumes superseded runs have already been resolved away to the\n * run that replaced them, because an abandoned run can itself report failed.\n */\nexport function aggregateRuns(\n deploymentId: string,\n runs: VerdictRun[],\n): DeploymentVerdict {\n if (runs.some((run) => run.status === \"failed\")) {\n return {\n blockingBugCount: runs.reduce(\n (total, run) => total + run.blockingBugCount,\n 0,\n ),\n deploymentId,\n outcome: \"failed\",\n runs,\n };\n }\n if (runs.some((run) => run.status === \"canceled\"))\n return { deploymentId, outcome: \"run-canceled\", runs };\n return { deploymentId, outcome: \"passed\", runs };\n}\n\n// Two matched triggers can resolve to one run, whose blocking bugs would then\n// be counted twice; the first trigger to name the run keeps it.\nfunction keepOnePerRun(runs: VerdictRun[]): VerdictRun[] {\n return runs.filter(\n (run, index) =>\n runs.findIndex((other) => other.runId === run.runId) === index,\n );\n}\n\nasync function requestRuns(\n ctx: WaitContext,\n matched: MatchedRun[],\n): Promise<PublicApiCallResult<VerdictRun[]>> {\n const answers = await Promise.all(\n matched.map(async (run) => ({\n result: await callPublicContract(ctx.deps, ctx.apiConfig, {\n contract: publicContractsV1.run.get,\n // A suite can hold hundreds of flows and the verdict reads none of\n // them, so ask for the smallest list the contract allows.\n input: { flowStatuses: [\"failed\"], runId: run.runId },\n }),\n triggerName: run.triggerName,\n })),\n );\n\n const failed = answers.find((answer) => answer.result.outcome !== \"ok\");\n if (failed && failed.result.outcome !== \"ok\") return failed.result;\n\n return {\n data: keepOnePerRun(\n answers.flatMap((answer) =>\n answer.result.outcome === \"ok\"\n ? [\n {\n blockingBugCount: answer.result.data.blockingBugCount,\n // The canonical id, which can name a run other than the one asked for.\n runId: answer.result.data.runId,\n runUrl: answer.result.data.url,\n status: answer.result.data.status,\n triggerName: answer.triggerName,\n },\n ]\n : [],\n ),\n ),\n outcome: \"ok\",\n };\n}\n\nexport async function awaitVerdict(\n ctx: WaitContext,\n matched: MatchedRun[],\n): Promise<DeploymentVerdict> {\n const { deploymentId } = ctx;\n let lastRuns: VerdictRun[] = [];\n let lastDescription: string | undefined = undefined;\n\n return pollUntil<VerdictRun[], DeploymentVerdict>(ctx, {\n deadlineAt: ctx.startedAt + ctx.config.timeout,\n async onData(runs) {\n lastRuns = runs;\n if (runs.every(isSettled))\n return { kind: \"done\", result: aggregateRuns(deploymentId, runs) };\n lastDescription = await reportStage(ctx, lastDescription, {\n runs,\n stage: \"waiting-for-verdict\",\n });\n return { intervalMs: ctx.config.runPollInterval, kind: \"continue\" };\n },\n onDeadline: () => ({\n deploymentId,\n elapsedMs: ctx.deps.clock.now() - ctx.startedAt,\n lastStage: { runs: lastRuns, stage: \"waiting-for-verdict\" },\n outcome: \"timed-out\",\n runs: lastRuns,\n }),\n request: () => requestRuns(ctx, matched),\n });\n}\n", "/**\n * If you change these, update the JSDoc on `WaitForVerdictConfig` with them.\n * The whole-operation budget matches the legacy `pollCiGreenlightStatus`\n * `pollTimeout`, so moving off that function does not also move the default.\n */\nexport const waitForVerdictDefaults = {\n maxRetries: 10,\n retryInterval: 10 * 1000,\n runAppearanceTimeout: 5 * 60 * 1000,\n runPollInterval: 30 * 1000,\n timeout: 120 * 60 * 1000,\n triggerPollInterval: 3 * 1000,\n};\n", "import type { LogDriver } from \"@qawolf/ci-utils\";\n\nimport { pluralize } from \"../../../other.js\";\n\nimport type { DeploymentVerdict } from \"./types.js\";\n\nfunction runUrls(runs: { runUrl: string }[]): string {\n return runs.map((run) => run.runUrl).join(\" \");\n}\n\nexport function logVerdict(log: LogDriver, verdict: DeploymentVerdict): void {\n switch (verdict.outcome) {\n case \"canceled-by-caller\":\n return log.warn(\"\uD83D\uDEAB The wait was canceled before QA Wolf answered.\");\n case \"failed\":\n return log.error(\n `\u274C QA Wolf found ${verdict.blockingBugCount} blocking bug${pluralize(verdict.blockingBugCount)}. ${runUrls(verdict.runs)}`,\n );\n case \"not-tested\": {\n log.info(\n verdict.reason === \"no-trigger-matched\"\n ? \"\u26A0\uFE0F QA Wolf: nothing to test for this deployment.\"\n : \"\u26A0\uFE0F QA Wolf: a trigger matched this deployment but started no run.\",\n );\n for (const trigger of verdict.triggers)\n log.info(` ${trigger.triggerName}: ${trigger.message}`);\n return;\n }\n case \"passed\":\n return log.info(`\u2705 QA Wolf gate: passed. ${runUrls(verdict.runs)}`);\n case \"run-canceled\":\n return log.error(\n `\uD83D\uDEAB The run was canceled, so QA Wolf reached no verdict. ${runUrls(verdict.runs)}`,\n );\n case \"timed-out\":\n return log.error(\n `\uD83D\uDEAB Gave up after ${Math.round(verdict.elapsedMs / 1000)}s waiting for QA Wolf. ${runUrls(verdict.runs)}`,\n );\n default:\n // The transport outcomes are already logged where the call failed.\n return undefined;\n }\n}\n", "import type { ApiConfig } from \"../../../api-types.js\";\nimport type { SdkDependencies } from \"../../dependencies.js\";\n\nimport { awaitRuns } from \"./awaitRuns.js\";\nimport { awaitVerdict } from \"./awaitVerdict.js\";\nimport { waitForVerdictDefaults } from \"./consts.js\";\nimport { logVerdict } from \"./logVerdict.js\";\nimport type {\n DeploymentVerdict,\n WaitContext,\n WaitForVerdictParams,\n} from \"./types.js\";\n\n/**\n * Blocks until QA Wolf can say whether a deployment's tests passed.\n *\n * It takes only the deployment id the report gave back: resolving that to the\n * runs its triggers created, and those runs to a status, stays inside. Nothing\n * throws \u2014 a refusal, a dead network, a cancellation and an exhausted budget\n * are all arms of the returned verdict.\n */\nexport async function waitForVerdict(\n deps: SdkDependencies,\n apiConfig: ApiConfig,\n {\n deploymentId,\n maxRetries = waitForVerdictDefaults.maxRetries,\n onProgress,\n retryInterval = waitForVerdictDefaults.retryInterval,\n runAppearanceTimeout = waitForVerdictDefaults.runAppearanceTimeout,\n runPollInterval = waitForVerdictDefaults.runPollInterval,\n signal,\n timeout = waitForVerdictDefaults.timeout,\n triggerPollInterval = waitForVerdictDefaults.triggerPollInterval,\n }: WaitForVerdictParams,\n): Promise<DeploymentVerdict> {\n const ctx: WaitContext = {\n apiConfig,\n config: {\n maxRetries,\n onProgress,\n retryInterval,\n runAppearanceTimeout,\n runPollInterval,\n signal,\n timeout,\n triggerPollInterval,\n },\n deploymentId,\n deps,\n startedAt: deps.clock.now(),\n };\n\n const phase = await awaitRuns(ctx);\n const verdict = \"kind\" in phase ? await awaitVerdict(ctx, phase.runs) : phase;\n\n logVerdict(deps.log, verdict);\n return verdict;\n}\n", "import type { ApiConfig } from \"../api-types.js\";\nimport { buildFetchWithTimeout } from \"../other.js\";\n\nimport { defaultClock } from \"./defaults/clock.js\";\nimport { defaultFetch } from \"./defaults/fetch.js\";\nimport { defaultLogDriver } from \"./defaults/log.js\";\nimport { defaultServiceBase } from \"./defaults/serviceBase.js\";\nimport { defaultUserAgent } from \"./defaults/userAgent.js\";\nimport type { SdkDependencies } from \"./dependencies.js\";\nimport { attemptNotifyDeploy } from \"./domain/attemptDeploy/index.js\";\nimport { generateSignedUrlForRunInputsExecutablesStorage } from \"./domain/generateSignedUrls/generate-signed-url-for-run-inputs-executables.js\";\nimport { generateSignedUrlForTempTeamStorage } from \"./domain/generateSignedUrls/generate-signed-url-for-team-storage.js\";\nimport { notifyTerminatedEphemeralEnvironment } from \"./domain/notifyTerminatedEphemeralEnvironment/index.js\";\nimport { pollCiGreenlightStatus } from \"./domain/pollCiGreenlight/index.js\";\nimport { makePollCiGreenlightStatusIterator } from \"./domain/pollCiGreenlight/iterator.js\";\nimport { reportDeployment } from \"./domain/reportDeployment/index.js\";\nimport { waitForVerdict } from \"./domain/waitForVerdict/index.js\";\n\nexport function makeQaWolfSdk(\n {\n apiKey,\n serviceBase = defaultServiceBase,\n userAgent = defaultUserAgent,\n }: {\n apiKey: string;\n serviceBase?: string;\n userAgent?: string;\n },\n {\n clock = defaultClock,\n fetch = defaultFetch,\n log = defaultLogDriver,\n }: Partial<SdkDependencies> = {},\n) {\n if (typeof fetch !== \"function\") {\n throw Error(\n `QA Wolf CI-SDK requires fetch to be defined. Make sure you are using NodeJS 18+, OR pass a fetch polyfill to the makeQaWolfSdk function.\nWe recommend 'undici' package for that purpose. See the Requirement section of our README for more guidance.`,\n );\n }\n\n const deps: SdkDependencies = {\n clock,\n // Versions of fetch may have different default timeouts. For consistency, we explicitly set it to 2 minutes here.\n // The increased timeout helps avoid edge cases where we need to search for a commit against multiple\n // code hosting service repositories as a fallback when not finding the repository based on organization/name.\n fetch: buildFetchWithTimeout(fetch, 120000),\n log,\n };\n const apiConfig: ApiConfig = { apiKey, serviceBase, userAgent };\n return {\n /**\n * @deprecated Reports through the legacy `deploy_success` webhook, which\n * triggers do not see. Use `deployment.reportStatus` instead.\n */\n attemptNotifyDeploy: attemptNotifyDeploy.bind(null, deps, apiConfig),\n deployment: {\n reportStatus: reportDeployment.bind(null, deps, apiConfig),\n waitForVerdict: waitForVerdict.bind(null, deps, apiConfig),\n },\n generateSignedUrlForRunInputsExecutablesStorage:\n generateSignedUrlForRunInputsExecutablesStorage.bind(\n null,\n deps,\n apiConfig,\n ),\n generateSignedUrlForTempTeamStorage:\n generateSignedUrlForTempTeamStorage.bind(null, deps, apiConfig),\n makePollCiGreenlightStatusIterator: makePollCiGreenlightStatusIterator.bind(\n null,\n deps,\n apiConfig,\n ),\n notifyTerminatedEphemeralEnvironment:\n notifyTerminatedEphemeralEnvironment.bind(null, deps, apiConfig),\n /**\n * @deprecated Polls a run id that only `attemptNotifyDeploy` returns, so it\n * keeps the pipeline on the legacy `deploy_success` webhook.\n */\n pollCiGreenlightStatus: pollCiGreenlightStatus.bind(null, deps, apiConfig),\n };\n}\n\nexport type * from \"./domain/attemptDeploy/index.js\";\nexport type * from \"./domain/generateSignedUrls/types.js\";\nexport type * from \"./domain/notifyTerminatedEphemeralEnvironment/types.js\";\nexport type * from \"./domain/pollCiGreenlight/types.js\";\nexport type * from \"./domain/reportDeployment/types.js\";\nexport type * from \"./domain/waitForVerdict/types.js\";\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["handleErrorResponse", "isRecord", "publicContractsV1", "publicContractsV1", "publicContractsV1", "publicContractsV1"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import type { LogDriver } from "@qawolf/ci-utils";
|
|
2
2
|
export type { LogDriver };
|
|
3
3
|
export type FetchDriver = typeof fetch;
|
|
4
|
+
/**
|
|
5
|
+
* Wall-clock time and waiting, injected so a poll loop can be tested without
|
|
6
|
+
* a test spending the intervals it polls on.
|
|
7
|
+
*/
|
|
8
|
+
export type ClockDriver = {
|
|
9
|
+
now: () => number;
|
|
10
|
+
sleep: (ms: number) => Promise<void>;
|
|
11
|
+
};
|
|
4
12
|
export type SdkDependencies = {
|
|
13
|
+
clock: ClockDriver;
|
|
5
14
|
fetch: FetchDriver;
|
|
6
15
|
log: LogDriver;
|
|
7
16
|
};
|