@testomatio/reporter 2.6.3 → 2.6.4-beta-acl
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/lib/pipe/testomatio.js +17 -0
- package/lib/uploader.js +7 -4
- package/package.json +1 -1
- package/src/pipe/testomatio.js +16 -0
- package/src/uploader.js +14 -5
package/lib/pipe/testomatio.js
CHANGED
|
@@ -264,6 +264,8 @@ class TestomatioPipe {
|
|
|
264
264
|
const errorText = err.response?.data?.message || err.message;
|
|
265
265
|
debug('Error creating run', err);
|
|
266
266
|
console.log(errorText || err);
|
|
267
|
+
if (err.response?.status === 403)
|
|
268
|
+
this.#disablePipe();
|
|
267
269
|
if (!this.apiKey)
|
|
268
270
|
console.error('Testomat.io API key is not set');
|
|
269
271
|
if (!this.apiKey?.startsWith('tstmt'))
|
|
@@ -312,6 +314,8 @@ class TestomatioPipe {
|
|
|
312
314
|
maxContentLength: Infinity,
|
|
313
315
|
})
|
|
314
316
|
.catch(err => {
|
|
317
|
+
if (err.response?.status === 403)
|
|
318
|
+
this.#disablePipe();
|
|
315
319
|
this.requestFailures++;
|
|
316
320
|
this.notReportedTestsCount++;
|
|
317
321
|
if (err.response) {
|
|
@@ -363,6 +367,8 @@ class TestomatioPipe {
|
|
|
363
367
|
maxContentLength: Infinity,
|
|
364
368
|
})
|
|
365
369
|
.catch(err => {
|
|
370
|
+
if (err.response?.status === 403)
|
|
371
|
+
this.#disablePipe();
|
|
366
372
|
this.requestFailures++;
|
|
367
373
|
this.notReportedTestsCount += testsToSend.length;
|
|
368
374
|
if (err.response) {
|
|
@@ -472,6 +478,17 @@ class TestomatioPipe {
|
|
|
472
478
|
}
|
|
473
479
|
debug('Run finished');
|
|
474
480
|
}
|
|
481
|
+
#disablePipe() {
|
|
482
|
+
this.isEnabled = false;
|
|
483
|
+
this.apiKey = null;
|
|
484
|
+
// clear interval function, otherwise the proccess will continue indefinitely
|
|
485
|
+
if (this.batch.intervalFunction) {
|
|
486
|
+
clearInterval(this.batch.intervalFunction);
|
|
487
|
+
this.batch.intervalFunction = null;
|
|
488
|
+
this.batch.isEnabled = false;
|
|
489
|
+
}
|
|
490
|
+
this.batch.tests = [];
|
|
491
|
+
}
|
|
475
492
|
#logFailedResponse(error) {
|
|
476
493
|
let responseBody = stringify(error.response?.data ?? error.response ?? error, { pretty: true });
|
|
477
494
|
if (!responseBody)
|
package/lib/uploader.js
CHANGED
|
@@ -40,6 +40,7 @@ class S3Uploader {
|
|
|
40
40
|
'TESTOMATIO_DISABLE_ARTIFACTS',
|
|
41
41
|
'TESTOMATIO_PRIVATE_ARTIFACTS',
|
|
42
42
|
'TESTOMATIO_ARTIFACT_MAX_SIZE_MB',
|
|
43
|
+
'TESTOMATIO_S3_NO_ACL',
|
|
43
44
|
];
|
|
44
45
|
}
|
|
45
46
|
resetConfig() {
|
|
@@ -91,7 +92,7 @@ class S3Uploader {
|
|
|
91
92
|
* @returns
|
|
92
93
|
*/
|
|
93
94
|
async #uploadToS3(Body, Key, file) {
|
|
94
|
-
const { S3_BUCKET, TESTOMATIO_PRIVATE_ARTIFACTS } = this.getConfig();
|
|
95
|
+
const { S3_BUCKET, TESTOMATIO_PRIVATE_ARTIFACTS, TESTOMATIO_S3_NO_ACL } = this.getConfig();
|
|
95
96
|
const ACL = TESTOMATIO_PRIVATE_ARTIFACTS ? 'private' : 'public-read';
|
|
96
97
|
if (!S3_BUCKET || !Body) {
|
|
97
98
|
console.log(constants_js_1.APP_PREFIX, picocolors_1.default.bold(picocolors_1.default.red(`Failed uploading '${Key}'. Please check S3 credentials`)), this.getMaskedConfig());
|
|
@@ -105,8 +106,10 @@ class S3Uploader {
|
|
|
105
106
|
Key,
|
|
106
107
|
Body,
|
|
107
108
|
};
|
|
108
|
-
// disable ACL for
|
|
109
|
-
|
|
109
|
+
// disable ACL for IAM roles or GCS (GCS doesn't support x-amz-acl header)
|
|
110
|
+
// to precent potential issues, forece setting TESTOMATIO_S3_NO_ACL env var too in such case
|
|
111
|
+
const isGCS = s3Config.endpoint && s3Config.endpoint.includes('storage.googleapis.com');
|
|
112
|
+
if (!s3Config.credentials.sessionToken && !TESTOMATIO_S3_NO_ACL && !isGCS) {
|
|
110
113
|
params.ACL = ACL;
|
|
111
114
|
}
|
|
112
115
|
try {
|
|
@@ -119,7 +122,7 @@ class S3Uploader {
|
|
|
119
122
|
catch (e) {
|
|
120
123
|
this.failedUploads.push({ path: file.path, size: file.size });
|
|
121
124
|
debug('S3 uploading error:', e);
|
|
122
|
-
console.log(constants_js_1.APP_PREFIX, 'Upload failed:', e.message, '\nConfig:\n', this.getMaskedConfig());
|
|
125
|
+
console.log(constants_js_1.APP_PREFIX, 'Upload failed:', e.message, `\nFile:\n ${file.path}, size: ${(0, filesize_1.filesize)(file.size || 0)}`, '\nConfig:\n', this.getMaskedConfig());
|
|
123
126
|
}
|
|
124
127
|
}
|
|
125
128
|
/**
|
package/package.json
CHANGED
package/src/pipe/testomatio.js
CHANGED
|
@@ -294,6 +294,7 @@ class TestomatioPipe {
|
|
|
294
294
|
const errorText = err.response?.data?.message || err.message;
|
|
295
295
|
debug('Error creating run', err);
|
|
296
296
|
console.log(errorText || err);
|
|
297
|
+
if (err.response?.status === 403) this.#disablePipe();
|
|
297
298
|
if (!this.apiKey) console.error('Testomat.io API key is not set');
|
|
298
299
|
if (!this.apiKey?.startsWith('tstmt')) console.error('Testomat.io API key is invalid');
|
|
299
300
|
|
|
@@ -347,6 +348,7 @@ class TestomatioPipe {
|
|
|
347
348
|
maxContentLength: Infinity,
|
|
348
349
|
})
|
|
349
350
|
.catch(err => {
|
|
351
|
+
if (err.response?.status === 403) this.#disablePipe();
|
|
350
352
|
this.requestFailures++;
|
|
351
353
|
this.notReportedTestsCount++;
|
|
352
354
|
if (err.response) {
|
|
@@ -397,6 +399,7 @@ class TestomatioPipe {
|
|
|
397
399
|
maxContentLength: Infinity,
|
|
398
400
|
})
|
|
399
401
|
.catch(err => {
|
|
402
|
+
if (err.response?.status === 403) this.#disablePipe();
|
|
400
403
|
this.requestFailures++;
|
|
401
404
|
this.notReportedTestsCount += testsToSend.length;
|
|
402
405
|
if (err.response) {
|
|
@@ -520,6 +523,19 @@ class TestomatioPipe {
|
|
|
520
523
|
debug('Run finished');
|
|
521
524
|
}
|
|
522
525
|
|
|
526
|
+
#disablePipe() {
|
|
527
|
+
this.isEnabled = false;
|
|
528
|
+
this.apiKey = null;
|
|
529
|
+
|
|
530
|
+
// clear interval function, otherwise the proccess will continue indefinitely
|
|
531
|
+
if (this.batch.intervalFunction) {
|
|
532
|
+
clearInterval(this.batch.intervalFunction);
|
|
533
|
+
this.batch.intervalFunction = null;
|
|
534
|
+
this.batch.isEnabled = false;
|
|
535
|
+
}
|
|
536
|
+
this.batch.tests = [];
|
|
537
|
+
}
|
|
538
|
+
|
|
523
539
|
#logFailedResponse(error) {
|
|
524
540
|
let responseBody = stringify(error.response?.data ?? error.response ?? error, { pretty: true });
|
|
525
541
|
if (!responseBody) responseBody = '<empty>';
|
package/src/uploader.js
CHANGED
|
@@ -38,6 +38,7 @@ export class S3Uploader {
|
|
|
38
38
|
'TESTOMATIO_DISABLE_ARTIFACTS',
|
|
39
39
|
'TESTOMATIO_PRIVATE_ARTIFACTS',
|
|
40
40
|
'TESTOMATIO_ARTIFACT_MAX_SIZE_MB',
|
|
41
|
+
'TESTOMATIO_S3_NO_ACL',
|
|
41
42
|
];
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -97,7 +98,7 @@ export class S3Uploader {
|
|
|
97
98
|
* @returns
|
|
98
99
|
*/
|
|
99
100
|
async #uploadToS3(Body, Key, file) {
|
|
100
|
-
const { S3_BUCKET, TESTOMATIO_PRIVATE_ARTIFACTS } = this.getConfig();
|
|
101
|
+
const { S3_BUCKET, TESTOMATIO_PRIVATE_ARTIFACTS, TESTOMATIO_S3_NO_ACL } = this.getConfig();
|
|
101
102
|
const ACL = TESTOMATIO_PRIVATE_ARTIFACTS ? 'private' : 'public-read';
|
|
102
103
|
|
|
103
104
|
if (!S3_BUCKET || !Body) {
|
|
@@ -118,14 +119,15 @@ export class S3Uploader {
|
|
|
118
119
|
Key,
|
|
119
120
|
Body,
|
|
120
121
|
};
|
|
121
|
-
// disable ACL for
|
|
122
|
-
|
|
122
|
+
// disable ACL for IAM roles or GCS (GCS doesn't support x-amz-acl header)
|
|
123
|
+
// to precent potential issues, forece setting TESTOMATIO_S3_NO_ACL env var too in such case
|
|
124
|
+
const isGCS = s3Config.endpoint && s3Config.endpoint.includes('storage.googleapis.com');
|
|
125
|
+
if (!s3Config.credentials.sessionToken && !TESTOMATIO_S3_NO_ACL && !isGCS) {
|
|
123
126
|
params.ACL = ACL;
|
|
124
127
|
}
|
|
125
128
|
|
|
126
129
|
try {
|
|
127
130
|
const upload = new Upload({ client: s3, params });
|
|
128
|
-
|
|
129
131
|
const link = await this.getS3LocationLink(upload);
|
|
130
132
|
this.successfulUploads.push({ path: file.path, size: file.size, link });
|
|
131
133
|
debug(`📤 Uploaded artifact. File: ${file.path}, size: ${prettyBytes(file.size || 0)}, link: ${link}`);
|
|
@@ -133,7 +135,14 @@ export class S3Uploader {
|
|
|
133
135
|
} catch (e) {
|
|
134
136
|
this.failedUploads.push({ path: file.path, size: file.size });
|
|
135
137
|
debug('S3 uploading error:', e);
|
|
136
|
-
console.log(
|
|
138
|
+
console.log(
|
|
139
|
+
APP_PREFIX,
|
|
140
|
+
'Upload failed:',
|
|
141
|
+
e.message,
|
|
142
|
+
`\nFile:\n ${file.path}, size: ${prettyBytes(file.size || 0)}`,
|
|
143
|
+
'\nConfig:\n',
|
|
144
|
+
this.getMaskedConfig(),
|
|
145
|
+
);
|
|
137
146
|
}
|
|
138
147
|
}
|
|
139
148
|
|