@redocly/cli 1.18.1 → 1.20.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/CHANGELOG.md +24 -0
- package/lib/__mocks__/@redocly/openapi-core.d.ts +2 -2
- package/lib/__mocks__/@redocly/openapi-core.js +1 -0
- package/lib/__mocks__/fs.d.ts +0 -1
- package/lib/__mocks__/perf_hooks.d.ts +0 -1
- package/lib/__mocks__/redoc.d.ts +0 -1
- package/lib/__tests__/commands/build-docs.test.js +21 -23
- package/lib/__tests__/commands/bundle.test.js +21 -30
- package/lib/__tests__/commands/join.test.js +101 -70
- package/lib/__tests__/commands/lint.test.js +54 -54
- package/lib/__tests__/commands/push-region.test.js +24 -25
- package/lib/__tests__/commands/push.test.js +269 -170
- package/lib/__tests__/fetch-with-timeout.test.js +3 -12
- package/lib/__tests__/fixtures/config.d.ts +0 -1
- package/lib/__tests__/utils.test.js +32 -37
- package/lib/__tests__/wrapper.test.js +31 -20
- package/lib/cms/api/__tests__/api.client.test.js +29 -38
- package/lib/cms/api/api-client.d.ts +0 -2
- package/lib/cms/api/api-client.js +107 -128
- package/lib/cms/api/api-keys.js +1 -2
- package/lib/cms/api/domains.js +1 -2
- package/lib/cms/commands/__tests__/push-status.test.js +251 -162
- package/lib/cms/commands/__tests__/push.test.js +120 -102
- package/lib/cms/commands/__tests__/utils.test.js +12 -21
- package/lib/cms/commands/push-status.d.ts +3 -2
- package/lib/cms/commands/push-status.js +94 -106
- package/lib/cms/commands/push.d.ts +3 -2
- package/lib/cms/commands/push.js +66 -74
- package/lib/cms/commands/utils.js +20 -34
- package/lib/commands/build-docs/index.d.ts +2 -2
- package/lib/commands/build-docs/index.js +8 -17
- package/lib/commands/build-docs/utils.d.ts +1 -1
- package/lib/commands/build-docs/utils.js +27 -39
- package/lib/commands/bundle.d.ts +2 -2
- package/lib/commands/bundle.js +70 -94
- package/lib/commands/join.d.ts +2 -2
- package/lib/commands/join.js +375 -388
- package/lib/commands/lint.d.ts +2 -2
- package/lib/commands/lint.js +64 -75
- package/lib/commands/login.d.ts +3 -2
- package/lib/commands/login.js +10 -22
- package/lib/commands/preview-docs/index.d.ts +2 -2
- package/lib/commands/preview-docs/index.js +93 -106
- package/lib/commands/preview-docs/preview-server/preview-server.js +64 -76
- package/lib/commands/preview-docs/preview-server/server.d.ts +1 -4
- package/lib/commands/preview-docs/preview-server/server.js +6 -6
- package/lib/commands/preview-project/constants.d.ts +1 -1
- package/lib/commands/preview-project/index.d.ts +2 -1
- package/lib/commands/preview-project/index.js +5 -14
- package/lib/commands/preview-project/types.d.ts +1 -1
- package/lib/commands/push.d.ts +9 -12
- package/lib/commands/push.js +180 -196
- package/lib/commands/split/__tests__/index.test.js +31 -25
- package/lib/commands/split/index.d.ts +2 -1
- package/lib/commands/split/index.js +20 -33
- package/lib/commands/stats.d.ts +2 -2
- package/lib/commands/stats.js +36 -47
- package/lib/index.js +34 -49
- package/lib/types.d.ts +4 -5
- package/lib/utils/__mocks__/miscellaneous.d.ts +0 -1
- package/lib/utils/fetch-with-timeout.js +7 -12
- package/lib/utils/getCommandNameFromArgs.d.ts +1 -1
- package/lib/utils/getCommandNameFromArgs.js +2 -4
- package/lib/utils/js-utils.js +6 -7
- package/lib/utils/miscellaneous.d.ts +4 -1
- package/lib/utils/miscellaneous.js +130 -152
- package/lib/utils/update-version-notifier.js +4 -13
- package/lib/wrapper.d.ts +9 -2
- package/lib/wrapper.js +27 -16
- package/package.json +3 -3
- package/src/__mocks__/@redocly/openapi-core.ts +1 -0
- package/src/__tests__/commands/build-docs.test.ts +5 -4
- package/src/__tests__/commands/join.test.ts +51 -51
- package/src/__tests__/commands/push-region.test.ts +10 -8
- package/src/__tests__/commands/push.test.ts +127 -102
- package/src/__tests__/utils.test.ts +1 -0
- package/src/__tests__/wrapper.test.ts +24 -2
- package/src/cms/api/api-client.ts +2 -1
- package/src/cms/commands/__tests__/push-status.test.ts +70 -56
- package/src/cms/commands/__tests__/push.test.ts +30 -24
- package/src/cms/commands/push-status.ts +8 -7
- package/src/cms/commands/push.ts +12 -9
- package/src/commands/build-docs/index.ts +10 -5
- package/src/commands/build-docs/utils.ts +4 -4
- package/src/commands/bundle.ts +14 -6
- package/src/commands/join.ts +6 -2
- package/src/commands/lint.ts +9 -3
- package/src/commands/login.ts +5 -2
- package/src/commands/preview-docs/index.ts +7 -1
- package/src/commands/preview-docs/preview-server/preview-server.ts +4 -3
- package/src/commands/preview-docs/preview-server/server.ts +2 -1
- package/src/commands/preview-project/constants.ts +1 -1
- package/src/commands/preview-project/index.ts +5 -4
- package/src/commands/preview-project/types.ts +1 -1
- package/src/commands/push.ts +15 -18
- package/src/commands/split/__tests__/index.test.ts +17 -6
- package/src/commands/split/index.ts +4 -2
- package/src/commands/stats.ts +13 -6
- package/src/index.ts +13 -7
- package/src/types.ts +2 -3
- package/src/utils/getCommandNameFromArgs.ts +1 -1
- package/src/utils/miscellaneous.ts +11 -1
- package/src/wrapper.ts +37 -11
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,13 +1,4 @@
|
|
|
1
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
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
const fs = require("fs");
|
|
13
4
|
const path = require("path");
|
|
@@ -21,9 +12,12 @@ const remotes = {
|
|
|
21
12
|
jest.mock('@redocly/openapi-core', () => ({
|
|
22
13
|
slash: jest.fn().mockImplementation((p) => p),
|
|
23
14
|
}));
|
|
24
|
-
jest.mock('../../api', () => (
|
|
15
|
+
jest.mock('../../api', () => ({
|
|
16
|
+
...jest.requireActual('../../api'),
|
|
17
|
+
ReuniteApiClient: jest.fn().mockImplementation(function (...args) {
|
|
25
18
|
this.remotes = remotes;
|
|
26
|
-
})
|
|
19
|
+
}),
|
|
20
|
+
}));
|
|
27
21
|
describe('handlePush()', () => {
|
|
28
22
|
let pathResolveSpy;
|
|
29
23
|
let pathRelativeSpy;
|
|
@@ -48,7 +42,7 @@ describe('handlePush()', () => {
|
|
|
48
42
|
fsStatSyncSpy.mockRestore();
|
|
49
43
|
fsReaddirSyncSpy.mockRestore();
|
|
50
44
|
});
|
|
51
|
-
it('should upload files', () =>
|
|
45
|
+
it('should upload files', async () => {
|
|
52
46
|
const mockConfig = { apis: {} };
|
|
53
47
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
54
48
|
fsStatSyncSpy.mockReturnValueOnce({
|
|
@@ -59,23 +53,27 @@ describe('handlePush()', () => {
|
|
|
59
53
|
pathResolveSpy.mockImplementationOnce((p) => p);
|
|
60
54
|
pathRelativeSpy.mockImplementationOnce((_, p) => p);
|
|
61
55
|
pathDirnameSpy.mockImplementation((_) => '.');
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
56
|
+
await (0, push_1.handlePush)({
|
|
57
|
+
argv: {
|
|
58
|
+
domain: 'test-domain',
|
|
59
|
+
'mount-path': 'test-mount-path',
|
|
60
|
+
organization: 'test-org',
|
|
61
|
+
project: 'test-project',
|
|
62
|
+
branch: 'test-branch',
|
|
63
|
+
namespace: 'test-namespace',
|
|
64
|
+
repository: 'test-repository',
|
|
65
|
+
'commit-sha': 'test-commit-sha',
|
|
66
|
+
'commit-url': 'test-commit-url',
|
|
67
|
+
'default-branch': 'test-branch',
|
|
68
|
+
'created-at': 'test-created-at',
|
|
69
|
+
author: 'TestAuthor <test-author@mail.com>',
|
|
70
|
+
message: 'Test message',
|
|
71
|
+
files: ['test-file'],
|
|
72
|
+
'max-execution-time': 10,
|
|
73
|
+
},
|
|
74
|
+
config: mockConfig,
|
|
75
|
+
version: 'cli-version',
|
|
76
|
+
});
|
|
79
77
|
expect(remotes.getDefaultBranch).toHaveBeenCalledWith('test-org', 'test-project');
|
|
80
78
|
expect(remotes.upsert).toHaveBeenCalledWith('test-org', 'test-project', {
|
|
81
79
|
mountBranchName: 'test-default-branch',
|
|
@@ -103,8 +101,8 @@ describe('handlePush()', () => {
|
|
|
103
101
|
stream: 'stream',
|
|
104
102
|
},
|
|
105
103
|
]);
|
|
106
|
-
})
|
|
107
|
-
it('should return push id', () =>
|
|
104
|
+
});
|
|
105
|
+
it('should return push id', async () => {
|
|
108
106
|
const mockConfig = { apis: {} };
|
|
109
107
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
110
108
|
fsStatSyncSpy.mockReturnValueOnce({
|
|
@@ -115,26 +113,30 @@ describe('handlePush()', () => {
|
|
|
115
113
|
pathResolveSpy.mockImplementationOnce((p) => p);
|
|
116
114
|
pathRelativeSpy.mockImplementationOnce((_, p) => p);
|
|
117
115
|
pathDirnameSpy.mockImplementation((_) => '.');
|
|
118
|
-
const result =
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
116
|
+
const result = await (0, push_1.handlePush)({
|
|
117
|
+
argv: {
|
|
118
|
+
domain: 'test-domain',
|
|
119
|
+
'mount-path': 'test-mount-path',
|
|
120
|
+
organization: 'test-org',
|
|
121
|
+
project: 'test-project',
|
|
122
|
+
branch: 'test-branch',
|
|
123
|
+
namespace: 'test-namespace',
|
|
124
|
+
repository: 'test-repository',
|
|
125
|
+
'commit-sha': 'test-commit-sha',
|
|
126
|
+
'commit-url': 'test-commit-url',
|
|
127
|
+
'default-branch': 'test-branch',
|
|
128
|
+
'created-at': 'test-created-at',
|
|
129
|
+
author: 'TestAuthor <test-author@mail.com>',
|
|
130
|
+
message: 'Test message',
|
|
131
|
+
files: ['test-file'],
|
|
132
|
+
'max-execution-time': 10,
|
|
133
|
+
},
|
|
134
|
+
config: mockConfig,
|
|
135
|
+
version: 'cli-version',
|
|
136
|
+
});
|
|
135
137
|
expect(result).toEqual({ pushId: 'test-id' });
|
|
136
|
-
})
|
|
137
|
-
it('should collect files from directory and preserve file structure', () =>
|
|
138
|
+
});
|
|
139
|
+
it('should collect files from directory and preserve file structure', async () => {
|
|
138
140
|
const mockConfig = { apis: {} };
|
|
139
141
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
140
142
|
/*
|
|
@@ -157,18 +159,22 @@ describe('handlePush()', () => {
|
|
|
157
159
|
}
|
|
158
160
|
throw new Error('Not a directory');
|
|
159
161
|
});
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
162
|
+
await (0, push_1.handlePush)({
|
|
163
|
+
argv: {
|
|
164
|
+
domain: 'test-domain',
|
|
165
|
+
'mount-path': 'test-mount-path',
|
|
166
|
+
organization: 'test-org',
|
|
167
|
+
project: 'test-project',
|
|
168
|
+
branch: 'test-branch',
|
|
169
|
+
author: 'TestAuthor <test-author@mail.com>',
|
|
170
|
+
message: 'Test message',
|
|
171
|
+
'default-branch': 'main',
|
|
172
|
+
files: ['test-folder'],
|
|
173
|
+
'max-execution-time': 10,
|
|
174
|
+
},
|
|
175
|
+
config: mockConfig,
|
|
176
|
+
version: 'cli-version',
|
|
177
|
+
});
|
|
172
178
|
expect(remotes.push).toHaveBeenCalledWith(expect.anything(), expect.anything(), expect.anything(), [
|
|
173
179
|
{
|
|
174
180
|
path: 'app/index.html',
|
|
@@ -183,27 +189,31 @@ describe('handlePush()', () => {
|
|
|
183
189
|
stream: 'stream',
|
|
184
190
|
},
|
|
185
191
|
]);
|
|
186
|
-
})
|
|
187
|
-
it('should not upload files if no files passed', () =>
|
|
192
|
+
});
|
|
193
|
+
it('should not upload files if no files passed', async () => {
|
|
188
194
|
const mockConfig = { apis: {} };
|
|
189
195
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
196
|
+
await (0, push_1.handlePush)({
|
|
197
|
+
argv: {
|
|
198
|
+
domain: 'test-domain',
|
|
199
|
+
'mount-path': 'test-mount-path',
|
|
200
|
+
organization: 'test-org',
|
|
201
|
+
project: 'test-project',
|
|
202
|
+
branch: 'test-branch',
|
|
203
|
+
author: 'TestAuthor <test-author@mail.com>',
|
|
204
|
+
message: 'Test message',
|
|
205
|
+
'default-branch': 'main',
|
|
206
|
+
files: [],
|
|
207
|
+
'max-execution-time': 10,
|
|
208
|
+
},
|
|
209
|
+
config: mockConfig,
|
|
210
|
+
version: 'cli-version',
|
|
211
|
+
});
|
|
202
212
|
expect(remotes.getDefaultBranch).not.toHaveBeenCalled();
|
|
203
213
|
expect(remotes.upsert).not.toHaveBeenCalled();
|
|
204
214
|
expect(remotes.push).not.toHaveBeenCalled();
|
|
205
|
-
})
|
|
206
|
-
it('should get organization from config if not passed', () =>
|
|
215
|
+
});
|
|
216
|
+
it('should get organization from config if not passed', async () => {
|
|
207
217
|
const mockConfig = { organization: 'test-org-from-config', apis: {} };
|
|
208
218
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
209
219
|
fsStatSyncSpy.mockReturnValueOnce({
|
|
@@ -214,22 +224,26 @@ describe('handlePush()', () => {
|
|
|
214
224
|
pathResolveSpy.mockImplementationOnce((p) => p);
|
|
215
225
|
pathRelativeSpy.mockImplementationOnce((_, p) => p);
|
|
216
226
|
pathDirnameSpy.mockImplementation((_) => '.');
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
227
|
+
await (0, push_1.handlePush)({
|
|
228
|
+
argv: {
|
|
229
|
+
domain: 'test-domain',
|
|
230
|
+
'mount-path': 'test-mount-path',
|
|
231
|
+
project: 'test-project',
|
|
232
|
+
branch: 'test-branch',
|
|
233
|
+
author: 'TestAuthor <test-author@mail.com>',
|
|
234
|
+
message: 'Test message',
|
|
235
|
+
files: ['test-file'],
|
|
236
|
+
'default-branch': 'main',
|
|
237
|
+
'max-execution-time': 10,
|
|
238
|
+
},
|
|
239
|
+
config: mockConfig,
|
|
240
|
+
version: 'cli-version',
|
|
241
|
+
});
|
|
228
242
|
expect(remotes.getDefaultBranch).toHaveBeenCalledWith('test-org-from-config', expect.anything());
|
|
229
243
|
expect(remotes.upsert).toHaveBeenCalledWith('test-org-from-config', expect.anything(), expect.anything());
|
|
230
244
|
expect(remotes.push).toHaveBeenCalledWith('test-org-from-config', expect.anything(), expect.anything(), expect.anything());
|
|
231
|
-
})
|
|
232
|
-
it('should get domain from env if not passed', () =>
|
|
245
|
+
});
|
|
246
|
+
it('should get domain from env if not passed', async () => {
|
|
233
247
|
const mockConfig = { organization: 'test-org-from-config', apis: {} };
|
|
234
248
|
process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
|
|
235
249
|
process.env.REDOCLY_DOMAIN = 'test-domain-from-env';
|
|
@@ -241,16 +255,20 @@ describe('handlePush()', () => {
|
|
|
241
255
|
pathResolveSpy.mockImplementationOnce((p) => p);
|
|
242
256
|
pathRelativeSpy.mockImplementationOnce((_, p) => p);
|
|
243
257
|
pathDirnameSpy.mockImplementation((_) => '.');
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
258
|
+
await (0, push_1.handlePush)({
|
|
259
|
+
argv: {
|
|
260
|
+
'mount-path': 'test-mount-path',
|
|
261
|
+
project: 'test-project',
|
|
262
|
+
branch: 'test-branch',
|
|
263
|
+
'default-branch': 'main',
|
|
264
|
+
author: 'TestAuthor <test-author@mail.com>',
|
|
265
|
+
message: 'Test message',
|
|
266
|
+
files: ['test-file'],
|
|
267
|
+
'max-execution-time': 10,
|
|
268
|
+
},
|
|
269
|
+
config: mockConfig,
|
|
270
|
+
version: 'cli-version',
|
|
271
|
+
});
|
|
254
272
|
expect(api_1.ReuniteApiClient).toBeCalledWith('test-domain-from-env', 'test-api-key');
|
|
255
|
-
})
|
|
273
|
+
});
|
|
256
274
|
});
|
|
@@ -1,43 +1,34 @@
|
|
|
1
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
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
const utils_1 = require("../utils");
|
|
13
4
|
jest.mock('@redocly/openapi-core', () => ({
|
|
14
5
|
pause: jest.requireActual('@redocly/openapi-core').pause,
|
|
15
6
|
}));
|
|
16
7
|
describe('retryUntilConditionMet()', () => {
|
|
17
|
-
it('should retry until condition meet and return result', () =>
|
|
8
|
+
it('should retry until condition meet and return result', async () => {
|
|
18
9
|
const operation = jest
|
|
19
10
|
.fn()
|
|
20
11
|
.mockResolvedValueOnce({ status: 'pending' })
|
|
21
12
|
.mockResolvedValueOnce({ status: 'pending' })
|
|
22
13
|
.mockResolvedValueOnce({ status: 'done' });
|
|
23
|
-
const data =
|
|
14
|
+
const data = await (0, utils_1.retryUntilConditionMet)({
|
|
24
15
|
operation,
|
|
25
|
-
condition: (result) =>
|
|
16
|
+
condition: (result) => result?.status === 'done',
|
|
26
17
|
retryIntervalMs: 100,
|
|
27
18
|
retryTimeoutMs: 1000,
|
|
28
19
|
});
|
|
29
20
|
expect(data).toEqual({ status: 'done' });
|
|
30
|
-
})
|
|
31
|
-
it('should throw error if condition not meet for desired timeout', () =>
|
|
21
|
+
});
|
|
22
|
+
it('should throw error if condition not meet for desired timeout', async () => {
|
|
32
23
|
const operation = jest.fn().mockResolvedValue({ status: 'pending' });
|
|
33
|
-
|
|
24
|
+
await expect((0, utils_1.retryUntilConditionMet)({
|
|
34
25
|
operation,
|
|
35
|
-
condition: (result) =>
|
|
26
|
+
condition: (result) => result?.status === 'done',
|
|
36
27
|
retryIntervalMs: 100,
|
|
37
28
|
retryTimeoutMs: 1000,
|
|
38
29
|
})).rejects.toThrow('Timeout exceeded');
|
|
39
|
-
})
|
|
40
|
-
it('should call "onConditionNotMet" and "onRetry" callbacks', () =>
|
|
30
|
+
});
|
|
31
|
+
it('should call "onConditionNotMet" and "onRetry" callbacks', async () => {
|
|
41
32
|
const operation = jest
|
|
42
33
|
.fn()
|
|
43
34
|
.mockResolvedValueOnce({ status: 'pending' })
|
|
@@ -45,9 +36,9 @@ describe('retryUntilConditionMet()', () => {
|
|
|
45
36
|
.mockResolvedValueOnce({ status: 'done' });
|
|
46
37
|
const onConditionNotMet = jest.fn();
|
|
47
38
|
const onRetry = jest.fn();
|
|
48
|
-
const data =
|
|
39
|
+
const data = await (0, utils_1.retryUntilConditionMet)({
|
|
49
40
|
operation,
|
|
50
|
-
condition: (result) =>
|
|
41
|
+
condition: (result) => result?.status === 'done',
|
|
51
42
|
retryIntervalMs: 100,
|
|
52
43
|
retryTimeoutMs: 1000,
|
|
53
44
|
onConditionNotMet,
|
|
@@ -56,5 +47,5 @@ describe('retryUntilConditionMet()', () => {
|
|
|
56
47
|
expect(data).toEqual({ status: 'done' });
|
|
57
48
|
expect(onConditionNotMet).toHaveBeenCalledTimes(2);
|
|
58
49
|
expect(onRetry).toHaveBeenCalledTimes(2);
|
|
59
|
-
})
|
|
50
|
+
});
|
|
60
51
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { OutputFormat } from '@redocly/openapi-core';
|
|
2
|
+
import type { CommandArgs } from '../../wrapper';
|
|
2
3
|
import type { DeploymentStatusResponse, PushResponse } from '../api/types';
|
|
3
4
|
export type PushStatusOptions = {
|
|
4
5
|
organization: string;
|
|
@@ -19,4 +20,4 @@ export interface PushStatusSummary {
|
|
|
19
20
|
production: DeploymentStatusResponse | null;
|
|
20
21
|
commit: PushResponse['commit'];
|
|
21
22
|
}
|
|
22
|
-
export declare function handlePushStatus(argv
|
|
23
|
+
export declare function handlePushStatus({ argv, config, }: CommandArgs<PushStatusOptions>): Promise<PushStatusSummary | undefined>;
|
|
@@ -1,15 +1,6 @@
|
|
|
1
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
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.handlePushStatus =
|
|
3
|
+
exports.handlePushStatus = handlePushStatus;
|
|
13
4
|
const colors = require("colorette");
|
|
14
5
|
const miscellaneous_1 = require("../../utils/miscellaneous");
|
|
15
6
|
const spinner_1 = require("../../utils/spinner");
|
|
@@ -18,29 +9,72 @@ const api_1 = require("../api");
|
|
|
18
9
|
const js_utils_1 = require("../../utils/js-utils");
|
|
19
10
|
const utils_2 = require("./utils");
|
|
20
11
|
const RETRY_INTERVAL_MS = 5000; // 5 sec
|
|
21
|
-
function handlePushStatus(argv, config) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
12
|
+
async function handlePushStatus({ argv, config, }) {
|
|
13
|
+
const startedAt = performance.now();
|
|
14
|
+
const spinner = new spinner_1.Spinner();
|
|
15
|
+
const { organization, project: projectId, pushId, wait } = argv;
|
|
16
|
+
const orgId = organization || config.organization;
|
|
17
|
+
if (!orgId) {
|
|
18
|
+
(0, miscellaneous_1.exitWithError)(`No organization provided, please use --organization option or specify the 'organization' field in the config file.`);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const domain = argv.domain || (0, api_1.getDomain)();
|
|
22
|
+
const maxExecutionTime = argv['max-execution-time'] || 1200; // 20 min
|
|
23
|
+
const retryIntervalMs = argv['retry-interval']
|
|
24
|
+
? argv['retry-interval'] * 1000
|
|
25
|
+
: RETRY_INTERVAL_MS;
|
|
26
|
+
const startTime = argv['start-time'] || Date.now();
|
|
27
|
+
const retryTimeoutMs = maxExecutionTime * 1000;
|
|
28
|
+
const continueOnDeployFailures = argv['continue-on-deploy-failures'] || false;
|
|
29
|
+
try {
|
|
30
|
+
const apiKey = (0, api_1.getApiKeys)(domain);
|
|
31
|
+
const client = new api_1.ReuniteApiClient(domain, apiKey);
|
|
32
|
+
let pushResponse;
|
|
33
|
+
pushResponse = await (0, utils_2.retryUntilConditionMet)({
|
|
34
|
+
operation: () => client.remotes.getPush({
|
|
35
|
+
organizationId: orgId,
|
|
36
|
+
projectId,
|
|
37
|
+
pushId,
|
|
38
|
+
}),
|
|
39
|
+
condition: wait
|
|
40
|
+
? // Keep retrying if status is "pending" or "running" (returning false, so the operation will be retried)
|
|
41
|
+
(result) => !['pending', 'running'].includes(result.status['preview'].deploy.status)
|
|
42
|
+
: null,
|
|
43
|
+
onConditionNotMet: (lastResult) => {
|
|
44
|
+
displayDeploymentAndBuildStatus({
|
|
45
|
+
status: lastResult.status['preview'].deploy.status,
|
|
46
|
+
url: lastResult.status['preview'].deploy.url,
|
|
47
|
+
spinner,
|
|
48
|
+
buildType: 'preview',
|
|
49
|
+
continueOnDeployFailures,
|
|
50
|
+
wait,
|
|
51
|
+
});
|
|
52
|
+
},
|
|
53
|
+
onRetry: (lastResult) => {
|
|
54
|
+
if (argv.onRetry) {
|
|
55
|
+
argv.onRetry({
|
|
56
|
+
preview: lastResult.status.preview,
|
|
57
|
+
production: lastResult.isMainBranch ? lastResult.status.production : null,
|
|
58
|
+
commit: lastResult.commit,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
startTime,
|
|
63
|
+
retryTimeoutMs,
|
|
64
|
+
retryIntervalMs,
|
|
65
|
+
});
|
|
66
|
+
printPushStatus({
|
|
67
|
+
buildType: 'preview',
|
|
68
|
+
spinner,
|
|
69
|
+
wait,
|
|
70
|
+
push: pushResponse,
|
|
71
|
+
continueOnDeployFailures,
|
|
72
|
+
});
|
|
73
|
+
printScorecard(pushResponse.status.preview.scorecard);
|
|
74
|
+
const shouldWaitForProdDeployment = pushResponse.isMainBranch &&
|
|
75
|
+
(wait ? pushResponse.status.preview.deploy.status === 'success' : true);
|
|
76
|
+
if (shouldWaitForProdDeployment) {
|
|
77
|
+
pushResponse = await (0, utils_2.retryUntilConditionMet)({
|
|
44
78
|
operation: () => client.remotes.getPush({
|
|
45
79
|
organizationId: orgId,
|
|
46
80
|
projectId,
|
|
@@ -48,14 +82,14 @@ function handlePushStatus(argv, config) {
|
|
|
48
82
|
}),
|
|
49
83
|
condition: wait
|
|
50
84
|
? // Keep retrying if status is "pending" or "running" (returning false, so the operation will be retried)
|
|
51
|
-
(result) => !['pending', 'running'].includes(result.status['
|
|
85
|
+
(result) => !['pending', 'running'].includes(result.status['production'].deploy.status)
|
|
52
86
|
: null,
|
|
53
87
|
onConditionNotMet: (lastResult) => {
|
|
54
88
|
displayDeploymentAndBuildStatus({
|
|
55
|
-
status: lastResult.status['
|
|
56
|
-
url: lastResult.status['
|
|
89
|
+
status: lastResult.status['production'].deploy.status,
|
|
90
|
+
url: lastResult.status['production'].deploy.url,
|
|
57
91
|
spinner,
|
|
58
|
-
buildType: '
|
|
92
|
+
buildType: 'production',
|
|
59
93
|
continueOnDeployFailures,
|
|
60
94
|
wait,
|
|
61
95
|
});
|
|
@@ -73,83 +107,37 @@ function handlePushStatus(argv, config) {
|
|
|
73
107
|
retryTimeoutMs,
|
|
74
108
|
retryIntervalMs,
|
|
75
109
|
});
|
|
110
|
+
}
|
|
111
|
+
if (pushResponse.isMainBranch) {
|
|
76
112
|
printPushStatus({
|
|
77
|
-
buildType: '
|
|
113
|
+
buildType: 'production',
|
|
78
114
|
spinner,
|
|
79
115
|
wait,
|
|
80
116
|
push: pushResponse,
|
|
81
117
|
continueOnDeployFailures,
|
|
82
118
|
});
|
|
83
|
-
printScorecard(pushResponse.status.
|
|
84
|
-
const shouldWaitForProdDeployment = pushResponse.isMainBranch &&
|
|
85
|
-
(wait ? pushResponse.status.preview.deploy.status === 'success' : true);
|
|
86
|
-
if (shouldWaitForProdDeployment) {
|
|
87
|
-
pushResponse = yield (0, utils_2.retryUntilConditionMet)({
|
|
88
|
-
operation: () => client.remotes.getPush({
|
|
89
|
-
organizationId: orgId,
|
|
90
|
-
projectId,
|
|
91
|
-
pushId,
|
|
92
|
-
}),
|
|
93
|
-
condition: wait
|
|
94
|
-
? // Keep retrying if status is "pending" or "running" (returning false, so the operation will be retried)
|
|
95
|
-
(result) => !['pending', 'running'].includes(result.status['production'].deploy.status)
|
|
96
|
-
: null,
|
|
97
|
-
onConditionNotMet: (lastResult) => {
|
|
98
|
-
displayDeploymentAndBuildStatus({
|
|
99
|
-
status: lastResult.status['production'].deploy.status,
|
|
100
|
-
url: lastResult.status['production'].deploy.url,
|
|
101
|
-
spinner,
|
|
102
|
-
buildType: 'production',
|
|
103
|
-
continueOnDeployFailures,
|
|
104
|
-
wait,
|
|
105
|
-
});
|
|
106
|
-
},
|
|
107
|
-
onRetry: (lastResult) => {
|
|
108
|
-
if (argv.onRetry) {
|
|
109
|
-
argv.onRetry({
|
|
110
|
-
preview: lastResult.status.preview,
|
|
111
|
-
production: lastResult.isMainBranch ? lastResult.status.production : null,
|
|
112
|
-
commit: lastResult.commit,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
startTime,
|
|
117
|
-
retryTimeoutMs,
|
|
118
|
-
retryIntervalMs,
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
if (pushResponse.isMainBranch) {
|
|
122
|
-
printPushStatus({
|
|
123
|
-
buildType: 'production',
|
|
124
|
-
spinner,
|
|
125
|
-
wait,
|
|
126
|
-
push: pushResponse,
|
|
127
|
-
continueOnDeployFailures,
|
|
128
|
-
});
|
|
129
|
-
printScorecard(pushResponse.status.production.scorecard);
|
|
130
|
-
}
|
|
131
|
-
printPushStatusInfo({ orgId, projectId, pushId, startedAt });
|
|
132
|
-
const summary = {
|
|
133
|
-
preview: pushResponse.status.preview,
|
|
134
|
-
production: pushResponse.isMainBranch ? pushResponse.status.production : null,
|
|
135
|
-
commit: pushResponse.commit,
|
|
136
|
-
};
|
|
137
|
-
return summary;
|
|
138
|
-
}
|
|
139
|
-
catch (err) {
|
|
140
|
-
spinner.stop(); // Spinner can block process exit, so we need to stop it explicitly.
|
|
141
|
-
const message = err instanceof utils_1.DeploymentError
|
|
142
|
-
? err.message
|
|
143
|
-
: `✗ Failed to get push status. Reason: ${err.message}\n`;
|
|
144
|
-
(0, miscellaneous_1.exitWithError)(message);
|
|
145
|
-
return;
|
|
119
|
+
printScorecard(pushResponse.status.production.scorecard);
|
|
146
120
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
121
|
+
printPushStatusInfo({ orgId, projectId, pushId, startedAt });
|
|
122
|
+
const summary = {
|
|
123
|
+
preview: pushResponse.status.preview,
|
|
124
|
+
production: pushResponse.isMainBranch ? pushResponse.status.production : null,
|
|
125
|
+
commit: pushResponse.commit,
|
|
126
|
+
};
|
|
127
|
+
return summary;
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
spinner.stop(); // Spinner can block process exit, so we need to stop it explicitly.
|
|
131
|
+
const message = err instanceof utils_1.DeploymentError
|
|
132
|
+
? err.message
|
|
133
|
+
: `✗ Failed to get push status. Reason: ${err.message}\n`;
|
|
134
|
+
(0, miscellaneous_1.exitWithError)(message);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
finally {
|
|
138
|
+
spinner.stop(); // Spinner can block process exit, so we need to stop it explicitly.
|
|
139
|
+
}
|
|
151
140
|
}
|
|
152
|
-
exports.handlePushStatus = handlePushStatus;
|
|
153
141
|
function printPushStatusInfo({ orgId, projectId, pushId, startedAt, }) {
|
|
154
142
|
process.stderr.write(`\nProcessed push-status for ${colors.yellow(orgId)}, ${colors.yellow(projectId)} and pushID ${colors.yellow(pushId)}.\n`);
|
|
155
143
|
(0, miscellaneous_1.printExecutionTime)('push-status', startedAt, 'Finished');
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { OutputFormat
|
|
1
|
+
import type { OutputFormat } from '@redocly/openapi-core';
|
|
2
|
+
import type { CommandArgs } from '../../wrapper';
|
|
2
3
|
export type PushOptions = {
|
|
3
4
|
apis?: string[];
|
|
4
5
|
organization?: string;
|
|
@@ -22,6 +23,6 @@ export type PushOptions = {
|
|
|
22
23
|
verbose?: boolean;
|
|
23
24
|
format?: Extract<OutputFormat, 'stylish'>;
|
|
24
25
|
};
|
|
25
|
-
export declare function handlePush(argv
|
|
26
|
+
export declare function handlePush({ argv, config, version, }: CommandArgs<PushOptions>): Promise<{
|
|
26
27
|
pushId: string;
|
|
27
28
|
} | void>;
|