@datadog/datadog-ci 0.17.6-alpha → 0.17.9
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/LICENSE-3rdparty.csv +1 -0
- package/dist/commands/dependencies/__tests__/helpers/context.d.ts +12 -0
- package/dist/commands/dependencies/__tests__/helpers/stream.d.ts +2 -0
- package/dist/commands/dependencies/__tests__/helpers/upload.run.d.ts +13 -0
- package/dist/commands/dependencies/__tests__/upload.test.d.ts +1 -0
- package/dist/commands/dependencies/api.d.ts +2 -0
- package/dist/commands/dependencies/index.d.ts +1 -0
- package/dist/commands/dependencies/interfaces.d.ts +10 -0
- package/dist/commands/dependencies/renderer.d.ts +13 -0
- package/dist/commands/dependencies/upload.d.ts +16 -0
- package/dist/commands/dsyms/__tests__/upload.test.d.ts +1 -0
- package/dist/commands/dsyms/__tests__/utils.test.d.ts +1 -0
- package/dist/commands/dsyms/index.d.ts +1 -0
- package/dist/commands/dsyms/interfaces.d.ts +7 -0
- package/dist/commands/dsyms/renderer.d.ts +9 -0
- package/dist/commands/dsyms/upload.d.ts +11 -0
- package/dist/commands/dsyms/utils.d.ts +9 -0
- package/dist/commands/git-metadata/__tests__/git.test.d.ts +1 -0
- package/dist/commands/{commit → git-metadata}/__tests__/git.test.js +0 -0
- package/dist/commands/git-metadata/__tests__/upload.test.d.ts +1 -0
- package/dist/commands/{commit → git-metadata}/__tests__/upload.test.js +1 -1
- package/dist/commands/git-metadata/api.d.ts +3 -0
- package/dist/commands/{commit → git-metadata}/api.js +0 -0
- package/dist/commands/git-metadata/git.d.ts +8 -0
- package/dist/commands/{commit → git-metadata}/git.js +0 -0
- package/dist/commands/git-metadata/index.d.ts +1 -0
- package/dist/commands/{commit → git-metadata}/index.js +0 -0
- package/dist/commands/git-metadata/interfaces.d.ts +9 -0
- package/dist/commands/{commit → git-metadata}/interfaces.js +0 -0
- package/dist/commands/git-metadata/renderer.d.ts +8 -0
- package/dist/commands/{commit → git-metadata}/renderer.js +5 -8
- package/dist/commands/git-metadata/upload.d.ts +12 -0
- package/dist/commands/{commit → git-metadata}/upload.js +8 -3
- package/dist/commands/junit/__tests__/api.test.d.ts +1 -0
- package/dist/commands/junit/__tests__/upload.test.d.ts +1 -0
- package/dist/commands/junit/api.d.ts +8 -0
- package/dist/commands/junit/index.d.ts +1 -0
- package/dist/commands/junit/interfaces.d.ts +12 -0
- package/dist/commands/junit/renderer.d.ts +8 -0
- package/dist/commands/junit/upload.d.ts +15 -0
- package/dist/commands/junit/upload.js +8 -25
- package/dist/commands/junit/utils.d.ts +1 -0
- package/dist/commands/lambda/__tests__/fixtures.d.ts +42 -0
- package/dist/commands/lambda/__tests__/fixtures.js +73 -0
- package/dist/commands/lambda/__tests__/functions/commons.test.d.ts +1 -0
- package/dist/commands/lambda/__tests__/functions/commons.test.js +171 -0
- package/dist/commands/lambda/__tests__/functions/instrument.test.d.ts +1 -0
- package/dist/commands/lambda/__tests__/{function.test.js → functions/instrument.test.js} +355 -417
- package/dist/commands/lambda/__tests__/functions/uninstrument.test.d.ts +1 -0
- package/dist/commands/lambda/__tests__/functions/uninstrument.test.js +298 -0
- package/dist/commands/lambda/__tests__/instrument.test.d.ts +1 -0
- package/dist/commands/lambda/__tests__/instrument.test.js +270 -163
- package/dist/commands/lambda/__tests__/loggroup.test.d.ts +1 -0
- package/dist/commands/lambda/__tests__/loggroup.test.js +98 -34
- package/dist/commands/lambda/__tests__/tags.test.d.ts +1 -0
- package/dist/commands/lambda/__tests__/tags.test.js +107 -31
- package/dist/commands/lambda/__tests__/uninstrument.test.d.ts +1 -0
- package/dist/commands/lambda/__tests__/uninstrument.test.js +223 -0
- package/dist/commands/lambda/constants.d.ts +44 -0
- package/dist/commands/lambda/constants.js +2 -1
- package/dist/commands/lambda/functions/commons.d.ts +71 -0
- package/dist/commands/lambda/functions/commons.js +170 -0
- package/dist/commands/lambda/functions/instrument.d.ts +16 -0
- package/dist/commands/lambda/{function.js → functions/instrument.js} +42 -102
- package/dist/commands/lambda/functions/uninstrument.d.ts +6 -0
- package/dist/commands/lambda/functions/uninstrument.js +110 -0
- package/dist/commands/lambda/index.d.ts +1 -0
- package/dist/commands/lambda/index.js +2 -1
- package/dist/commands/lambda/instrument.d.ts +29 -0
- package/dist/commands/lambda/instrument.js +85 -40
- package/dist/commands/lambda/interfaces.d.ts +70 -0
- package/dist/commands/lambda/loggroup.d.ts +14 -0
- package/dist/commands/lambda/loggroup.js +27 -4
- package/dist/commands/lambda/tags.d.ts +6 -0
- package/dist/commands/lambda/tags.js +19 -3
- package/dist/commands/lambda/uninstrument.d.ts +11 -0
- package/dist/commands/lambda/uninstrument.js +127 -0
- package/dist/commands/sourcemaps/__tests__/git.test.d.ts +1 -0
- package/dist/commands/sourcemaps/__tests__/upload.test.d.ts +1 -0
- package/dist/commands/sourcemaps/__tests__/utils.test.d.ts +1 -0
- package/dist/commands/sourcemaps/git.d.ts +20 -0
- package/dist/commands/sourcemaps/index.d.ts +1 -0
- package/dist/commands/sourcemaps/interfaces.d.ts +15 -0
- package/dist/commands/sourcemaps/renderer.d.ts +12 -0
- package/dist/commands/sourcemaps/upload.d.ts +25 -0
- package/dist/commands/sourcemaps/utils.d.ts +3 -0
- package/dist/commands/sourcemaps/validation.d.ts +6 -0
- package/dist/commands/synthetics/__tests__/api.test.d.ts +1 -0
- package/dist/commands/synthetics/__tests__/cli.test.d.ts +1 -0
- package/dist/commands/synthetics/__tests__/cli.test.js +232 -0
- package/dist/commands/synthetics/__tests__/crypto.test.d.ts +1 -0
- package/dist/commands/synthetics/__tests__/fixtures.d.ts +71 -0
- package/dist/commands/synthetics/__tests__/fixtures.js +17 -2
- package/dist/commands/synthetics/__tests__/reporters/default.test.d.ts +1 -0
- package/dist/commands/synthetics/__tests__/reporters/default.test.js +5 -4
- package/dist/commands/synthetics/__tests__/reporters/junit.test.d.ts +1 -0
- package/dist/commands/synthetics/__tests__/run-test.test.d.ts +1 -0
- package/dist/commands/synthetics/__tests__/run-test.test.js +48 -319
- package/dist/commands/synthetics/__tests__/tunnel.test.d.ts +1 -0
- package/dist/commands/synthetics/__tests__/utils.test.d.ts +1 -0
- package/dist/commands/synthetics/__tests__/utils.test.js +13 -1
- package/dist/commands/synthetics/__tests__/websocket.test.d.ts +1 -0
- package/dist/commands/synthetics/__tests__/websocket.test.js +6 -5
- package/dist/commands/synthetics/api.d.ts +24 -0
- package/dist/commands/synthetics/cli.d.ts +26 -0
- package/dist/commands/synthetics/cli.js +229 -0
- package/dist/commands/synthetics/crypto.d.ts +5 -0
- package/dist/commands/synthetics/errors.d.ts +9 -0
- package/dist/commands/synthetics/errors.js +25 -0
- package/dist/commands/synthetics/index.d.ts +1 -0
- package/dist/commands/synthetics/index.js +2 -2
- package/dist/commands/synthetics/interfaces.d.ts +342 -0
- package/dist/commands/synthetics/reporters/default.d.ts +18 -0
- package/dist/commands/synthetics/reporters/default.js +4 -3
- package/dist/commands/synthetics/reporters/junit.d.ts +95 -0
- package/dist/commands/synthetics/run-test.d.ts +74 -0
- package/dist/commands/synthetics/run-test.js +135 -319
- package/dist/commands/synthetics/tunnel.d.ts +43 -0
- package/dist/commands/synthetics/utils.d.ts +27 -0
- package/dist/commands/synthetics/utils.js +24 -5
- package/dist/commands/synthetics/websocket.d.ts +38 -0
- package/dist/commands/trace/__tests__/trace.test.d.ts +1 -0
- package/dist/commands/trace/api.d.ts +6 -0
- package/dist/commands/trace/index.d.ts +1 -0
- package/dist/commands/trace/interfaces.d.ts +23 -0
- package/dist/commands/trace/trace.d.ts +17 -0
- package/dist/commands/trace/trace.js +32 -3
- package/dist/helpers/__tests__/ci.test.d.ts +1 -0
- package/dist/helpers/__tests__/ci.test.js +23 -0
- package/dist/helpers/__tests__/git.test.d.ts +1 -0
- package/dist/helpers/__tests__/retry.test.d.ts +1 -0
- package/dist/helpers/__tests__/retry.test.js +98 -0
- package/dist/helpers/__tests__/tags.test.d.ts +1 -0
- package/dist/helpers/__tests__/upload.test.d.ts +1 -0
- package/dist/helpers/__tests__/user-provided-git.test.d.ts +1 -0
- package/dist/helpers/__tests__/utils.test.d.ts +1 -0
- package/dist/helpers/apikey.d.ts +14 -0
- package/dist/helpers/ci.d.ts +15 -0
- package/dist/helpers/ci.js +13 -6
- package/dist/helpers/errors.d.ts +2 -0
- package/dist/helpers/formatting.d.ts +5 -0
- package/dist/helpers/git.d.ts +2 -0
- package/dist/helpers/interfaces.d.ts +19 -0
- package/dist/helpers/metrics.d.ts +11 -0
- package/dist/helpers/retry.d.ts +2 -0
- package/dist/helpers/retry.js +38 -0
- package/dist/helpers/tags.d.ts +28 -0
- package/dist/helpers/upload.d.ts +44 -0
- package/dist/helpers/upload.js +4 -26
- package/dist/helpers/user-provided-git.d.ts +1 -0
- package/dist/helpers/utils.d.ts +31 -0
- package/dist/index.d.ts +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ProxyConfiguration } from '../../helpers/utils';
|
|
2
|
+
import { MainReporter } from './interfaces';
|
|
3
|
+
export interface TunnelInfo {
|
|
4
|
+
host: string;
|
|
5
|
+
id: string;
|
|
6
|
+
privateKey: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class Tunnel {
|
|
9
|
+
private url;
|
|
10
|
+
private testIDs;
|
|
11
|
+
private connected;
|
|
12
|
+
private forwardedSockets;
|
|
13
|
+
private FORWARDING_TIMEOUT;
|
|
14
|
+
private log;
|
|
15
|
+
private logError;
|
|
16
|
+
private logWarning;
|
|
17
|
+
private multiplexer?;
|
|
18
|
+
private privateKey;
|
|
19
|
+
private publicKey;
|
|
20
|
+
private sshConfig;
|
|
21
|
+
private ws;
|
|
22
|
+
constructor(url: string, testIDs: string[], proxy: ProxyConfiguration, reporter: MainReporter);
|
|
23
|
+
/**
|
|
24
|
+
* keepAlive will return a promise that tracks the state of the tunnel (and reject in case of error)
|
|
25
|
+
*/
|
|
26
|
+
keepAlive(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* start the tunnel:
|
|
29
|
+
* - get the pre-signed URL to connect to the tunnel service
|
|
30
|
+
* - Set up SSH
|
|
31
|
+
* - establish a WebSocket connection to the tunnel service
|
|
32
|
+
*/
|
|
33
|
+
start(): Promise<TunnelInfo>;
|
|
34
|
+
/**
|
|
35
|
+
* stop the tunnel
|
|
36
|
+
*/
|
|
37
|
+
stop(): Promise<void>;
|
|
38
|
+
private authenticateSSHConnection;
|
|
39
|
+
private forwardProxiedPacketsFromSSH;
|
|
40
|
+
private forwardWebSocketToSSH;
|
|
41
|
+
private getConnectionInfo;
|
|
42
|
+
private processSSHStream;
|
|
43
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { APIHelper, ConfigOverride, ExecutionRule, InternalTest, MainReporter, PollResult, Reporter, Result, Suite, Summary, TestPayload, Trigger, TriggerConfig, TriggerResponse, TriggerResult } from './interfaces';
|
|
2
|
+
import { Tunnel } from './tunnel';
|
|
3
|
+
export declare const handleConfig: (test: InternalTest, publicId: string, reporter: MainReporter, config?: ConfigOverride | undefined) => TestPayload;
|
|
4
|
+
export declare const getExecutionRule: (test: InternalTest, configOverride?: ConfigOverride | undefined) => ExecutionRule;
|
|
5
|
+
export declare const getStrictestExecutionRule: (configRule: ExecutionRule, testRule?: ExecutionRule | undefined) => ExecutionRule;
|
|
6
|
+
export declare const isCriticalError: (result: Result) => boolean;
|
|
7
|
+
export declare const hasResultPassed: (result: Result, failOnCriticalErrors: boolean, failOnTimeout: boolean) => boolean;
|
|
8
|
+
export declare const hasTestSucceeded: (results: PollResult[], failOnCriticalErrors: boolean, failOnTimeout: boolean) => boolean;
|
|
9
|
+
export declare const getSuites: (GLOB: string, reporter: MainReporter) => Promise<Suite[]>;
|
|
10
|
+
export declare const wait: (duration: number) => Promise<unknown>;
|
|
11
|
+
export declare const waitForResults: (api: APIHelper, triggerResponses: TriggerResponse[], defaultTimeout: number, triggerConfigs: TriggerConfig[], tunnel?: Tunnel | undefined, failOnCriticalErrors?: boolean | undefined) => Promise<{
|
|
12
|
+
[key: string]: PollResult[];
|
|
13
|
+
}>;
|
|
14
|
+
export declare const createTriggerResultMap: (triggerResponses: TriggerResponse[], defaultTimeout: number, triggerConfigs: TriggerConfig[]) => Map<string, TriggerResult>;
|
|
15
|
+
export declare const createSummary: () => Summary;
|
|
16
|
+
export declare const getResultDuration: (result: Result) => number;
|
|
17
|
+
export declare const getReporter: (reporters: Reporter[]) => MainReporter;
|
|
18
|
+
export declare const getTestsToTrigger: (api: APIHelper, triggerConfigs: TriggerConfig[], reporter: MainReporter) => Promise<{
|
|
19
|
+
tests: InternalTest[];
|
|
20
|
+
overriddenTestsToTrigger: TestPayload[];
|
|
21
|
+
summary: Summary;
|
|
22
|
+
}>;
|
|
23
|
+
export declare const runTests: (api: APIHelper, testsToTrigger: TestPayload[]) => Promise<Trigger>;
|
|
24
|
+
export declare const retry: <T, E extends Error>(func: () => Promise<T>, shouldRetryAfterWait: (retries: number, error: E) => number | undefined) => Promise<T>;
|
|
25
|
+
export declare const removeUndefinedValues: <T extends {
|
|
26
|
+
[key: string]: any;
|
|
27
|
+
}>(object: T) => T;
|
|
@@ -31,7 +31,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
31
31
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
32
32
|
};
|
|
33
33
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
-
exports.retry = exports.runTests = exports.getTestsToTrigger = exports.getReporter = exports.getResultDuration = exports.createTriggerResultMap = exports.waitForResults = exports.wait = exports.getSuites = exports.hasTestSucceeded = exports.hasResultPassed = exports.isCriticalError = exports.getStrictestExecutionRule = exports.getExecutionRule = exports.handleConfig = void 0;
|
|
34
|
+
exports.removeUndefinedValues = exports.retry = exports.runTests = exports.getTestsToTrigger = exports.getReporter = exports.getResultDuration = exports.createSummary = exports.createTriggerResultMap = exports.waitForResults = exports.wait = exports.getSuites = exports.hasTestSucceeded = exports.hasResultPassed = exports.isCriticalError = exports.getStrictestExecutionRule = exports.getExecutionRule = exports.handleConfig = void 0;
|
|
35
35
|
const fs = __importStar(require("fs"));
|
|
36
36
|
const path = __importStar(require("path"));
|
|
37
37
|
const url_1 = require("url");
|
|
@@ -284,12 +284,21 @@ const createFailingResult = (errorMessage, resultId, deviceId, dcId, tunnel) =>
|
|
|
284
284
|
resultID: resultId,
|
|
285
285
|
timestamp: 0,
|
|
286
286
|
});
|
|
287
|
+
const createSummary = () => ({
|
|
288
|
+
criticalErrors: 0,
|
|
289
|
+
failed: 0,
|
|
290
|
+
passed: 0,
|
|
291
|
+
skipped: 0,
|
|
292
|
+
testsNotFound: new Set(),
|
|
293
|
+
timedOut: 0,
|
|
294
|
+
});
|
|
295
|
+
exports.createSummary = createSummary;
|
|
287
296
|
const getResultDuration = (result) => {
|
|
288
297
|
if ('duration' in result) {
|
|
289
|
-
return result.duration;
|
|
298
|
+
return Math.round(result.duration);
|
|
290
299
|
}
|
|
291
300
|
if ('timings' in result) {
|
|
292
|
-
return result.timings.total;
|
|
301
|
+
return Math.round(result.timings.total);
|
|
293
302
|
}
|
|
294
303
|
return 0;
|
|
295
304
|
};
|
|
@@ -356,7 +365,7 @@ exports.getReporter = getReporter;
|
|
|
356
365
|
const getTestsToTrigger = (api, triggerConfigs, reporter) => __awaiter(void 0, void 0, void 0, function* () {
|
|
357
366
|
const overriddenTestsToTrigger = [];
|
|
358
367
|
const errorMessages = [];
|
|
359
|
-
const summary =
|
|
368
|
+
const summary = exports.createSummary();
|
|
360
369
|
const tests = yield Promise.all(triggerConfigs.map(({ config, id, suite }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
361
370
|
let test;
|
|
362
371
|
id = PUBLIC_ID_REGEX.test(id) ? id : id.substr(id.lastIndexOf('/') + 1);
|
|
@@ -367,7 +376,7 @@ const getTestsToTrigger = (api, triggerConfigs, reporter) => __awaiter(void 0, v
|
|
|
367
376
|
if (api_1.is5xxError(e)) {
|
|
368
377
|
throw e;
|
|
369
378
|
}
|
|
370
|
-
summary.
|
|
379
|
+
summary.testsNotFound.add(id);
|
|
371
380
|
const errorMessage = api_1.formatBackendErrors(e);
|
|
372
381
|
errorMessages.push(`[${chalk_1.default.bold.dim(id)}] ${chalk_1.default.yellow.bold('Test not found')}: ${errorMessage}\n`);
|
|
373
382
|
return;
|
|
@@ -426,3 +435,13 @@ const retry = (func, shouldRetryAfterWait) => __awaiter(void 0, void 0, void 0,
|
|
|
426
435
|
return trier();
|
|
427
436
|
});
|
|
428
437
|
exports.retry = retry;
|
|
438
|
+
const removeUndefinedValues = (object) => {
|
|
439
|
+
const newObject = Object.assign({}, object);
|
|
440
|
+
for (const [key, value] of Object.entries(newObject)) {
|
|
441
|
+
if (value === undefined) {
|
|
442
|
+
delete newObject[key];
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
return newObject;
|
|
446
|
+
};
|
|
447
|
+
exports.removeUndefinedValues = removeUndefinedValues;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import { default as WebSocketModule } from 'ws';
|
|
4
|
+
import { ProxyConfiguration } from '../../helpers/utils';
|
|
5
|
+
export declare class WebSocket extends EventEmitter {
|
|
6
|
+
private url;
|
|
7
|
+
private proxyOpts;
|
|
8
|
+
private firstMessage?;
|
|
9
|
+
private keepAliveWebsocket?;
|
|
10
|
+
private websocket?;
|
|
11
|
+
constructor(url: string, proxyOpts: ProxyConfiguration);
|
|
12
|
+
/**
|
|
13
|
+
* close will terminate the WebSocket connection
|
|
14
|
+
*/
|
|
15
|
+
close(gracefullyClose?: boolean): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* connect will start a WebSocket connection
|
|
18
|
+
*/
|
|
19
|
+
connect(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* duplex will create a duplex stream for the WS connection
|
|
22
|
+
*/
|
|
23
|
+
duplex(): import("stream").Duplex;
|
|
24
|
+
/**
|
|
25
|
+
* keepAlive will return a promise to keep track of the tunnel connection
|
|
26
|
+
*/
|
|
27
|
+
keepAlive(): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* on allows to listen for WebSocket messages
|
|
30
|
+
*/
|
|
31
|
+
on(event: 'message', listener: (data: WebSocketModule.Data) => void): this;
|
|
32
|
+
/**
|
|
33
|
+
* once allows to listen for a WebSocket message
|
|
34
|
+
*/
|
|
35
|
+
once(event: 'message', listener: (data: WebSocketModule.Data) => void): this;
|
|
36
|
+
waitForFirstMessage(): Promise<WebSocketModule.Data>;
|
|
37
|
+
private establishWebsocketConnection;
|
|
38
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AxiosPromise, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
2
|
+
import { Payload } from './interfaces';
|
|
3
|
+
export declare const reportCustomSpan: (request: (args: AxiosRequestConfig) => AxiosPromise<AxiosResponse>) => (customSpan: Payload, provider: string) => Promise<AxiosResponse<AxiosResponse<any>>>;
|
|
4
|
+
export declare const apiConstructor: (baseUrl: string, apiKey: string) => {
|
|
5
|
+
reportCustomSpan: (customSpan: Payload, provider: string) => Promise<AxiosResponse<AxiosResponse<any>>>;
|
|
6
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AxiosPromise, AxiosResponse } from 'axios';
|
|
2
|
+
export declare const CIRCLECI = "circleci";
|
|
3
|
+
export declare const JENKINS = "jenkins";
|
|
4
|
+
export declare const SUPPORTED_PROVIDERS: readonly ["circleci", "jenkins"];
|
|
5
|
+
export declare type Provider = typeof SUPPORTED_PROVIDERS[number];
|
|
6
|
+
export interface Payload {
|
|
7
|
+
command: string;
|
|
8
|
+
custom: {
|
|
9
|
+
id: string;
|
|
10
|
+
parent_id?: string;
|
|
11
|
+
};
|
|
12
|
+
data: Record<string, string>;
|
|
13
|
+
end_time: string;
|
|
14
|
+
error_message: string;
|
|
15
|
+
exit_code: number;
|
|
16
|
+
is_error: boolean;
|
|
17
|
+
name: string;
|
|
18
|
+
start_time: string;
|
|
19
|
+
tags: Partial<Record<string, string>>;
|
|
20
|
+
}
|
|
21
|
+
export interface APIHelper {
|
|
22
|
+
reportCustomSpan(customSpan: Payload, provider: Provider): AxiosPromise<AxiosResponse>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from 'clipanion';
|
|
2
|
+
import { Provider } from './interfaces';
|
|
3
|
+
export declare class TraceCommand extends Command {
|
|
4
|
+
static usage: import("clipanion/lib/advanced").Usage;
|
|
5
|
+
private command?;
|
|
6
|
+
private config;
|
|
7
|
+
private name?;
|
|
8
|
+
private noFail?;
|
|
9
|
+
private tags?;
|
|
10
|
+
execute(): Promise<number>;
|
|
11
|
+
getCIEnvVars(): [Record<string, string>, Provider?];
|
|
12
|
+
private getApiHelper;
|
|
13
|
+
private getBaseIntakeUrl;
|
|
14
|
+
private getEnvironmentVars;
|
|
15
|
+
private reportCustomSpan;
|
|
16
|
+
private signalToNumber;
|
|
17
|
+
}
|
|
@@ -18,6 +18,7 @@ const child_process_1 = require("child_process");
|
|
|
18
18
|
const clipanion_1 = require("clipanion");
|
|
19
19
|
const crypto_1 = __importDefault(require("crypto"));
|
|
20
20
|
const os_1 = __importDefault(require("os"));
|
|
21
|
+
const retry_1 = require("../../helpers/retry");
|
|
21
22
|
const tags_1 = require("../../helpers/tags");
|
|
22
23
|
const api_1 = require("./api");
|
|
23
24
|
const interfaces_1 = require("./interfaces");
|
|
@@ -41,7 +42,17 @@ class TraceCommand extends clipanion_1.Command {
|
|
|
41
42
|
const [command, ...args] = this.command;
|
|
42
43
|
const id = crypto_1.default.randomBytes(5).toString('hex');
|
|
43
44
|
const startTime = new Date().toISOString();
|
|
44
|
-
const childProcess = child_process_1.spawn(command, args, {
|
|
45
|
+
const childProcess = child_process_1.spawn(command, args, {
|
|
46
|
+
env: Object.assign(Object.assign({}, process.env), { DD_CUSTOM_PARENT_ID: id }),
|
|
47
|
+
stdio: ['inherit', 'inherit', 'pipe'],
|
|
48
|
+
});
|
|
49
|
+
const chunks = [];
|
|
50
|
+
childProcess.stderr.pipe(this.context.stderr);
|
|
51
|
+
const stderrCatcher = new Promise((resolve, reject) => {
|
|
52
|
+
childProcess.stderr.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
|
|
53
|
+
childProcess.stderr.on('error', (err) => reject(err));
|
|
54
|
+
childProcess.stderr.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
55
|
+
});
|
|
45
56
|
const [status, signal] = yield new Promise((resolve, reject) => {
|
|
46
57
|
childProcess.on('error', (error) => {
|
|
47
58
|
reject(error);
|
|
@@ -50,15 +61,15 @@ class TraceCommand extends clipanion_1.Command {
|
|
|
50
61
|
resolve([exitStatus, exitSignal]);
|
|
51
62
|
});
|
|
52
63
|
});
|
|
64
|
+
const stderr = yield stderrCatcher;
|
|
53
65
|
const endTime = new Date().toISOString();
|
|
54
66
|
const exitCode = (_a = status !== null && status !== void 0 ? status : this.signalToNumber(signal)) !== null && _a !== void 0 ? _a : BAD_COMMAND_EXIT_CODE;
|
|
55
67
|
const [ciEnvVars, provider] = this.getCIEnvVars();
|
|
56
68
|
if (provider) {
|
|
57
|
-
const api = this.getApiHelper();
|
|
58
69
|
const commandStr = this.command.join(' ');
|
|
59
70
|
const envVarTags = this.config.envVarTags ? tags_1.parseTags(this.config.envVarTags.split(',')) : {};
|
|
60
71
|
const cliTags = this.tags ? tags_1.parseTags(this.tags) : {};
|
|
61
|
-
yield
|
|
72
|
+
yield this.reportCustomSpan({
|
|
62
73
|
command: commandStr,
|
|
63
74
|
custom: {
|
|
64
75
|
id,
|
|
@@ -66,6 +77,8 @@ class TraceCommand extends clipanion_1.Command {
|
|
|
66
77
|
},
|
|
67
78
|
data: ciEnvVars,
|
|
68
79
|
end_time: endTime,
|
|
80
|
+
error_message: stderr,
|
|
81
|
+
exit_code: exitCode,
|
|
69
82
|
is_error: exitCode !== 0,
|
|
70
83
|
name: (_b = this.name) !== null && _b !== void 0 ? _b : commandStr,
|
|
71
84
|
start_time: startTime,
|
|
@@ -151,6 +164,22 @@ class TraceCommand extends clipanion_1.Command {
|
|
|
151
164
|
getEnvironmentVars(keys) {
|
|
152
165
|
return keys.filter((key) => key in process.env).reduce((accum, key) => (Object.assign(Object.assign({}, accum), { [key]: process.env[key] })), {});
|
|
153
166
|
}
|
|
167
|
+
reportCustomSpan(payload, provider) {
|
|
168
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
169
|
+
const api = this.getApiHelper();
|
|
170
|
+
try {
|
|
171
|
+
yield retry_1.retryRequest(() => api.reportCustomSpan(payload, provider), {
|
|
172
|
+
onRetry: (e, attempt) => {
|
|
173
|
+
this.context.stderr.write(chalk_1.default.yellow(`[attempt ${attempt}] Could not report custom span. Retrying...: ${e.message}\n`));
|
|
174
|
+
},
|
|
175
|
+
retries: 5,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
this.context.stderr.write(chalk_1.default.red(`Failed to report custom span: ${error.message}\n`));
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
154
183
|
signalToNumber(signal) {
|
|
155
184
|
if (!signal) {
|
|
156
185
|
return undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -75,6 +75,7 @@ describe('getCIMetadata', () => {
|
|
|
75
75
|
GITHUB_REF: branch,
|
|
76
76
|
GITHUB_REPOSITORY: 'DataDog/datadog-ci',
|
|
77
77
|
GITHUB_RUN_ID: '42',
|
|
78
|
+
GITHUB_SERVER_URL: 'https://github.com',
|
|
78
79
|
GITHUB_SHA: commit,
|
|
79
80
|
};
|
|
80
81
|
const expectedPipelineURL = 'https://github.com/DataDog/datadog-ci/actions/runs/42';
|
|
@@ -89,6 +90,28 @@ describe('getCIMetadata', () => {
|
|
|
89
90
|
},
|
|
90
91
|
});
|
|
91
92
|
});
|
|
93
|
+
test('github actions with run attempt is recognized', () => {
|
|
94
|
+
process.env = {
|
|
95
|
+
GITHUB_ACTIONS: 'true',
|
|
96
|
+
GITHUB_REF: branch,
|
|
97
|
+
GITHUB_REPOSITORY: 'DataDog/datadog-ci',
|
|
98
|
+
GITHUB_RUN_ATTEMPT: '2',
|
|
99
|
+
GITHUB_RUN_ID: '42',
|
|
100
|
+
GITHUB_SERVER_URL: 'https://github.com',
|
|
101
|
+
GITHUB_SHA: commit,
|
|
102
|
+
};
|
|
103
|
+
const expectedPipelineURL = 'https://github.com/DataDog/datadog-ci/actions/runs/42/attempts/2';
|
|
104
|
+
expect(ci_1.getCIMetadata()).toEqual({
|
|
105
|
+
ci: {
|
|
106
|
+
pipeline: { url: expectedPipelineURL },
|
|
107
|
+
provider: { name: ci_1.CI_ENGINES.GITHUB },
|
|
108
|
+
},
|
|
109
|
+
git: {
|
|
110
|
+
branch,
|
|
111
|
+
commitSha: commit,
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
});
|
|
92
115
|
test('jenkins is recognized', () => {
|
|
93
116
|
process.env = {
|
|
94
117
|
BUILD_URL: pipelineURL,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const retry_1 = require("../retry");
|
|
13
|
+
describe('retry', () => {
|
|
14
|
+
const retryCallback = jest.fn();
|
|
15
|
+
const createResultWithErrors = (errors) => {
|
|
16
|
+
let i = -1;
|
|
17
|
+
return () => {
|
|
18
|
+
i = i + 1;
|
|
19
|
+
if (errors[i] === undefined) {
|
|
20
|
+
return Promise.resolve({
|
|
21
|
+
config: {},
|
|
22
|
+
data: {},
|
|
23
|
+
headers: undefined,
|
|
24
|
+
status: 200,
|
|
25
|
+
statusText: '',
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return Promise.reject(errors[i]);
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
jest.restoreAllMocks();
|
|
33
|
+
});
|
|
34
|
+
const buildHttpError = (statusCode) => ({
|
|
35
|
+
response: {
|
|
36
|
+
status: statusCode,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
test('should retry retriable failed requests', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
|
+
yield retry_1.retryRequest(createResultWithErrors([buildHttpError(500), undefined]), {
|
|
41
|
+
maxTimeout: 50,
|
|
42
|
+
minTimeout: 10,
|
|
43
|
+
onRetry: retryCallback,
|
|
44
|
+
retries: 5,
|
|
45
|
+
});
|
|
46
|
+
expect(retryCallback).toBeCalledTimes(1);
|
|
47
|
+
}));
|
|
48
|
+
test('should retry non-http errors', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
49
|
+
yield retry_1.retryRequest(createResultWithErrors([{ message: 'Connection timeout' }, undefined]), {
|
|
50
|
+
maxTimeout: 50,
|
|
51
|
+
minTimeout: 10,
|
|
52
|
+
onRetry: retryCallback,
|
|
53
|
+
retries: 5,
|
|
54
|
+
});
|
|
55
|
+
expect(retryCallback).toBeCalledTimes(1);
|
|
56
|
+
}));
|
|
57
|
+
test('should not retry some clients failures', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
58
|
+
let threwError = false;
|
|
59
|
+
try {
|
|
60
|
+
yield retry_1.retryRequest(createResultWithErrors([buildHttpError(413)]), {
|
|
61
|
+
maxTimeout: 50,
|
|
62
|
+
minTimeout: 10,
|
|
63
|
+
onRetry: retryCallback,
|
|
64
|
+
retries: 5,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
threwError = true;
|
|
69
|
+
}
|
|
70
|
+
expect(threwError).toBeTruthy();
|
|
71
|
+
expect(retryCallback).toBeCalledTimes(0);
|
|
72
|
+
}));
|
|
73
|
+
test('should retry only a given amount of times', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
74
|
+
let threwError = false;
|
|
75
|
+
try {
|
|
76
|
+
yield retry_1.retryRequest(createResultWithErrors([buildHttpError(500), buildHttpError(500), buildHttpError(500), buildHttpError(500)]), {
|
|
77
|
+
maxTimeout: 20,
|
|
78
|
+
minTimeout: 10,
|
|
79
|
+
onRetry: retryCallback,
|
|
80
|
+
retries: 3,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
threwError = true;
|
|
85
|
+
}
|
|
86
|
+
expect(threwError).toBeTruthy();
|
|
87
|
+
expect(retryCallback).toBeCalledTimes(3);
|
|
88
|
+
}));
|
|
89
|
+
test('should not retry if the call was successful', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
90
|
+
yield retry_1.retryRequest(createResultWithErrors([undefined]), {
|
|
91
|
+
maxTimeout: 50,
|
|
92
|
+
minTimeout: 10,
|
|
93
|
+
onRetry: retryCallback,
|
|
94
|
+
retries: 5,
|
|
95
|
+
});
|
|
96
|
+
expect(retryCallback).toBeCalledTimes(0);
|
|
97
|
+
}));
|
|
98
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AxiosError } from 'axios';
|
|
2
|
+
import { BufferedMetricsLogger } from 'datadog-metrics';
|
|
3
|
+
/** ApiKeyValidator is an helper interface to interpret Datadog error responses and possibly check the
|
|
4
|
+
* validity of the api key.
|
|
5
|
+
*/
|
|
6
|
+
export interface ApiKeyValidator {
|
|
7
|
+
verifyApiKey(error: AxiosError): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export interface ApiKeyValidatorParams {
|
|
10
|
+
apiKey: string | undefined;
|
|
11
|
+
datadogSite: string;
|
|
12
|
+
metricsLogger?: BufferedMetricsLogger;
|
|
13
|
+
}
|
|
14
|
+
export declare const newApiKeyValidator: (params: ApiKeyValidatorParams) => ApiKeyValidator;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Metadata, SpanTags } from './interfaces';
|
|
2
|
+
export declare const CI_ENGINES: {
|
|
3
|
+
APPVEYOR: string;
|
|
4
|
+
AZURE: string;
|
|
5
|
+
BITBUCKET: string;
|
|
6
|
+
BITRISE: string;
|
|
7
|
+
BUILDKITE: string;
|
|
8
|
+
CIRCLECI: string;
|
|
9
|
+
GITHUB: string;
|
|
10
|
+
GITLAB: string;
|
|
11
|
+
JENKINS: string;
|
|
12
|
+
TRAVIS: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const getCISpanTags: () => SpanTags | undefined;
|
|
15
|
+
export declare const getCIMetadata: () => Metadata | undefined;
|
package/dist/helpers/ci.js
CHANGED
|
@@ -125,13 +125,17 @@ const getCISpanTags = () => {
|
|
|
125
125
|
};
|
|
126
126
|
}
|
|
127
127
|
if (env.GITHUB_ACTIONS || env.GITHUB_ACTION) {
|
|
128
|
-
const { GITHUB_RUN_ID, GITHUB_WORKFLOW, GITHUB_RUN_NUMBER, GITHUB_WORKSPACE, GITHUB_HEAD_REF, GITHUB_REF, GITHUB_SHA, GITHUB_REPOSITORY, } = env;
|
|
129
|
-
const repositoryUrl =
|
|
130
|
-
|
|
128
|
+
const { GITHUB_RUN_ID, GITHUB_WORKFLOW, GITHUB_RUN_NUMBER, GITHUB_WORKSPACE, GITHUB_HEAD_REF, GITHUB_REF, GITHUB_SHA, GITHUB_REPOSITORY, GITHUB_SERVER_URL, } = env;
|
|
129
|
+
const repositoryUrl = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git`;
|
|
130
|
+
let pipelineURL = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}`;
|
|
131
|
+
// Some older versions of enterprise might not have this yet.
|
|
132
|
+
if (env.GITHUB_RUN_ATTEMPT) {
|
|
133
|
+
pipelineURL += `/attempts/${env.GITHUB_RUN_ATTEMPT}`;
|
|
134
|
+
}
|
|
131
135
|
const ref = GITHUB_HEAD_REF || GITHUB_REF || '';
|
|
132
136
|
const refKey = ref.includes('tags') ? tags_1.GIT_TAG : tags_1.GIT_BRANCH;
|
|
133
137
|
tags = {
|
|
134
|
-
[tags_1.CI_JOB_URL]:
|
|
138
|
+
[tags_1.CI_JOB_URL]: `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/commit/${GITHUB_SHA}/checks`,
|
|
135
139
|
[tags_1.CI_PIPELINE_ID]: GITHUB_RUN_ID,
|
|
136
140
|
[tags_1.CI_PIPELINE_NAME]: GITHUB_WORKFLOW,
|
|
137
141
|
[tags_1.CI_PIPELINE_NUMBER]: GITHUB_RUN_NUMBER,
|
|
@@ -339,8 +343,11 @@ const getCIMetadata = () => {
|
|
|
339
343
|
};
|
|
340
344
|
}
|
|
341
345
|
if (env.GITHUB_ACTIONS) {
|
|
342
|
-
const { GITHUB_REF, GITHUB_SHA, GITHUB_REPOSITORY, GITHUB_RUN_ID } = env;
|
|
343
|
-
|
|
346
|
+
const { GITHUB_REF, GITHUB_SHA, GITHUB_REPOSITORY, GITHUB_RUN_ID, GITHUB_SERVER_URL } = env;
|
|
347
|
+
let pipelineURL = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}`;
|
|
348
|
+
if (env.GITHUB_RUN_ATTEMPT) {
|
|
349
|
+
pipelineURL += `/attempts/${env.GITHUB_RUN_ATTEMPT}`;
|
|
350
|
+
}
|
|
344
351
|
return {
|
|
345
352
|
ci: {
|
|
346
353
|
pipeline: {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { AxiosPromise, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
2
|
+
import { CI_JOB_NAME, CI_JOB_URL, CI_PIPELINE_ID, CI_PIPELINE_NAME, CI_PIPELINE_NUMBER, CI_PIPELINE_URL, CI_PROVIDER_NAME, CI_STAGE_NAME, CI_WORKSPACE_PATH, GIT_BRANCH, GIT_COMMIT_AUTHOR_DATE, GIT_COMMIT_AUTHOR_EMAIL, GIT_COMMIT_AUTHOR_NAME, GIT_COMMIT_COMMITTER_DATE, GIT_COMMIT_COMMITTER_EMAIL, GIT_COMMIT_COMMITTER_NAME, GIT_COMMIT_MESSAGE, GIT_REPOSITORY_URL, GIT_SHA, GIT_TAG } from './tags';
|
|
3
|
+
export interface Metadata {
|
|
4
|
+
ci: {
|
|
5
|
+
pipeline: {
|
|
6
|
+
url?: string;
|
|
7
|
+
};
|
|
8
|
+
provider: {
|
|
9
|
+
name: string;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
git: {
|
|
13
|
+
branch?: string;
|
|
14
|
+
commitSha?: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export declare type SpanTag = typeof CI_JOB_NAME | typeof CI_JOB_URL | typeof CI_PIPELINE_ID | typeof CI_PIPELINE_NAME | typeof CI_PIPELINE_NUMBER | typeof CI_PIPELINE_URL | typeof CI_PROVIDER_NAME | typeof CI_STAGE_NAME | typeof CI_WORKSPACE_PATH | typeof GIT_BRANCH | typeof GIT_REPOSITORY_URL | typeof GIT_SHA | typeof GIT_TAG | typeof GIT_COMMIT_AUTHOR_EMAIL | typeof GIT_COMMIT_AUTHOR_NAME | typeof GIT_COMMIT_AUTHOR_DATE | typeof GIT_COMMIT_MESSAGE | typeof GIT_COMMIT_COMMITTER_DATE | typeof GIT_COMMIT_COMMITTER_EMAIL | typeof GIT_COMMIT_COMMITTER_NAME;
|
|
18
|
+
export declare type SpanTags = Partial<Record<SpanTag, string>>;
|
|
19
|
+
export declare type RequestBuilder = (args: AxiosRequestConfig) => AxiosPromise<AxiosResponse>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import metrics from 'datadog-metrics';
|
|
2
|
+
export interface MetricsLogger {
|
|
3
|
+
logger: metrics.BufferedMetricsLogger;
|
|
4
|
+
flush(): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export interface MetricsLoggerOptions {
|
|
7
|
+
datadogSite?: string;
|
|
8
|
+
defaultTags?: string[];
|
|
9
|
+
prefix: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const getMetricsLogger: (opts: MetricsLoggerOptions) => MetricsLogger;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.retryRequest = void 0;
|
|
16
|
+
const async_retry_1 = __importDefault(require("async-retry"));
|
|
17
|
+
const errorCodesNoRetry = [400, 403, 413];
|
|
18
|
+
const retryRequest = (requestPerformer, retryOpts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
|
+
// Request function, passed to async-retry
|
|
20
|
+
const doRequest = (bail) => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
|
+
try {
|
|
22
|
+
yield requestPerformer();
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
if (error.response && errorCodesNoRetry.includes(error.response.status)) {
|
|
26
|
+
// If it's an axios error with a status code that is excluded from retries, we bail to avoid retrying
|
|
27
|
+
bail(error);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
// Other cases are retried: other axios HTTP errors as well as
|
|
31
|
+
// non-axios errors such as DNS resolution errors and connection timeouts
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
// Do the actual call
|
|
36
|
+
return async_retry_1.default(doRequest, retryOpts);
|
|
37
|
+
});
|
|
38
|
+
exports.retryRequest = retryRequest;
|