@redocly/cli 1.11.0 → 1.12.1
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/CHANGELOG.md +17 -0
- package/lib/__tests__/utils.test.js +3 -3
- package/lib/cms/api/types.d.ts +22 -11
- package/lib/cms/commands/__tests__/push-status.test.js +338 -29
- package/lib/cms/commands/__tests__/push.test.js +32 -2
- package/lib/cms/commands/__tests__/utils.test.d.ts +1 -0
- package/lib/cms/commands/__tests__/utils.test.js +60 -0
- package/lib/cms/commands/push-status.d.ts +14 -4
- package/lib/cms/commands/push-status.js +160 -90
- package/lib/cms/commands/push.d.ts +6 -2
- package/lib/cms/commands/push.js +8 -2
- package/lib/cms/commands/utils.d.ts +22 -0
- package/lib/cms/commands/utils.js +53 -0
- package/lib/index.js +12 -1
- package/lib/utils/miscellaneous.js +5 -4
- package/lib/wrapper.d.ts +1 -1
- package/package.json +2 -2
- package/src/__tests__/utils.test.ts +3 -3
- package/src/cms/api/types.ts +19 -12
- package/src/cms/commands/__tests__/push-status.test.ts +473 -47
- package/src/cms/commands/__tests__/push.test.ts +40 -2
- package/src/cms/commands/__tests__/utils.test.ts +62 -0
- package/src/cms/commands/push-status.ts +242 -120
- package/src/cms/commands/push.ts +21 -5
- package/src/cms/commands/utils.ts +52 -0
- package/src/index.ts +13 -2
- package/src/utils/miscellaneous.ts +5 -4
- package/src/wrapper.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @redocly/cli
|
|
2
2
|
|
|
3
|
+
## 1.12.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated @redocly/openapi-core to v1.12.1.
|
|
8
|
+
|
|
9
|
+
## 1.12.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- Added return values for the `push` and `push-status` commands.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Fixed handling of wildcards on Windows ([#1521](https://github.com/Redocly/redocly-cli/issues/1521)).
|
|
18
|
+
- Updated @redocly/openapi-core to v1.12.0.
|
|
19
|
+
|
|
3
20
|
## 1.11.0
|
|
4
21
|
|
|
5
22
|
### Minor Changes
|
|
@@ -348,13 +348,13 @@ describe('handleErrors', () => {
|
|
|
348
348
|
jest.clearAllMocks();
|
|
349
349
|
});
|
|
350
350
|
it('should handle ResolveError', () => {
|
|
351
|
-
const resolveError = new openapi_core_1.ResolveError(new Error('File not found'));
|
|
351
|
+
const resolveError = new openapi_core_1.ResolveError(new Error('File not found.'));
|
|
352
352
|
expect(() => (0, miscellaneous_1.handleError)(resolveError, ref)).toThrowError(miscellaneous_1.HandledError);
|
|
353
353
|
expect(redColoretteMocks).toHaveBeenCalledTimes(1);
|
|
354
354
|
expect(process.stderr.write).toHaveBeenCalledWith(`Failed to resolve API description at openapi/test.yaml:\n\n - File not found.\n\n`);
|
|
355
355
|
});
|
|
356
356
|
it('should handle YamlParseError', () => {
|
|
357
|
-
const yamlParseError = new openapi_core_1.YamlParseError(new Error('Invalid yaml'), {});
|
|
357
|
+
const yamlParseError = new openapi_core_1.YamlParseError(new Error('Invalid yaml.'), {});
|
|
358
358
|
expect(() => (0, miscellaneous_1.handleError)(yamlParseError, ref)).toThrowError(miscellaneous_1.HandledError);
|
|
359
359
|
expect(redColoretteMocks).toHaveBeenCalledTimes(1);
|
|
360
360
|
expect(process.stderr.write).toHaveBeenCalledWith(`Failed to parse API description at openapi/test.yaml:\n\n - Invalid yaml.\n\n`);
|
|
@@ -372,7 +372,7 @@ describe('handleErrors', () => {
|
|
|
372
372
|
expect(process.stderr.write).toHaveBeenCalledWith('Syntax error: Unexpected identifier test stack\n\n');
|
|
373
373
|
});
|
|
374
374
|
it('should throw unknown error', () => {
|
|
375
|
-
const testError = new Error('Test error');
|
|
375
|
+
const testError = new Error('Test error.');
|
|
376
376
|
expect(() => (0, miscellaneous_1.handleError)(testError, ref)).toThrowError(miscellaneous_1.HandledError);
|
|
377
377
|
expect(process.stderr.write).toHaveBeenCalledWith(`Something went wrong when processing openapi/test.yaml:\n\n - Test error.\n\n`);
|
|
378
378
|
});
|
package/lib/cms/api/types.d.ts
CHANGED
|
@@ -44,32 +44,44 @@ export type Remote = {
|
|
|
44
44
|
export type PushResponse = {
|
|
45
45
|
id: string;
|
|
46
46
|
remoteId: string;
|
|
47
|
+
isMainBranch: boolean;
|
|
48
|
+
isOutdated: boolean;
|
|
49
|
+
hasChanges: boolean;
|
|
50
|
+
replace: boolean;
|
|
51
|
+
scoutJobId: string | null;
|
|
52
|
+
uploadedFiles: Array<{
|
|
53
|
+
path: string;
|
|
54
|
+
mimeType: string;
|
|
55
|
+
}>;
|
|
47
56
|
commit: {
|
|
48
|
-
message: string;
|
|
49
57
|
branchName: string;
|
|
50
|
-
|
|
51
|
-
url: string | null;
|
|
58
|
+
message: string;
|
|
52
59
|
createdAt: string | null;
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
namespaceId: string | null;
|
|
61
|
+
repositoryId: string | null;
|
|
62
|
+
url: string | null;
|
|
63
|
+
sha: string | null;
|
|
55
64
|
author: {
|
|
56
65
|
name: string;
|
|
57
66
|
email: string;
|
|
58
67
|
image: string | null;
|
|
59
68
|
};
|
|
69
|
+
statuses: Array<{
|
|
70
|
+
name: string;
|
|
71
|
+
description: string;
|
|
72
|
+
status: 'pending' | 'running' | 'success' | 'failed';
|
|
73
|
+
url: string | null;
|
|
74
|
+
}>;
|
|
60
75
|
};
|
|
61
76
|
remote: {
|
|
62
77
|
commits: {
|
|
63
|
-
branchName: string;
|
|
64
78
|
sha: string;
|
|
79
|
+
branchName: string;
|
|
65
80
|
}[];
|
|
66
81
|
};
|
|
67
|
-
hasChanges: boolean;
|
|
68
|
-
isOutdated: boolean;
|
|
69
|
-
isMainBranch: boolean;
|
|
70
82
|
status: PushStatusResponse;
|
|
71
83
|
};
|
|
72
|
-
type DeploymentStatusResponse = {
|
|
84
|
+
export type DeploymentStatusResponse = {
|
|
73
85
|
deploy: {
|
|
74
86
|
url: string | null;
|
|
75
87
|
status: DeploymentStatus;
|
|
@@ -88,4 +100,3 @@ export type ScorecardItem = {
|
|
|
88
100
|
};
|
|
89
101
|
export type PushStatusBase = 'pending' | 'success' | 'running' | 'failed';
|
|
90
102
|
export type DeploymentStatus = 'skipped' | PushStatusBase;
|
|
91
|
-
export {};
|
|
@@ -10,12 +10,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const push_status_1 = require("../push-status");
|
|
13
|
-
const miscellaneous_1 = require("../../../utils/miscellaneous");
|
|
14
13
|
const remotes = {
|
|
15
14
|
getPush: jest.fn(),
|
|
16
15
|
getRemotesList: jest.fn(),
|
|
17
16
|
};
|
|
18
|
-
jest.mock('../../../utils/miscellaneous');
|
|
19
17
|
jest.mock('colorette', () => ({
|
|
20
18
|
green: (str) => str,
|
|
21
19
|
yellow: (str) => str,
|
|
@@ -27,22 +25,49 @@ jest.mock('colorette', () => ({
|
|
|
27
25
|
jest.mock('../../api', () => (Object.assign(Object.assign({}, jest.requireActual('../../api')), { ReuniteApiClient: jest.fn().mockImplementation(function (...args) {
|
|
28
26
|
this.remotes = remotes;
|
|
29
27
|
}) })));
|
|
28
|
+
jest.mock('@redocly/openapi-core', () => ({
|
|
29
|
+
pause: jest.requireActual('@redocly/openapi-core').pause,
|
|
30
|
+
}));
|
|
30
31
|
describe('handlePushStatus()', () => {
|
|
31
32
|
const mockConfig = { apis: {} };
|
|
33
|
+
const commitStub = {
|
|
34
|
+
message: 'test-commit-message',
|
|
35
|
+
branchName: 'test-branch-name',
|
|
36
|
+
sha: null,
|
|
37
|
+
url: null,
|
|
38
|
+
createdAt: null,
|
|
39
|
+
namespaceId: null,
|
|
40
|
+
repositoryId: null,
|
|
41
|
+
author: {
|
|
42
|
+
name: 'test-author-name',
|
|
43
|
+
email: 'test-author-email',
|
|
44
|
+
image: null,
|
|
45
|
+
},
|
|
46
|
+
statuses: [],
|
|
47
|
+
};
|
|
32
48
|
const pushResponseStub = {
|
|
49
|
+
id: 'test-push-id',
|
|
50
|
+
remoteId: 'test-remote-id',
|
|
51
|
+
replace: false,
|
|
52
|
+
scoutJobId: null,
|
|
53
|
+
uploadedFiles: [],
|
|
54
|
+
commit: commitStub,
|
|
55
|
+
remote: { commits: [] },
|
|
56
|
+
isOutdated: false,
|
|
57
|
+
isMainBranch: false,
|
|
33
58
|
hasChanges: true,
|
|
34
59
|
status: {
|
|
35
60
|
preview: {
|
|
36
61
|
scorecard: [],
|
|
37
62
|
deploy: {
|
|
38
|
-
url: 'https://test-url',
|
|
63
|
+
url: 'https://preview-test-url',
|
|
39
64
|
status: 'success',
|
|
40
65
|
},
|
|
41
66
|
},
|
|
42
67
|
production: {
|
|
43
68
|
scorecard: [],
|
|
44
69
|
deploy: {
|
|
45
|
-
url: 'https://test-url',
|
|
70
|
+
url: 'https://production-test-url',
|
|
46
71
|
status: 'success',
|
|
47
72
|
},
|
|
48
73
|
},
|
|
@@ -56,16 +81,16 @@ describe('handlePushStatus()', () => {
|
|
|
56
81
|
jest.clearAllMocks();
|
|
57
82
|
});
|
|
58
83
|
it('should throw error if organization not provided', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
59
|
-
yield (0, push_status_1.handlePushStatus)({
|
|
84
|
+
yield expect((0, push_status_1.handlePushStatus)({
|
|
60
85
|
domain: 'test-domain',
|
|
61
86
|
organization: '',
|
|
62
87
|
project: 'test-project',
|
|
63
88
|
pushId: 'test-push-id',
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
89
|
+
}, mockConfig)).rejects.toThrowErrorMatchingInlineSnapshot(`"No organization provided, please use --organization option or specify the 'organization' field in the config file."`);
|
|
90
|
+
expect(process.stderr.write).toHaveBeenCalledWith(`No organization provided, please use --organization option or specify the 'organization' field in the config file.` +
|
|
91
|
+
'\n\n');
|
|
67
92
|
}));
|
|
68
|
-
it('should
|
|
93
|
+
it('should print success push status for preview-build', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
94
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
70
95
|
remotes.getPush.mockResolvedValueOnce(pushResponseStub);
|
|
71
96
|
yield (0, push_status_1.handlePushStatus)({
|
|
@@ -73,12 +98,11 @@ describe('handlePushStatus()', () => {
|
|
|
73
98
|
organization: 'test-org',
|
|
74
99
|
project: 'test-project',
|
|
75
100
|
pushId: 'test-push-id',
|
|
76
|
-
'max-execution-time': 1000,
|
|
77
101
|
}, mockConfig);
|
|
78
102
|
expect(process.stdout.write).toHaveBeenCalledTimes(1);
|
|
79
|
-
expect(process.stdout.write).toHaveBeenCalledWith('🚀 Preview deploy success.\nPreview URL: https://test-url\n');
|
|
103
|
+
expect(process.stdout.write).toHaveBeenCalledWith('🚀 Preview deploy success.\nPreview URL: https://preview-test-url\n');
|
|
80
104
|
}));
|
|
81
|
-
it('should
|
|
105
|
+
it('should print success push status for preview and production builds', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
82
106
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
83
107
|
remotes.getPush.mockResolvedValue(Object.assign(Object.assign({}, pushResponseStub), { isMainBranch: true }));
|
|
84
108
|
yield (0, push_status_1.handlePushStatus)({
|
|
@@ -86,38 +110,39 @@ describe('handlePushStatus()', () => {
|
|
|
86
110
|
organization: 'test-org',
|
|
87
111
|
project: 'test-project',
|
|
88
112
|
pushId: 'test-push-id',
|
|
89
|
-
'max-execution-time': 1000,
|
|
90
113
|
}, mockConfig);
|
|
91
114
|
expect(process.stdout.write).toHaveBeenCalledTimes(2);
|
|
92
|
-
expect(process.stdout.write).toHaveBeenCalledWith('🚀 Preview deploy success.\nPreview URL: https://test-url\n');
|
|
93
|
-
expect(process.stdout.write).toHaveBeenCalledWith('🚀 Production deploy success.\nProduction URL: https://test-url\n');
|
|
115
|
+
expect(process.stdout.write).toHaveBeenCalledWith('🚀 Preview deploy success.\nPreview URL: https://preview-test-url\n');
|
|
116
|
+
expect(process.stdout.write).toHaveBeenCalledWith('🚀 Production deploy success.\nProduction URL: https://production-test-url\n');
|
|
94
117
|
}));
|
|
95
|
-
it('should
|
|
118
|
+
it('should print failed push status for preview build', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
96
119
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
97
120
|
remotes.getPush.mockResolvedValue({
|
|
98
121
|
isOutdated: false,
|
|
99
122
|
hasChanges: true,
|
|
100
123
|
status: {
|
|
101
|
-
preview: { deploy: { status: 'failed', url: 'https://test-url' }, scorecard: [] },
|
|
124
|
+
preview: { deploy: { status: 'failed', url: 'https://preview-test-url' }, scorecard: [] },
|
|
102
125
|
},
|
|
103
126
|
});
|
|
104
|
-
yield (0, push_status_1.handlePushStatus)({
|
|
127
|
+
yield expect((0, push_status_1.handlePushStatus)({
|
|
105
128
|
domain: 'test-domain',
|
|
106
129
|
organization: 'test-org',
|
|
107
130
|
project: 'test-project',
|
|
108
131
|
pushId: 'test-push-id',
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
132
|
+
}, mockConfig)).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
133
|
+
"❌ Preview deploy fail.
|
|
134
|
+
Preview URL: https://preview-test-url"
|
|
135
|
+
`);
|
|
136
|
+
expect(process.stderr.write).toHaveBeenCalledWith('❌ Preview deploy fail.\nPreview URL: https://preview-test-url' + '\n\n');
|
|
112
137
|
}));
|
|
113
|
-
it('should
|
|
138
|
+
it('should print success push status for preview build and print scorecards', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
114
139
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
115
140
|
remotes.getPush.mockResolvedValue({
|
|
116
141
|
isOutdated: false,
|
|
117
142
|
hasChanges: true,
|
|
118
143
|
status: {
|
|
119
144
|
preview: {
|
|
120
|
-
deploy: { status: 'success', url: 'https://test-url' },
|
|
145
|
+
deploy: { status: 'success', url: 'https://preview-test-url' },
|
|
121
146
|
scorecard: [
|
|
122
147
|
{
|
|
123
148
|
name: 'test-name',
|
|
@@ -134,21 +159,24 @@ describe('handlePushStatus()', () => {
|
|
|
134
159
|
organization: 'test-org',
|
|
135
160
|
project: 'test-project',
|
|
136
161
|
pushId: 'test-push-id',
|
|
137
|
-
'max-execution-time': 1000,
|
|
138
162
|
}, mockConfig);
|
|
139
163
|
expect(process.stdout.write).toHaveBeenCalledTimes(4);
|
|
140
|
-
expect(process.stdout.write).toHaveBeenCalledWith('🚀 Preview deploy success.\nPreview URL: https://test-url\n');
|
|
164
|
+
expect(process.stdout.write).toHaveBeenCalledWith('🚀 Preview deploy success.\nPreview URL: https://preview-test-url\n');
|
|
141
165
|
expect(process.stdout.write).toHaveBeenCalledWith('\nScorecard:');
|
|
142
166
|
expect(process.stdout.write).toHaveBeenCalledWith('\n Name: test-name\n Status: success\n URL: test-url\n Description: test-description\n');
|
|
143
167
|
expect(process.stdout.write).toHaveBeenCalledWith('\n');
|
|
144
168
|
}));
|
|
145
|
-
it('should
|
|
169
|
+
it('should print message if there is no changes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
146
170
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
147
171
|
remotes.getPush.mockResolvedValueOnce({
|
|
148
172
|
isOutdated: false,
|
|
149
173
|
hasChanges: false,
|
|
150
174
|
status: {
|
|
151
|
-
preview: { deploy: { status: 'skipped', url: 'https://test-url' }, scorecard: [] },
|
|
175
|
+
preview: { deploy: { status: 'skipped', url: 'https://preview-test-url' }, scorecard: [] },
|
|
176
|
+
production: {
|
|
177
|
+
deploy: { status: 'skipped', url: null },
|
|
178
|
+
scorecard: [],
|
|
179
|
+
},
|
|
152
180
|
},
|
|
153
181
|
});
|
|
154
182
|
yield (0, push_status_1.handlePushStatus)({
|
|
@@ -157,8 +185,289 @@ describe('handlePushStatus()', () => {
|
|
|
157
185
|
project: 'test-project',
|
|
158
186
|
pushId: 'test-push-id',
|
|
159
187
|
wait: true,
|
|
160
|
-
'max-execution-time': 1000,
|
|
161
188
|
}, mockConfig);
|
|
162
|
-
expect(process.stderr.write).toHaveBeenCalledWith('Files not
|
|
189
|
+
expect(process.stderr.write).toHaveBeenCalledWith('Files not added to your project. Reason: no changes.\n');
|
|
163
190
|
}));
|
|
191
|
+
describe('return value', () => {
|
|
192
|
+
it('should return preview deployment info', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
193
|
+
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
194
|
+
remotes.getPush.mockResolvedValue(Object.assign(Object.assign({}, pushResponseStub), { isMainBranch: false }));
|
|
195
|
+
const result = yield (0, push_status_1.handlePushStatus)({
|
|
196
|
+
domain: 'test-domain',
|
|
197
|
+
organization: 'test-org',
|
|
198
|
+
project: 'test-project',
|
|
199
|
+
pushId: 'test-push-id',
|
|
200
|
+
}, mockConfig);
|
|
201
|
+
expect(result).toEqual({
|
|
202
|
+
preview: {
|
|
203
|
+
deploy: {
|
|
204
|
+
status: 'success',
|
|
205
|
+
url: 'https://preview-test-url',
|
|
206
|
+
},
|
|
207
|
+
scorecard: [],
|
|
208
|
+
},
|
|
209
|
+
production: null,
|
|
210
|
+
commit: commitStub,
|
|
211
|
+
});
|
|
212
|
+
}));
|
|
213
|
+
it('should return preview and production deployment info', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
214
|
+
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
215
|
+
remotes.getPush.mockResolvedValue(Object.assign(Object.assign({}, pushResponseStub), { isMainBranch: true }));
|
|
216
|
+
const result = yield (0, push_status_1.handlePushStatus)({
|
|
217
|
+
domain: 'test-domain',
|
|
218
|
+
organization: 'test-org',
|
|
219
|
+
project: 'test-project',
|
|
220
|
+
pushId: 'test-push-id',
|
|
221
|
+
}, mockConfig);
|
|
222
|
+
expect(result).toEqual({
|
|
223
|
+
preview: {
|
|
224
|
+
deploy: {
|
|
225
|
+
status: 'success',
|
|
226
|
+
url: 'https://preview-test-url',
|
|
227
|
+
},
|
|
228
|
+
scorecard: [],
|
|
229
|
+
},
|
|
230
|
+
production: {
|
|
231
|
+
deploy: {
|
|
232
|
+
status: 'success',
|
|
233
|
+
url: 'https://production-test-url',
|
|
234
|
+
},
|
|
235
|
+
scorecard: [],
|
|
236
|
+
},
|
|
237
|
+
commit: commitStub,
|
|
238
|
+
});
|
|
239
|
+
}));
|
|
240
|
+
});
|
|
241
|
+
describe('"wait" option', () => {
|
|
242
|
+
it('should wait for preview "success" deployment status', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
243
|
+
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
244
|
+
remotes.getPush.mockResolvedValueOnce(Object.assign(Object.assign({}, pushResponseStub), { status: {
|
|
245
|
+
preview: {
|
|
246
|
+
deploy: { status: 'pending', url: 'https://preview-test-url' },
|
|
247
|
+
scorecard: [],
|
|
248
|
+
},
|
|
249
|
+
} }));
|
|
250
|
+
remotes.getPush.mockResolvedValueOnce(Object.assign(Object.assign({}, pushResponseStub), { status: {
|
|
251
|
+
preview: {
|
|
252
|
+
deploy: { status: 'running', url: 'https://preview-test-url' },
|
|
253
|
+
scorecard: [],
|
|
254
|
+
},
|
|
255
|
+
} }));
|
|
256
|
+
remotes.getPush.mockResolvedValueOnce(Object.assign(Object.assign({}, pushResponseStub), { status: {
|
|
257
|
+
preview: {
|
|
258
|
+
deploy: { status: 'success', url: 'https://preview-test-url' },
|
|
259
|
+
scorecard: [],
|
|
260
|
+
},
|
|
261
|
+
} }));
|
|
262
|
+
const result = yield (0, push_status_1.handlePushStatus)({
|
|
263
|
+
domain: 'test-domain',
|
|
264
|
+
organization: 'test-org',
|
|
265
|
+
project: 'test-project',
|
|
266
|
+
pushId: 'test-push-id',
|
|
267
|
+
'retry-interval': 0.5,
|
|
268
|
+
wait: true,
|
|
269
|
+
}, mockConfig);
|
|
270
|
+
expect(result).toEqual({
|
|
271
|
+
preview: {
|
|
272
|
+
deploy: {
|
|
273
|
+
status: 'success',
|
|
274
|
+
url: 'https://preview-test-url',
|
|
275
|
+
},
|
|
276
|
+
scorecard: [],
|
|
277
|
+
},
|
|
278
|
+
production: null,
|
|
279
|
+
commit: commitStub,
|
|
280
|
+
});
|
|
281
|
+
}));
|
|
282
|
+
it('should wait for production "success" status after preview "success" status', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
283
|
+
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
284
|
+
remotes.getPush.mockResolvedValueOnce(Object.assign(Object.assign({}, pushResponseStub), { isMainBranch: true, status: {
|
|
285
|
+
preview: {
|
|
286
|
+
deploy: { status: 'success', url: 'https://preview-test-url' },
|
|
287
|
+
scorecard: [],
|
|
288
|
+
},
|
|
289
|
+
production: {
|
|
290
|
+
deploy: { status: 'pending', url: 'https://production-test-url' },
|
|
291
|
+
scorecard: [],
|
|
292
|
+
},
|
|
293
|
+
} }));
|
|
294
|
+
remotes.getPush.mockResolvedValueOnce(Object.assign(Object.assign({}, pushResponseStub), { isMainBranch: true, status: {
|
|
295
|
+
preview: {
|
|
296
|
+
deploy: { status: 'success', url: 'https://preview-test-url' },
|
|
297
|
+
scorecard: [],
|
|
298
|
+
},
|
|
299
|
+
production: {
|
|
300
|
+
deploy: { status: 'running', url: 'https://production-test-url' },
|
|
301
|
+
scorecard: [],
|
|
302
|
+
},
|
|
303
|
+
} }));
|
|
304
|
+
remotes.getPush.mockResolvedValueOnce(Object.assign(Object.assign({}, pushResponseStub), { isMainBranch: true, status: {
|
|
305
|
+
preview: {
|
|
306
|
+
deploy: { status: 'success', url: 'https://preview-test-url' },
|
|
307
|
+
scorecard: [],
|
|
308
|
+
},
|
|
309
|
+
production: {
|
|
310
|
+
deploy: { status: 'success', url: 'https://production-test-url' },
|
|
311
|
+
scorecard: [],
|
|
312
|
+
},
|
|
313
|
+
} }));
|
|
314
|
+
const result = yield (0, push_status_1.handlePushStatus)({
|
|
315
|
+
domain: 'test-domain',
|
|
316
|
+
organization: 'test-org',
|
|
317
|
+
project: 'test-project',
|
|
318
|
+
pushId: 'test-push-id',
|
|
319
|
+
'retry-interval': 0.5,
|
|
320
|
+
wait: true,
|
|
321
|
+
}, mockConfig);
|
|
322
|
+
expect(result).toEqual({
|
|
323
|
+
preview: {
|
|
324
|
+
deploy: { status: 'success', url: 'https://preview-test-url' },
|
|
325
|
+
scorecard: [],
|
|
326
|
+
},
|
|
327
|
+
production: {
|
|
328
|
+
deploy: { status: 'success', url: 'https://production-test-url' },
|
|
329
|
+
scorecard: [],
|
|
330
|
+
},
|
|
331
|
+
commit: commitStub,
|
|
332
|
+
});
|
|
333
|
+
}));
|
|
334
|
+
});
|
|
335
|
+
describe('"continue-on-deploy-failures" option', () => {
|
|
336
|
+
it('should throw error if option value is false', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
337
|
+
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
338
|
+
remotes.getPush.mockResolvedValueOnce(Object.assign(Object.assign({}, pushResponseStub), { status: {
|
|
339
|
+
preview: {
|
|
340
|
+
deploy: { status: 'failed', url: 'https://preview-test-url' },
|
|
341
|
+
scorecard: [],
|
|
342
|
+
},
|
|
343
|
+
} }));
|
|
344
|
+
yield expect((0, push_status_1.handlePushStatus)({
|
|
345
|
+
domain: 'test-domain',
|
|
346
|
+
organization: 'test-org',
|
|
347
|
+
project: 'test-project',
|
|
348
|
+
pushId: 'test-push-id',
|
|
349
|
+
'continue-on-deploy-failures': false,
|
|
350
|
+
}, mockConfig)).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
351
|
+
"❌ Preview deploy fail.
|
|
352
|
+
Preview URL: https://preview-test-url"
|
|
353
|
+
`);
|
|
354
|
+
}));
|
|
355
|
+
it('should not throw error if option value is true', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
356
|
+
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
357
|
+
remotes.getPush.mockResolvedValueOnce(Object.assign(Object.assign({}, pushResponseStub), { status: {
|
|
358
|
+
preview: {
|
|
359
|
+
deploy: { status: 'failed', url: 'https://preview-test-url' },
|
|
360
|
+
scorecard: [],
|
|
361
|
+
},
|
|
362
|
+
} }));
|
|
363
|
+
yield expect((0, push_status_1.handlePushStatus)({
|
|
364
|
+
domain: 'test-domain',
|
|
365
|
+
organization: 'test-org',
|
|
366
|
+
project: 'test-project',
|
|
367
|
+
pushId: 'test-push-id',
|
|
368
|
+
'continue-on-deploy-failures': true,
|
|
369
|
+
}, mockConfig)).resolves.toStrictEqual({
|
|
370
|
+
preview: {
|
|
371
|
+
deploy: { status: 'failed', url: 'https://preview-test-url' },
|
|
372
|
+
scorecard: [],
|
|
373
|
+
},
|
|
374
|
+
production: null,
|
|
375
|
+
commit: commitStub,
|
|
376
|
+
});
|
|
377
|
+
}));
|
|
378
|
+
});
|
|
379
|
+
describe('"onRetry" callback', () => {
|
|
380
|
+
it('should be called when command retries request to API in wait mode for preview deploy', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
381
|
+
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
382
|
+
remotes.getPush.mockResolvedValueOnce(Object.assign(Object.assign({}, pushResponseStub), { status: {
|
|
383
|
+
preview: {
|
|
384
|
+
deploy: { status: 'pending', url: 'https://preview-test-url' },
|
|
385
|
+
scorecard: [],
|
|
386
|
+
},
|
|
387
|
+
} }));
|
|
388
|
+
remotes.getPush.mockResolvedValueOnce(Object.assign(Object.assign({}, pushResponseStub), { status: {
|
|
389
|
+
preview: {
|
|
390
|
+
deploy: { status: 'running', url: 'https://preview-test-url' },
|
|
391
|
+
scorecard: [],
|
|
392
|
+
},
|
|
393
|
+
} }));
|
|
394
|
+
remotes.getPush.mockResolvedValueOnce(Object.assign(Object.assign({}, pushResponseStub), { status: {
|
|
395
|
+
preview: {
|
|
396
|
+
deploy: { status: 'success', url: 'https://preview-test-url' },
|
|
397
|
+
scorecard: [],
|
|
398
|
+
},
|
|
399
|
+
} }));
|
|
400
|
+
const onRetrySpy = jest.fn();
|
|
401
|
+
const result = yield (0, push_status_1.handlePushStatus)({
|
|
402
|
+
domain: 'test-domain',
|
|
403
|
+
organization: 'test-org',
|
|
404
|
+
project: 'test-project',
|
|
405
|
+
pushId: 'test-push-id',
|
|
406
|
+
wait: true,
|
|
407
|
+
'retry-interval': 0.5,
|
|
408
|
+
onRetry: onRetrySpy,
|
|
409
|
+
}, mockConfig);
|
|
410
|
+
expect(onRetrySpy).toBeCalledTimes(2);
|
|
411
|
+
// first retry
|
|
412
|
+
expect(onRetrySpy).toHaveBeenNthCalledWith(1, {
|
|
413
|
+
preview: {
|
|
414
|
+
deploy: {
|
|
415
|
+
status: 'pending',
|
|
416
|
+
url: 'https://preview-test-url',
|
|
417
|
+
},
|
|
418
|
+
scorecard: [],
|
|
419
|
+
},
|
|
420
|
+
production: null,
|
|
421
|
+
commit: commitStub,
|
|
422
|
+
});
|
|
423
|
+
// second retry
|
|
424
|
+
expect(onRetrySpy).toHaveBeenNthCalledWith(2, {
|
|
425
|
+
preview: {
|
|
426
|
+
deploy: {
|
|
427
|
+
status: 'running',
|
|
428
|
+
url: 'https://preview-test-url',
|
|
429
|
+
},
|
|
430
|
+
scorecard: [],
|
|
431
|
+
},
|
|
432
|
+
production: null,
|
|
433
|
+
commit: commitStub,
|
|
434
|
+
});
|
|
435
|
+
// final result
|
|
436
|
+
expect(result).toEqual({
|
|
437
|
+
preview: {
|
|
438
|
+
deploy: {
|
|
439
|
+
status: 'success',
|
|
440
|
+
url: 'https://preview-test-url',
|
|
441
|
+
},
|
|
442
|
+
scorecard: [],
|
|
443
|
+
},
|
|
444
|
+
production: null,
|
|
445
|
+
commit: commitStub,
|
|
446
|
+
});
|
|
447
|
+
}));
|
|
448
|
+
});
|
|
449
|
+
describe('"max-execution-time" option', () => {
|
|
450
|
+
it('should throw error in case "max-execution-time" was exceeded', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
451
|
+
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
452
|
+
// Stuck deployment simulation
|
|
453
|
+
remotes.getPush.mockResolvedValue(Object.assign(Object.assign({}, pushResponseStub), { status: {
|
|
454
|
+
preview: {
|
|
455
|
+
deploy: { status: 'pending', url: 'https://preview-test-url' },
|
|
456
|
+
scorecard: [],
|
|
457
|
+
},
|
|
458
|
+
} }));
|
|
459
|
+
yield expect((0, push_status_1.handlePushStatus)({
|
|
460
|
+
domain: 'test-domain',
|
|
461
|
+
organization: 'test-org',
|
|
462
|
+
project: 'test-project',
|
|
463
|
+
pushId: 'test-push-id',
|
|
464
|
+
'retry-interval': 2,
|
|
465
|
+
'max-execution-time': 1,
|
|
466
|
+
wait: true,
|
|
467
|
+
}, mockConfig)).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
468
|
+
"✗ Failed to get push status. Reason: Timeout exceeded
|
|
469
|
+
"
|
|
470
|
+
`);
|
|
471
|
+
}));
|
|
472
|
+
});
|
|
164
473
|
});
|
|
@@ -32,8 +32,8 @@ describe('handlePush()', () => {
|
|
|
32
32
|
let fsReaddirSyncSpy;
|
|
33
33
|
beforeEach(() => {
|
|
34
34
|
remotes.getDefaultBranch.mockResolvedValueOnce('test-default-branch');
|
|
35
|
-
remotes.upsert.mockResolvedValueOnce({ id: 'test-remote-id' });
|
|
36
|
-
remotes.push.mockResolvedValueOnce({ branchName: 'uploaded-to-branch' });
|
|
35
|
+
remotes.upsert.mockResolvedValueOnce({ id: 'test-remote-id', mountPath: 'test-mount-path' });
|
|
36
|
+
remotes.push.mockResolvedValueOnce({ branchName: 'uploaded-to-branch', id: 'test-id' });
|
|
37
37
|
jest.spyOn(fs, 'createReadStream').mockReturnValue('stream');
|
|
38
38
|
pathResolveSpy = jest.spyOn(path, 'resolve');
|
|
39
39
|
pathRelativeSpy = jest.spyOn(path, 'relative');
|
|
@@ -104,6 +104,36 @@ describe('handlePush()', () => {
|
|
|
104
104
|
},
|
|
105
105
|
]);
|
|
106
106
|
}));
|
|
107
|
+
it('should return push id', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
108
|
+
const mockConfig = { apis: {} };
|
|
109
|
+
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
110
|
+
fsStatSyncSpy.mockReturnValueOnce({
|
|
111
|
+
isDirectory() {
|
|
112
|
+
return false;
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
pathResolveSpy.mockImplementationOnce((p) => p);
|
|
116
|
+
pathRelativeSpy.mockImplementationOnce((_, p) => p);
|
|
117
|
+
pathDirnameSpy.mockImplementation((_) => '.');
|
|
118
|
+
const result = yield (0, push_1.handlePush)({
|
|
119
|
+
domain: 'test-domain',
|
|
120
|
+
'mount-path': 'test-mount-path',
|
|
121
|
+
organization: 'test-org',
|
|
122
|
+
project: 'test-project',
|
|
123
|
+
branch: 'test-branch',
|
|
124
|
+
namespace: 'test-namespace',
|
|
125
|
+
repository: 'test-repository',
|
|
126
|
+
'commit-sha': 'test-commit-sha',
|
|
127
|
+
'commit-url': 'test-commit-url',
|
|
128
|
+
'default-branch': 'test-branch',
|
|
129
|
+
'created-at': 'test-created-at',
|
|
130
|
+
author: 'TestAuthor <test-author@mail.com>',
|
|
131
|
+
message: 'Test message',
|
|
132
|
+
files: ['test-file'],
|
|
133
|
+
'max-execution-time': 10,
|
|
134
|
+
}, mockConfig);
|
|
135
|
+
expect(result).toEqual({ pushId: 'test-id' });
|
|
136
|
+
}));
|
|
107
137
|
it('should collect files from directory and preserve file structure', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
108
138
|
const mockConfig = { apis: {} };
|
|
109
139
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|