@secustor/backstage-plugin-renovate-backend 0.12.0 → 0.13.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 +18 -0
- package/dist/config/index.cjs.js +43 -0
- package/dist/config/index.cjs.js.map +1 -0
- package/dist/index.cjs.js +4 -1408
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/plugin.cjs.js +68 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/queue/factory.cjs.js +15 -0
- package/dist/queue/factory.cjs.js.map +1 -0
- package/dist/schema/openapi.generated.cjs.js +636 -0
- package/dist/schema/openapi.generated.cjs.js.map +1 -0
- package/dist/service/cleanupTask.cjs.js +39 -0
- package/dist/service/cleanupTask.cjs.js.map +1 -0
- package/dist/service/databaseHandler.cjs.js +255 -0
- package/dist/service/databaseHandler.cjs.js.map +1 -0
- package/dist/service/jobSync.cjs.js +45 -0
- package/dist/service/jobSync.cjs.js.map +1 -0
- package/dist/service/router.cjs.js +127 -0
- package/dist/service/router.cjs.js.map +1 -0
- package/dist/service/schema.cjs.js +13 -0
- package/dist/service/schema.cjs.js.map +1 -0
- package/dist/service/types.cjs.js +14 -0
- package/dist/service/types.cjs.js.map +1 -0
- package/dist/wrapper/platforms/github.cjs.js +13 -0
- package/dist/wrapper/platforms/github.cjs.js.map +1 -0
- package/dist/wrapper/platforms/index.cjs.js +80 -0
- package/dist/wrapper/platforms/index.cjs.js.map +1 -0
- package/dist/wrapper/renovateRunner.cjs.js +119 -0
- package/dist/wrapper/renovateRunner.cjs.js.map +1 -0
- package/dist/wrapper/utils.cjs.js +62 -0
- package/dist/wrapper/utils.cjs.js.map +1 -0
- package/package.json +12 -12
package/dist/index.cjs.js
CHANGED
|
@@ -2,1415 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var backendOpenapiUtils = require('@backstage/backend-openapi-utils');
|
|
8
|
-
var zod = require('zod');
|
|
9
|
-
var backstagePluginRenovateCommon = require('@secustor/backstage-plugin-renovate-common');
|
|
10
|
-
var catalogClient = require('@backstage/catalog-client');
|
|
11
|
-
var is = require('@sindresorhus/is');
|
|
12
|
-
var integration = require('@backstage/integration');
|
|
13
|
-
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
14
|
-
var errors = require('@backstage/errors');
|
|
15
|
-
var nanoid = require('nanoid');
|
|
16
|
-
var backstagePluginRenovateNode = require('@secustor/backstage-plugin-renovate-node');
|
|
17
|
-
var catalogModel = require('@backstage/catalog-model');
|
|
5
|
+
var router = require('./service/router.cjs.js');
|
|
6
|
+
var plugin = require('./plugin.cjs.js');
|
|
18
7
|
|
|
19
|
-
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
20
8
|
|
|
21
|
-
var express__default = /*#__PURE__*/_interopDefaultCompat(express);
|
|
22
|
-
var is__default = /*#__PURE__*/_interopDefaultCompat(is);
|
|
23
9
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
info: {
|
|
27
|
-
title: "renovate",
|
|
28
|
-
description: "Backstage Renovate API",
|
|
29
|
-
version: "0.2.0"
|
|
30
|
-
},
|
|
31
|
-
servers: [
|
|
32
|
-
{
|
|
33
|
-
description: "local test setup",
|
|
34
|
-
url: "http://localhost:7007"
|
|
35
|
-
}
|
|
36
|
-
],
|
|
37
|
-
paths: {
|
|
38
|
-
"/health": {
|
|
39
|
-
get: {
|
|
40
|
-
summary: "Get health status of the plugin",
|
|
41
|
-
responses: {
|
|
42
|
-
"200": {
|
|
43
|
-
description: "health status is green",
|
|
44
|
-
content: {
|
|
45
|
-
"application/json": {
|
|
46
|
-
schema: {
|
|
47
|
-
type: "string",
|
|
48
|
-
example: "ok"
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
"/reports": {
|
|
57
|
-
get: {
|
|
58
|
-
summary: "Get all reports",
|
|
59
|
-
responses: {
|
|
60
|
-
"200": {
|
|
61
|
-
$ref: "#/components/responses/reports"
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
delete: {
|
|
66
|
-
summary: "Delete reports based on parameters",
|
|
67
|
-
parameters: [
|
|
68
|
-
{
|
|
69
|
-
$ref: "#/components/parameters/keepLatest"
|
|
70
|
-
}
|
|
71
|
-
],
|
|
72
|
-
responses: {
|
|
73
|
-
"200": {
|
|
74
|
-
$ref: "#/components/responses/deleted-successful"
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
"/reports/{host}": {
|
|
80
|
-
get: {
|
|
81
|
-
summary: "Get reports for host",
|
|
82
|
-
parameters: [
|
|
83
|
-
{
|
|
84
|
-
name: "host",
|
|
85
|
-
in: "path",
|
|
86
|
-
required: true,
|
|
87
|
-
schema: {
|
|
88
|
-
type: "string",
|
|
89
|
-
example: "github.com"
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
],
|
|
93
|
-
responses: {
|
|
94
|
-
"200": {
|
|
95
|
-
$ref: "#/components/responses/reports"
|
|
96
|
-
},
|
|
97
|
-
"404": {
|
|
98
|
-
description: "unknown host"
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
delete: {
|
|
103
|
-
summary: "Delete reports based on parameters",
|
|
104
|
-
parameters: [
|
|
105
|
-
{
|
|
106
|
-
$ref: "#/components/parameters/keepLatest"
|
|
107
|
-
}
|
|
108
|
-
],
|
|
109
|
-
responses: {
|
|
110
|
-
"200": {
|
|
111
|
-
$ref: "#/components/responses/deleted-successful"
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
"/reports/{host}/{repository}": {
|
|
117
|
-
get: {
|
|
118
|
-
summary: "Get reports for repository",
|
|
119
|
-
parameters: [
|
|
120
|
-
{
|
|
121
|
-
name: "host",
|
|
122
|
-
in: "path",
|
|
123
|
-
required: true,
|
|
124
|
-
schema: {
|
|
125
|
-
type: "string",
|
|
126
|
-
example: "github.com"
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: "repository",
|
|
131
|
-
in: "path",
|
|
132
|
-
required: true,
|
|
133
|
-
schema: {
|
|
134
|
-
type: "string",
|
|
135
|
-
example: "myOrg/myRepository"
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
],
|
|
139
|
-
responses: {
|
|
140
|
-
"200": {
|
|
141
|
-
$ref: "#/components/responses/reports"
|
|
142
|
-
},
|
|
143
|
-
"404": {
|
|
144
|
-
description: "unknown repository"
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
},
|
|
148
|
-
delete: {
|
|
149
|
-
summary: "Delete reports based on parameters",
|
|
150
|
-
parameters: [
|
|
151
|
-
{
|
|
152
|
-
$ref: "#/components/parameters/keepLatest"
|
|
153
|
-
}
|
|
154
|
-
],
|
|
155
|
-
responses: {
|
|
156
|
-
"200": {
|
|
157
|
-
$ref: "#/components/responses/deleted-successful"
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
"/dependencies": {
|
|
163
|
-
get: {
|
|
164
|
-
summary: "Get dependencies for host",
|
|
165
|
-
parameters: [
|
|
166
|
-
{
|
|
167
|
-
name: "pageSize",
|
|
168
|
-
in: "query",
|
|
169
|
-
description: "size of the page",
|
|
170
|
-
schema: {
|
|
171
|
-
type: "number",
|
|
172
|
-
default: 100
|
|
173
|
-
}
|
|
174
|
-
},
|
|
175
|
-
{
|
|
176
|
-
name: "page",
|
|
177
|
-
in: "query",
|
|
178
|
-
description: "page number. starting with 0",
|
|
179
|
-
schema: {
|
|
180
|
-
type: "number"
|
|
181
|
-
}
|
|
182
|
-
},
|
|
183
|
-
{
|
|
184
|
-
name: "availableValues",
|
|
185
|
-
in: "query",
|
|
186
|
-
description: "if set to true, the response will include all available values for the filters",
|
|
187
|
-
schema: {
|
|
188
|
-
type: "boolean"
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
name: "datasource",
|
|
193
|
-
in: "query",
|
|
194
|
-
description: "filter by datasource",
|
|
195
|
-
schema: {
|
|
196
|
-
type: "array",
|
|
197
|
-
items: {
|
|
198
|
-
example: "npm,pypi",
|
|
199
|
-
type: "string"
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
name: "depName",
|
|
205
|
-
in: "query",
|
|
206
|
-
description: "filter by dependency name",
|
|
207
|
-
schema: {
|
|
208
|
-
type: "array",
|
|
209
|
-
items: {
|
|
210
|
-
example: "pdm,react",
|
|
211
|
-
type: "string"
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
name: "depType",
|
|
217
|
-
in: "query",
|
|
218
|
-
description: "filter by dependency type",
|
|
219
|
-
schema: {
|
|
220
|
-
type: "array",
|
|
221
|
-
items: {
|
|
222
|
-
example: "dev,prod",
|
|
223
|
-
type: "string"
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
},
|
|
227
|
-
{
|
|
228
|
-
name: "host",
|
|
229
|
-
in: "query",
|
|
230
|
-
schema: {
|
|
231
|
-
type: "array",
|
|
232
|
-
example: "github.com,gitlab.example.com",
|
|
233
|
-
items: {
|
|
234
|
-
type: "string"
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
name: "latestOnly",
|
|
240
|
-
in: "query",
|
|
241
|
-
description: "include only dependencies which have been found in the last extraction",
|
|
242
|
-
schema: {
|
|
243
|
-
type: "boolean"
|
|
244
|
-
}
|
|
245
|
-
},
|
|
246
|
-
{
|
|
247
|
-
name: "manager",
|
|
248
|
-
in: "query",
|
|
249
|
-
description: "filter by manager",
|
|
250
|
-
schema: {
|
|
251
|
-
type: "array",
|
|
252
|
-
items: {
|
|
253
|
-
example: "npm,composer",
|
|
254
|
-
type: "string"
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
},
|
|
258
|
-
{
|
|
259
|
-
name: "packageFile",
|
|
260
|
-
in: "query",
|
|
261
|
-
description: "filter by package file",
|
|
262
|
-
schema: {
|
|
263
|
-
type: "array",
|
|
264
|
-
items: {
|
|
265
|
-
example: "package.json,composer.json",
|
|
266
|
-
type: "string"
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
name: "repository",
|
|
272
|
-
in: "query",
|
|
273
|
-
schema: {
|
|
274
|
-
type: "array",
|
|
275
|
-
example: "myOrg/myRepository,myOrg/myOtherRepository",
|
|
276
|
-
items: {
|
|
277
|
-
type: "string"
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
],
|
|
282
|
-
responses: {
|
|
283
|
-
"200": {
|
|
284
|
-
$ref: "#/components/responses/dependencies"
|
|
285
|
-
},
|
|
286
|
-
"404": {
|
|
287
|
-
description: "unknown host"
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
},
|
|
292
|
-
"/runs": {
|
|
293
|
-
post: {
|
|
294
|
-
summary: "Start or get Renovate runs",
|
|
295
|
-
requestBody: {
|
|
296
|
-
content: {
|
|
297
|
-
"application/json": {
|
|
298
|
-
schema: {
|
|
299
|
-
type: "object",
|
|
300
|
-
required: ["target"],
|
|
301
|
-
properties: {
|
|
302
|
-
target: {
|
|
303
|
-
$ref: "#/components/schemas/target"
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
},
|
|
310
|
-
responses: {
|
|
311
|
-
"202": {
|
|
312
|
-
description: "Run has been scheduled",
|
|
313
|
-
content: {
|
|
314
|
-
"application/json": {
|
|
315
|
-
schema: {
|
|
316
|
-
type: "object",
|
|
317
|
-
properties: {
|
|
318
|
-
taskID: {
|
|
319
|
-
description: "id of the scheduler task",
|
|
320
|
-
type: "string",
|
|
321
|
-
example: "9-d_CO9JlaEmd-OM9QfkI"
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
},
|
|
328
|
-
"400": {
|
|
329
|
-
description: "Unexpected incoming data",
|
|
330
|
-
content: {
|
|
331
|
-
"application/json": {
|
|
332
|
-
schema: {
|
|
333
|
-
type: "object",
|
|
334
|
-
properties: {
|
|
335
|
-
error: {
|
|
336
|
-
$ref: "#/components/schemas/error"
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
},
|
|
347
|
-
components: {
|
|
348
|
-
parameters: {
|
|
349
|
-
keepLatest: {
|
|
350
|
-
name: "keepLatest",
|
|
351
|
-
description: "how many reports of all targets should be kept",
|
|
352
|
-
in: "query",
|
|
353
|
-
required: false,
|
|
354
|
-
example: 3,
|
|
355
|
-
schema: {
|
|
356
|
-
type: "number"
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
},
|
|
360
|
-
responses: {
|
|
361
|
-
dependencies: {
|
|
362
|
-
description: "Returns dependencies",
|
|
363
|
-
headers: {
|
|
364
|
-
"X-Total-Count": {
|
|
365
|
-
schema: {
|
|
366
|
-
type: "integer",
|
|
367
|
-
description: "Total number of entries"
|
|
368
|
-
}
|
|
369
|
-
},
|
|
370
|
-
"X-Page-Count": {
|
|
371
|
-
schema: {
|
|
372
|
-
type: "integer",
|
|
373
|
-
description: "Total number of pages"
|
|
374
|
-
}
|
|
375
|
-
},
|
|
376
|
-
"X-Page": {
|
|
377
|
-
schema: {
|
|
378
|
-
type: "integer",
|
|
379
|
-
description: "Current page"
|
|
380
|
-
}
|
|
381
|
-
},
|
|
382
|
-
"X-Page-Size": {
|
|
383
|
-
schema: {
|
|
384
|
-
type: "integer",
|
|
385
|
-
description: "Number of entries per page"
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
},
|
|
389
|
-
content: {
|
|
390
|
-
"application/json": {
|
|
391
|
-
schema: {
|
|
392
|
-
type: "object",
|
|
393
|
-
required: ["dependencies"],
|
|
394
|
-
properties: {
|
|
395
|
-
dependencies: {
|
|
396
|
-
type: "array",
|
|
397
|
-
items: {
|
|
398
|
-
$ref: "#/components/schemas/dependency"
|
|
399
|
-
}
|
|
400
|
-
},
|
|
401
|
-
availableValues: {
|
|
402
|
-
type: "object",
|
|
403
|
-
description: "Will only be part of the response if `availableValues` is true. Returns all available values for the applied filters\n",
|
|
404
|
-
properties: {
|
|
405
|
-
datasource: {
|
|
406
|
-
type: "array",
|
|
407
|
-
items: {
|
|
408
|
-
type: "string"
|
|
409
|
-
}
|
|
410
|
-
},
|
|
411
|
-
depName: {
|
|
412
|
-
type: "array",
|
|
413
|
-
items: {
|
|
414
|
-
type: "string"
|
|
415
|
-
}
|
|
416
|
-
},
|
|
417
|
-
depType: {
|
|
418
|
-
type: "array",
|
|
419
|
-
items: {
|
|
420
|
-
type: "string"
|
|
421
|
-
}
|
|
422
|
-
},
|
|
423
|
-
host: {
|
|
424
|
-
type: "array",
|
|
425
|
-
items: {
|
|
426
|
-
type: "string"
|
|
427
|
-
}
|
|
428
|
-
},
|
|
429
|
-
manager: {
|
|
430
|
-
type: "array",
|
|
431
|
-
items: {
|
|
432
|
-
type: "string"
|
|
433
|
-
}
|
|
434
|
-
},
|
|
435
|
-
packageFile: {
|
|
436
|
-
type: "array",
|
|
437
|
-
items: {
|
|
438
|
-
type: "string"
|
|
439
|
-
}
|
|
440
|
-
},
|
|
441
|
-
repository: {
|
|
442
|
-
type: "array",
|
|
443
|
-
items: {
|
|
444
|
-
type: "string"
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
},
|
|
454
|
-
"deleted-successful": {
|
|
455
|
-
description: "Successful deleted",
|
|
456
|
-
content: {
|
|
457
|
-
"application/json": {
|
|
458
|
-
schema: {
|
|
459
|
-
type: "object",
|
|
460
|
-
properties: {
|
|
461
|
-
deleted: {
|
|
462
|
-
type: "number",
|
|
463
|
-
example: 15,
|
|
464
|
-
description: "Numbers of reports deleted"
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
},
|
|
471
|
-
reports: {
|
|
472
|
-
description: "Returns reports",
|
|
473
|
-
content: {
|
|
474
|
-
"application/json": {
|
|
475
|
-
schema: {
|
|
476
|
-
type: "array",
|
|
477
|
-
items: {
|
|
478
|
-
type: "object",
|
|
479
|
-
additionalProperties: false,
|
|
480
|
-
required: [
|
|
481
|
-
"taskID",
|
|
482
|
-
"repository",
|
|
483
|
-
"host",
|
|
484
|
-
"timestamp",
|
|
485
|
-
"report"
|
|
486
|
-
],
|
|
487
|
-
properties: {
|
|
488
|
-
taskID: {
|
|
489
|
-
type: "string"
|
|
490
|
-
},
|
|
491
|
-
timestamp: {
|
|
492
|
-
type: "string",
|
|
493
|
-
format: "date-time"
|
|
494
|
-
},
|
|
495
|
-
host: {
|
|
496
|
-
type: "string"
|
|
497
|
-
},
|
|
498
|
-
repository: {
|
|
499
|
-
type: "string"
|
|
500
|
-
},
|
|
501
|
-
report: {
|
|
502
|
-
$ref: "#/components/schemas/repositoryReport"
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
},
|
|
511
|
-
schemas: {
|
|
512
|
-
error: {
|
|
513
|
-
anyOf: [
|
|
514
|
-
{
|
|
515
|
-
type: "object",
|
|
516
|
-
example: {
|
|
517
|
-
message: "I'm an error",
|
|
518
|
-
code: 1111
|
|
519
|
-
}
|
|
520
|
-
},
|
|
521
|
-
{
|
|
522
|
-
type: "string",
|
|
523
|
-
example: "I'm an error"
|
|
524
|
-
}
|
|
525
|
-
]
|
|
526
|
-
},
|
|
527
|
-
target: {
|
|
528
|
-
anyOf: [
|
|
529
|
-
{
|
|
530
|
-
type: "string",
|
|
531
|
-
description: "URL to an repository",
|
|
532
|
-
example: "https://github.com/secustor/renovate-test"
|
|
533
|
-
},
|
|
534
|
-
{
|
|
535
|
-
type: "string",
|
|
536
|
-
description: "stringified Entity with SourceLocation URL annotation",
|
|
537
|
-
example: "component:default/backstage-plugins-example"
|
|
538
|
-
},
|
|
539
|
-
{
|
|
540
|
-
type: "string",
|
|
541
|
-
description: "host and path",
|
|
542
|
-
example: "secustor/backstage-plugins"
|
|
543
|
-
}
|
|
544
|
-
]
|
|
545
|
-
},
|
|
546
|
-
repositoryReportList: {
|
|
547
|
-
type: "array",
|
|
548
|
-
items: {
|
|
549
|
-
$ref: "#/components/schemas/repositoryReport"
|
|
550
|
-
}
|
|
551
|
-
},
|
|
552
|
-
repositoryReport: {
|
|
553
|
-
description: "report for a specific repository",
|
|
554
|
-
type: "object",
|
|
555
|
-
additionalProperties: false,
|
|
556
|
-
required: ["branches", "packageFiles", "problems"],
|
|
557
|
-
properties: {
|
|
558
|
-
branches: {
|
|
559
|
-
type: "array",
|
|
560
|
-
items: {
|
|
561
|
-
type: "object"
|
|
562
|
-
}
|
|
563
|
-
},
|
|
564
|
-
packageFiles: {
|
|
565
|
-
type: "object"
|
|
566
|
-
},
|
|
567
|
-
problems: {
|
|
568
|
-
type: "array",
|
|
569
|
-
items: {
|
|
570
|
-
type: "object"
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
},
|
|
575
|
-
dependency: {
|
|
576
|
-
type: "object",
|
|
577
|
-
additionalProperties: false,
|
|
578
|
-
required: [
|
|
579
|
-
"id",
|
|
580
|
-
"runID",
|
|
581
|
-
"host",
|
|
582
|
-
"repository",
|
|
583
|
-
"extractionTimestamp",
|
|
584
|
-
"manager",
|
|
585
|
-
"datasource",
|
|
586
|
-
"packageFile",
|
|
587
|
-
"depName"
|
|
588
|
-
],
|
|
589
|
-
properties: {
|
|
590
|
-
id: {
|
|
591
|
-
type: "string"
|
|
592
|
-
},
|
|
593
|
-
runID: {
|
|
594
|
-
type: "string"
|
|
595
|
-
},
|
|
596
|
-
host: {
|
|
597
|
-
type: "string"
|
|
598
|
-
},
|
|
599
|
-
repository: {
|
|
600
|
-
type: "string"
|
|
601
|
-
},
|
|
602
|
-
extractionTimestamp: {
|
|
603
|
-
type: "string",
|
|
604
|
-
format: "date-time"
|
|
605
|
-
},
|
|
606
|
-
manager: {
|
|
607
|
-
type: "string"
|
|
608
|
-
},
|
|
609
|
-
datasource: {
|
|
610
|
-
type: "string"
|
|
611
|
-
},
|
|
612
|
-
packageFile: {
|
|
613
|
-
type: "string"
|
|
614
|
-
},
|
|
615
|
-
packageFileUrl: {
|
|
616
|
-
type: "string"
|
|
617
|
-
},
|
|
618
|
-
depName: {
|
|
619
|
-
type: "string"
|
|
620
|
-
},
|
|
621
|
-
packageName: {
|
|
622
|
-
type: "string"
|
|
623
|
-
},
|
|
624
|
-
depType: {
|
|
625
|
-
type: "string"
|
|
626
|
-
},
|
|
627
|
-
currentValue: {
|
|
628
|
-
type: "string"
|
|
629
|
-
},
|
|
630
|
-
currentVersion: {
|
|
631
|
-
type: "string"
|
|
632
|
-
},
|
|
633
|
-
currentVersionTimestamp: {
|
|
634
|
-
type: "string",
|
|
635
|
-
format: "date-time"
|
|
636
|
-
},
|
|
637
|
-
skipReason: {
|
|
638
|
-
type: "string"
|
|
639
|
-
},
|
|
640
|
-
registryUrl: {
|
|
641
|
-
type: "string"
|
|
642
|
-
},
|
|
643
|
-
sourceUrl: {
|
|
644
|
-
type: "string"
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
};
|
|
651
|
-
const createOpenApiRouter = async (options) => backendOpenapiUtils.createValidatedOpenApiRouter(spec, options);
|
|
652
|
-
|
|
653
|
-
const target = zod.z.string().or(backstagePluginRenovateCommon.targetRepo);
|
|
654
|
-
const runRequestBody = zod.z.object({
|
|
655
|
-
target
|
|
656
|
-
});
|
|
657
|
-
|
|
658
|
-
async function getGithubToken(integrations, url) {
|
|
659
|
-
const cred = await integration.DefaultGithubCredentialsProvider.fromIntegrations(
|
|
660
|
-
integrations
|
|
661
|
-
).getCredentials({ url });
|
|
662
|
-
return cred.token;
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
async function getPlatformEnvs(target, context) {
|
|
666
|
-
const { rootConfig, logger } = context;
|
|
667
|
-
const env = {};
|
|
668
|
-
const integrations = integration.ScmIntegrations.fromConfig(rootConfig);
|
|
669
|
-
const integration$1 = integrations.byHost(target.host);
|
|
670
|
-
if (is__default.default.nullOrUndefined(integration$1)) {
|
|
671
|
-
throw new Error(
|
|
672
|
-
`Could not identify platform for target ${target.host}/${target.repository}`
|
|
673
|
-
);
|
|
674
|
-
}
|
|
675
|
-
const errMsg = `No credentials could be found for url and '${integration$1.type}' type for host ${target.host}`;
|
|
676
|
-
const url = `https://${target.host}/${target.repository}`;
|
|
677
|
-
switch (integration$1.type) {
|
|
678
|
-
case "github": {
|
|
679
|
-
env.RENOVATE_PLATFORM = integration$1.type;
|
|
680
|
-
const token = await getGithubToken(integrations, url);
|
|
681
|
-
env.RENOVATE_TOKEN = requireConfigVariable(token, errMsg);
|
|
682
|
-
env.RENOVATE_REPOSITORIES = target.repository;
|
|
683
|
-
break;
|
|
684
|
-
}
|
|
685
|
-
case "gitlab":
|
|
686
|
-
{
|
|
687
|
-
const cred = await integration.DefaultGitlabCredentialsProvider.fromIntegrations(
|
|
688
|
-
integrations
|
|
689
|
-
).getCredentials({ url });
|
|
690
|
-
const gitLabIntegrationConfig = requireConfigVariable(
|
|
691
|
-
integrations.gitlab.byHost(target.host)?.config,
|
|
692
|
-
errMsg
|
|
693
|
-
);
|
|
694
|
-
env.RENOVATE_PLATFORM = integration$1.type;
|
|
695
|
-
env.RENOVATE_ENDPOINT = gitLabIntegrationConfig.apiBaseUrl ?? `https://${target.host}/api/v4`;
|
|
696
|
-
env.RENOVATE_TOKEN = requireConfigVariable(cred.token, errMsg);
|
|
697
|
-
env.RENOVATE_REPOSITORIES = target.repository;
|
|
698
|
-
}
|
|
699
|
-
break;
|
|
700
|
-
default:
|
|
701
|
-
throw new Error(`Unsupported platform type ${integration$1.type}`);
|
|
702
|
-
}
|
|
703
|
-
const githubComURL = "https://github.com";
|
|
704
|
-
const githubComIntegration = integrations.github.byUrl(githubComURL);
|
|
705
|
-
if (is__default.default.nullOrUndefined(githubComIntegration)) {
|
|
706
|
-
logger.warn(`No Github.com integration has been found`);
|
|
707
|
-
} else {
|
|
708
|
-
const githubComToken = await getGithubToken(integrations, githubComURL);
|
|
709
|
-
if (githubComToken) {
|
|
710
|
-
env.RENOVATE_GITHUB_COM = githubComToken;
|
|
711
|
-
} else {
|
|
712
|
-
logger.warn(
|
|
713
|
-
`Could not get token for Github.com token in the defined integrations`
|
|
714
|
-
);
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
return env;
|
|
718
|
-
}
|
|
719
|
-
function requireConfigVariable(input, errMessage) {
|
|
720
|
-
if (is__default.default.nullOrUndefined(input)) {
|
|
721
|
-
throw new Error(errMessage);
|
|
722
|
-
}
|
|
723
|
-
return input;
|
|
724
|
-
}
|
|
725
|
-
function getFileUrl(options) {
|
|
726
|
-
if (options.host.includes("github")) {
|
|
727
|
-
return `https://${options.host}/${options.repository}/blob/HEAD/${options.packageFile}`;
|
|
728
|
-
}
|
|
729
|
-
return null;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
async function createRouter(runner, options) {
|
|
733
|
-
const {
|
|
734
|
-
auth,
|
|
735
|
-
rootConfig: config,
|
|
736
|
-
logger,
|
|
737
|
-
databaseHandler,
|
|
738
|
-
discovery
|
|
739
|
-
} = options;
|
|
740
|
-
const middlewareFactory = rootHttpRouter.MiddlewareFactory.create({ logger, config });
|
|
741
|
-
const client = new catalogClient.CatalogClient({ discoveryApi: discovery });
|
|
742
|
-
const router = await createOpenApiRouter();
|
|
743
|
-
router.use(express__default.default.json());
|
|
744
|
-
router.get("/health", (_, response) => {
|
|
745
|
-
logger.debug("healthcheck request");
|
|
746
|
-
response.json("ok");
|
|
747
|
-
});
|
|
748
|
-
router.get("/reports", async (_request, response) => {
|
|
749
|
-
const reports = await databaseHandler.getReports();
|
|
750
|
-
response.status(200).json(reports);
|
|
751
|
-
});
|
|
752
|
-
router.delete("/reports", async (request, response) => {
|
|
753
|
-
const modified = await databaseHandler.deleteReports({
|
|
754
|
-
keepLatest: request.query.keepLatest
|
|
755
|
-
});
|
|
756
|
-
response.status(200).json({ modified });
|
|
757
|
-
});
|
|
758
|
-
router.get("/reports/:host", async (request, response) => {
|
|
759
|
-
const reports = await databaseHandler.getReports({
|
|
760
|
-
...request.params
|
|
761
|
-
});
|
|
762
|
-
response.status(200).json(reports);
|
|
763
|
-
});
|
|
764
|
-
router.delete("/reports/:host", async (request, response) => {
|
|
765
|
-
const modified = await databaseHandler.deleteReportsByTarget(
|
|
766
|
-
request.params,
|
|
767
|
-
{ keepLatest: request.query.keepLatest }
|
|
768
|
-
);
|
|
769
|
-
response.status(200).json({ modified });
|
|
770
|
-
});
|
|
771
|
-
router.get("/reports/:host/:repository", async (request, response) => {
|
|
772
|
-
const reports = await databaseHandler.getReports({
|
|
773
|
-
...request.params
|
|
774
|
-
});
|
|
775
|
-
response.status(200).json(reports);
|
|
776
|
-
});
|
|
777
|
-
router.delete("/reports/:host/:repository", async (request, response) => {
|
|
778
|
-
const modified = await databaseHandler.deleteReportsByTarget(
|
|
779
|
-
request.params,
|
|
780
|
-
{ keepLatest: request.query.keepLatest }
|
|
781
|
-
);
|
|
782
|
-
response.status(200).json({ modified });
|
|
783
|
-
});
|
|
784
|
-
router.get("/dependencies", async (request, response) => {
|
|
785
|
-
const filter = request.query;
|
|
786
|
-
const { result, total, pageCount, page, pageSize } = await databaseHandler.getDependencies(filter, filter);
|
|
787
|
-
const massaged = result.map((dep) => {
|
|
788
|
-
return {
|
|
789
|
-
...dep,
|
|
790
|
-
id: dep.id,
|
|
791
|
-
runID: dep.run_id,
|
|
792
|
-
extractionTimestamp: dep.extractionTimestamp?.toISOString(),
|
|
793
|
-
currentVersionTimestamp: dep.currentVersionTimestamp?.toISOString(),
|
|
794
|
-
packageFileUrl: getFileUrl(dep) ?? void 0
|
|
795
|
-
};
|
|
796
|
-
});
|
|
797
|
-
let availableValues;
|
|
798
|
-
if (request.query.availableValues) {
|
|
799
|
-
availableValues = await databaseHandler.getDependenciesValues(filter);
|
|
800
|
-
}
|
|
801
|
-
response.setHeader("X-Total-Count", total);
|
|
802
|
-
response.setHeader("X-Page-Count", pageCount);
|
|
803
|
-
response.setHeader("X-Page", page);
|
|
804
|
-
response.setHeader("X-Page-Size", pageSize);
|
|
805
|
-
response.json({
|
|
806
|
-
dependencies: massaged,
|
|
807
|
-
availableValues
|
|
808
|
-
});
|
|
809
|
-
});
|
|
810
|
-
router.post("/runs", async (request, response) => {
|
|
811
|
-
const body = runRequestBody.safeParse(request.body);
|
|
812
|
-
if (!body.success) {
|
|
813
|
-
response.status(400).json({ error: body.error.toString() });
|
|
814
|
-
return;
|
|
815
|
-
}
|
|
816
|
-
let target = body.data.target;
|
|
817
|
-
if (is__default.default.string(target) && backstagePluginRenovateCommon.isEntityRef(target)) {
|
|
818
|
-
const { token } = await auth.getPluginRequestToken({
|
|
819
|
-
onBehalfOf: await auth.getOwnServiceCredentials(),
|
|
820
|
-
targetPluginId: "catalog"
|
|
821
|
-
});
|
|
822
|
-
const result2 = await client.getEntityByRef(target, { token });
|
|
823
|
-
if (result2) {
|
|
824
|
-
target = result2;
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
const targetRepo = backstagePluginRenovateCommon.getTargetRepo(target);
|
|
828
|
-
const id = backstagePluginRenovateCommon.getTaskID(targetRepo);
|
|
829
|
-
const result = await runner.runNext(targetRepo);
|
|
830
|
-
if (result.status === "already-running") {
|
|
831
|
-
logger.debug("Task already running", { taskID: id });
|
|
832
|
-
response.status(423).json({ error: "Task is already running" });
|
|
833
|
-
return;
|
|
834
|
-
}
|
|
835
|
-
response.status(202).json({ taskID: id });
|
|
836
|
-
});
|
|
837
|
-
router.use(middlewareFactory.error());
|
|
838
|
-
return router;
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
const RENOVATE_ANNOTATION_KEEP_UPDATED = "renovate.secustor.dev/keep-updated";
|
|
842
|
-
function getPluginConfig(rootConfig) {
|
|
843
|
-
return rootConfig.getConfig("renovate");
|
|
844
|
-
}
|
|
845
|
-
function getRenovateConfig(rootConfig) {
|
|
846
|
-
const value = getPluginConfig(rootConfig).getOptional("config");
|
|
847
|
-
return value ?? null;
|
|
848
|
-
}
|
|
849
|
-
function getRuntimeConfigs(rootConfig) {
|
|
850
|
-
const runtimeConfig = getPluginConfig(rootConfig).getConfig("runtime");
|
|
851
|
-
const runtime = runtimeConfig.getString("type");
|
|
852
|
-
return {
|
|
853
|
-
runtime,
|
|
854
|
-
config: runtimeConfig.getConfig(runtime)
|
|
855
|
-
};
|
|
856
|
-
}
|
|
857
|
-
function getScheduleDefinition(pluginConfig, variant) {
|
|
858
|
-
try {
|
|
859
|
-
const scheduleConfig = pluginConfig.getConfig(`schedules.${variant}`);
|
|
860
|
-
return {
|
|
861
|
-
enabled: scheduleConfig.getOptionalBoolean("enabled") ?? true,
|
|
862
|
-
...backendPluginApi.readSchedulerServiceTaskScheduleDefinitionFromConfig(scheduleConfig)
|
|
863
|
-
};
|
|
864
|
-
} catch (e) {
|
|
865
|
-
return {
|
|
866
|
-
enabled: true,
|
|
867
|
-
scope: "global",
|
|
868
|
-
timeout: { minutes: 60 },
|
|
869
|
-
frequency: { minutes: 60 }
|
|
870
|
-
};
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
async function extractReport(opts) {
|
|
875
|
-
const { logStream, logger } = opts;
|
|
876
|
-
return new Promise((resolve) => {
|
|
877
|
-
let uncompletedText = "";
|
|
878
|
-
logStream.on("data", (chunk) => {
|
|
879
|
-
const text = uncompletedText.concat(chunk.toString());
|
|
880
|
-
const logLines = text.split("\n");
|
|
881
|
-
uncompletedText = logLines.pop() ?? "";
|
|
882
|
-
for (const logLine of logLines) {
|
|
883
|
-
const log = JSON.parse(logLine);
|
|
884
|
-
if (log.report) {
|
|
885
|
-
const report = log.report;
|
|
886
|
-
resolve(report);
|
|
887
|
-
}
|
|
888
|
-
const msg = log.msg;
|
|
889
|
-
delete log.msg;
|
|
890
|
-
delete log.logContext;
|
|
891
|
-
logger.debug(msg, log);
|
|
892
|
-
}
|
|
893
|
-
});
|
|
894
|
-
});
|
|
895
|
-
}
|
|
896
|
-
function getCacheEnvs(config, logger) {
|
|
897
|
-
const cacheEnabled = getPluginConfig(config).getOptionalBoolean("cache.enabled") ?? true;
|
|
898
|
-
if (!cacheEnabled) {
|
|
899
|
-
logger.debug("Cache has been disabled in plugin configuration");
|
|
900
|
-
return {};
|
|
901
|
-
}
|
|
902
|
-
const cacheConfig = config.getOptionalConfig("backend.cache");
|
|
903
|
-
if (is__default.default.nullOrUndefined(cacheConfig)) {
|
|
904
|
-
logger.debug("No cache configured");
|
|
905
|
-
return {};
|
|
906
|
-
}
|
|
907
|
-
const store = cacheConfig.getString("store");
|
|
908
|
-
if (store !== "redis") {
|
|
909
|
-
logger.debug(`Unsupported cache store '${store}' detected`);
|
|
910
|
-
return {};
|
|
911
|
-
}
|
|
912
|
-
const connection = cacheConfig.getOptionalString("connection");
|
|
913
|
-
if (is__default.default.nullOrUndefined(connection)) {
|
|
914
|
-
logger.debug("No connection string for redis cache configured in backend");
|
|
915
|
-
return {};
|
|
916
|
-
}
|
|
917
|
-
logger.debug("Injecting Redis cache into Renovate");
|
|
918
|
-
return {
|
|
919
|
-
RENOVATE_REDIS_PREFIX: "renovate_",
|
|
920
|
-
RENOVATE_REDIS_URL: connection
|
|
921
|
-
};
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
function createQueue(queues, rootConfig, runnable) {
|
|
925
|
-
const type = getPluginConfig(rootConfig).getString("queue.type");
|
|
926
|
-
const factory = queues.get(type);
|
|
927
|
-
if (!factory) {
|
|
928
|
-
throw new Error(`Could not find Queue implementation ${type}`);
|
|
929
|
-
}
|
|
930
|
-
return factory(runnable);
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
class RenovateRunner {
|
|
934
|
-
constructor(queueFactories, databaseHandler, rootConfig, logger, runtimes) {
|
|
935
|
-
this.databaseHandler = databaseHandler;
|
|
936
|
-
this.rootConfig = rootConfig;
|
|
937
|
-
this.logger = logger;
|
|
938
|
-
this.runtimes = runtimes;
|
|
939
|
-
this.queue = createQueue(queueFactories, rootConfig, this);
|
|
940
|
-
}
|
|
941
|
-
queue;
|
|
942
|
-
static async from(options) {
|
|
943
|
-
const { databaseHandler, rootConfig, runtimes, logger, queueFactories } = options;
|
|
944
|
-
return new RenovateRunner(
|
|
945
|
-
queueFactories,
|
|
946
|
-
databaseHandler,
|
|
947
|
-
rootConfig,
|
|
948
|
-
logger,
|
|
949
|
-
runtimes
|
|
950
|
-
);
|
|
951
|
-
}
|
|
952
|
-
async addToQueue(...targets) {
|
|
953
|
-
const props = targets.map((target) => {
|
|
954
|
-
const jobId = backstagePluginRenovateCommon.getTaskID(target);
|
|
955
|
-
const targetRepo = backstagePluginRenovateCommon.getTargetRepo(target);
|
|
956
|
-
return {
|
|
957
|
-
jobId,
|
|
958
|
-
data: {
|
|
959
|
-
id: jobId,
|
|
960
|
-
target: targetRepo
|
|
961
|
-
}
|
|
962
|
-
};
|
|
963
|
-
});
|
|
964
|
-
return await this.queue.addBulk(props);
|
|
965
|
-
}
|
|
966
|
-
async runNext(target) {
|
|
967
|
-
const jobId = backstagePluginRenovateCommon.getTaskID(target);
|
|
968
|
-
const targetRepo = backstagePluginRenovateCommon.getTargetRepo(target);
|
|
969
|
-
return await this.queue.add(
|
|
970
|
-
jobId,
|
|
971
|
-
{ id: jobId, target: targetRepo },
|
|
972
|
-
{
|
|
973
|
-
force: true,
|
|
974
|
-
insertInFront: true
|
|
975
|
-
}
|
|
976
|
-
);
|
|
977
|
-
}
|
|
978
|
-
async run(props) {
|
|
979
|
-
const { id, target } = props;
|
|
980
|
-
const runID = nanoid.nanoid();
|
|
981
|
-
const logger = this.logger.child({ runID, jobID: id, ...target });
|
|
982
|
-
try {
|
|
983
|
-
logger.info("Renovate run starting");
|
|
984
|
-
const report = await this.renovate(props, logger);
|
|
985
|
-
await this.databaseHandler.addReport({
|
|
986
|
-
runID,
|
|
987
|
-
taskID: id,
|
|
988
|
-
report,
|
|
989
|
-
target,
|
|
990
|
-
logger
|
|
991
|
-
});
|
|
992
|
-
logger.info("Renovate run successfully finished");
|
|
993
|
-
} catch (e) {
|
|
994
|
-
logger.error("Renovate failed", errors.isError(e) ? e : {});
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
async renovate({ id, target }, logger) {
|
|
998
|
-
const { runtime, config: runtimeConfig } = getRuntimeConfigs(
|
|
999
|
-
this.rootConfig
|
|
1000
|
-
);
|
|
1001
|
-
const wrapperRuntime = this.runtimes.get(runtime);
|
|
1002
|
-
if (is__default.default.nullOrUndefined(wrapperRuntime)) {
|
|
1003
|
-
throw new Error(`Unknown runtime type '${runtime}'`);
|
|
1004
|
-
}
|
|
1005
|
-
const env = {
|
|
1006
|
-
// setup logging
|
|
1007
|
-
LOG_FORMAT: "json",
|
|
1008
|
-
LOG_LEVEL: "debug",
|
|
1009
|
-
LOG_CONTEXT: id,
|
|
1010
|
-
RENOVATE_REPORT_TYPE: "logging",
|
|
1011
|
-
// setup platform specifics
|
|
1012
|
-
...await getPlatformEnvs(target, {
|
|
1013
|
-
logger,
|
|
1014
|
-
rootConfig: this.rootConfig
|
|
1015
|
-
}),
|
|
1016
|
-
...getCacheEnvs(this.rootConfig, logger)
|
|
1017
|
-
};
|
|
1018
|
-
const renovateConfig = getRenovateConfig(this.rootConfig);
|
|
1019
|
-
const promise = wrapperRuntime.run({
|
|
1020
|
-
runID: id,
|
|
1021
|
-
env,
|
|
1022
|
-
renovateConfig,
|
|
1023
|
-
runtimeConfig,
|
|
1024
|
-
logger
|
|
1025
|
-
});
|
|
1026
|
-
return promise.then((result) => {
|
|
1027
|
-
return extractReport({
|
|
1028
|
-
logger,
|
|
1029
|
-
logStream: result.stdout
|
|
1030
|
-
});
|
|
1031
|
-
});
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
const DependencyValueFiltersKeys = [
|
|
1036
|
-
"datasource",
|
|
1037
|
-
"depName",
|
|
1038
|
-
"depType",
|
|
1039
|
-
"host",
|
|
1040
|
-
"manager",
|
|
1041
|
-
"packageFile",
|
|
1042
|
-
"repository"
|
|
1043
|
-
];
|
|
1044
|
-
|
|
1045
|
-
const migrationsDir = backendPluginApi.resolvePackagePath(
|
|
1046
|
-
"@secustor/backstage-plugin-renovate-backend",
|
|
1047
|
-
"migrations"
|
|
1048
|
-
);
|
|
1049
|
-
class DatabaseHandler {
|
|
1050
|
-
constructor(client, logger) {
|
|
1051
|
-
this.client = client;
|
|
1052
|
-
this.logger = logger;
|
|
1053
|
-
}
|
|
1054
|
-
static async create(options) {
|
|
1055
|
-
const { database, logger } = options;
|
|
1056
|
-
const client = await database.getClient();
|
|
1057
|
-
if (!database.migrations?.skip) {
|
|
1058
|
-
await client.migrate.latest({
|
|
1059
|
-
directory: migrationsDir
|
|
1060
|
-
});
|
|
1061
|
-
}
|
|
1062
|
-
return new DatabaseHandler(client, logger);
|
|
1063
|
-
}
|
|
1064
|
-
async addReport(options) {
|
|
1065
|
-
const { runID, taskID, report, target } = options;
|
|
1066
|
-
const logger = options.logger ?? this.logger;
|
|
1067
|
-
const timestamp = /* @__PURE__ */ new Date();
|
|
1068
|
-
const inserts = [];
|
|
1069
|
-
for (const [repository, value] of Object.entries(report.repositories)) {
|
|
1070
|
-
inserts.push({
|
|
1071
|
-
run_id: runID,
|
|
1072
|
-
task_id: taskID,
|
|
1073
|
-
timestamp,
|
|
1074
|
-
host: target.host,
|
|
1075
|
-
repository,
|
|
1076
|
-
report: value
|
|
1077
|
-
});
|
|
1078
|
-
}
|
|
1079
|
-
await this.client("reports").insert(inserts).catch((reason) => logger.error("Failed insert data", reason));
|
|
1080
|
-
await this.updateDependencies(timestamp, options);
|
|
1081
|
-
}
|
|
1082
|
-
async getReports(query) {
|
|
1083
|
-
const builder = this.client.select();
|
|
1084
|
-
if (query) {
|
|
1085
|
-
builder.where(query);
|
|
1086
|
-
}
|
|
1087
|
-
const rows = await builder.from("reports");
|
|
1088
|
-
return rows.map((row) => {
|
|
1089
|
-
return {
|
|
1090
|
-
runID: row.run_id,
|
|
1091
|
-
taskID: row.task_id,
|
|
1092
|
-
timestamp: row.timestamp.toISOString(),
|
|
1093
|
-
host: row.host,
|
|
1094
|
-
repository: row.repository,
|
|
1095
|
-
// if the JSON field has not been auto-parsed do it manually
|
|
1096
|
-
report: is__default.default.string(row.report) ? JSON.parse(row.report) : row.report
|
|
1097
|
-
};
|
|
1098
|
-
});
|
|
1099
|
-
}
|
|
1100
|
-
async getTargets() {
|
|
1101
|
-
return this.client.select().distinct("host", "repository").from("reports");
|
|
1102
|
-
}
|
|
1103
|
-
async deleteReportsByTarget({ host, repository }, options) {
|
|
1104
|
-
const offset = getOffset(options);
|
|
1105
|
-
const toBeDeletedIDs = this.client("reports").select("run_id").where("host", host).andWhere("repository", repository).orderBy("timestamp", "DESC").offset(offset);
|
|
1106
|
-
return this.client("reports").delete().whereIn("run_id", [toBeDeletedIDs]);
|
|
1107
|
-
}
|
|
1108
|
-
async deleteReports(options) {
|
|
1109
|
-
const targets = await this.getTargets();
|
|
1110
|
-
const modified = await Promise.all(
|
|
1111
|
-
targets.map((target) => this.deleteReportsByTarget(target, options))
|
|
1112
|
-
);
|
|
1113
|
-
return modified.reduce((a, b) => a + b, 0);
|
|
1114
|
-
}
|
|
1115
|
-
async updateDependencies(timestamp, options) {
|
|
1116
|
-
const { runID, report, target } = options;
|
|
1117
|
-
const dependencies = [];
|
|
1118
|
-
for (const [repository, repositoryContent] of Object.entries(
|
|
1119
|
-
report.repositories
|
|
1120
|
-
)) {
|
|
1121
|
-
for (const [manager, packageFiles] of Object.entries(
|
|
1122
|
-
repositoryContent.packageFiles
|
|
1123
|
-
)) {
|
|
1124
|
-
for (const packageFile of packageFiles) {
|
|
1125
|
-
const packageFilePath = packageFile.packageFile;
|
|
1126
|
-
for (const dependency of packageFile.deps) {
|
|
1127
|
-
const {
|
|
1128
|
-
packageName,
|
|
1129
|
-
depName,
|
|
1130
|
-
depType,
|
|
1131
|
-
datasource,
|
|
1132
|
-
currentValue,
|
|
1133
|
-
currentVersion,
|
|
1134
|
-
skipReason,
|
|
1135
|
-
registryUrl,
|
|
1136
|
-
sourceUrl,
|
|
1137
|
-
currentVersionTimestamp
|
|
1138
|
-
} = dependency;
|
|
1139
|
-
const massagedDepName = depName ?? packageName;
|
|
1140
|
-
if (!massagedDepName) {
|
|
1141
|
-
continue;
|
|
1142
|
-
}
|
|
1143
|
-
dependencies.push({
|
|
1144
|
-
run_id: runID,
|
|
1145
|
-
host: target.host,
|
|
1146
|
-
extractionTimestamp: timestamp,
|
|
1147
|
-
repository,
|
|
1148
|
-
manager,
|
|
1149
|
-
datasource: datasource ?? packageFile.datasource ?? "no-datasource",
|
|
1150
|
-
depName: massagedDepName,
|
|
1151
|
-
packageName,
|
|
1152
|
-
packageFile: packageFilePath,
|
|
1153
|
-
depType,
|
|
1154
|
-
currentValue,
|
|
1155
|
-
currentVersion,
|
|
1156
|
-
currentVersionTimestamp,
|
|
1157
|
-
skipReason,
|
|
1158
|
-
registryUrl,
|
|
1159
|
-
sourceUrl
|
|
1160
|
-
});
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
await this.client("dependencies").insert(dependencies);
|
|
1166
|
-
}
|
|
1167
|
-
async getDependencies(filters, pagination) {
|
|
1168
|
-
const page = pagination?.page ?? 0;
|
|
1169
|
-
const pageSize = pagination?.pageSize ?? 500;
|
|
1170
|
-
const builder = this.client("dependencies").select();
|
|
1171
|
-
this.applyDependencyFilters(builder, filters);
|
|
1172
|
-
const total = await this.getDependenciesCount(filters);
|
|
1173
|
-
const offset = page * pageSize;
|
|
1174
|
-
return {
|
|
1175
|
-
result: await builder.offset(offset).limit(pageSize),
|
|
1176
|
-
total,
|
|
1177
|
-
page,
|
|
1178
|
-
pageSize,
|
|
1179
|
-
pageCount: Math.ceil(total / pageSize)
|
|
1180
|
-
};
|
|
1181
|
-
}
|
|
1182
|
-
async getDependenciesCount(filters) {
|
|
1183
|
-
const builder = this.client("dependencies").count({ count: "*" });
|
|
1184
|
-
this.applyDependencyFilters(builder, filters);
|
|
1185
|
-
const count = await builder.first().then((result) => result?.count);
|
|
1186
|
-
if (is__default.default.string(count)) {
|
|
1187
|
-
return Number.parseInt(count, 10);
|
|
1188
|
-
}
|
|
1189
|
-
return count ?? 0;
|
|
1190
|
-
}
|
|
1191
|
-
applyDependencyFilters(builder, filters) {
|
|
1192
|
-
if (filters.host) {
|
|
1193
|
-
builder.whereIn("host", filters.host);
|
|
1194
|
-
}
|
|
1195
|
-
if (filters.repository) {
|
|
1196
|
-
builder.whereIn("repository", filters.repository);
|
|
1197
|
-
}
|
|
1198
|
-
if (filters.manager) {
|
|
1199
|
-
builder.whereIn("manager", filters.manager);
|
|
1200
|
-
}
|
|
1201
|
-
if (filters.datasource) {
|
|
1202
|
-
builder.whereIn("datasource", filters.datasource);
|
|
1203
|
-
}
|
|
1204
|
-
if (filters.depName) {
|
|
1205
|
-
builder.whereIn("depName", filters.depName);
|
|
1206
|
-
}
|
|
1207
|
-
if (filters.depType) {
|
|
1208
|
-
builder.whereIn("depType", filters.depType);
|
|
1209
|
-
}
|
|
1210
|
-
if (filters.latestOnly) {
|
|
1211
|
-
const runIDs = this.client("dependencies").select("d.run_id").from("dependencies as d").join(
|
|
1212
|
-
this.client("dependencies").select("host", "repository").max("extractionTimestamp as max_timestamp").groupBy("host", "repository").as("max_d"),
|
|
1213
|
-
// eslint-disable-next-line func-names
|
|
1214
|
-
function() {
|
|
1215
|
-
this.on("d.host", "=", "max_d.host").andOn("d.repository", "=", "max_d.repository").andOn("d.extractionTimestamp", "=", "max_d.max_timestamp");
|
|
1216
|
-
}
|
|
1217
|
-
).distinct();
|
|
1218
|
-
builder.whereIn("run_id", runIDs);
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
/**
|
|
1222
|
-
* Gets the available values for the dependencies stored in the database.
|
|
1223
|
-
* If filters are supplied, OTHER values are filtered accordingly, if a filter is supplied, all values are returned
|
|
1224
|
-
* @param filters
|
|
1225
|
-
*/
|
|
1226
|
-
async getDependenciesValues(filters) {
|
|
1227
|
-
const baseBuilder = this.client(
|
|
1228
|
-
"dependencies"
|
|
1229
|
-
);
|
|
1230
|
-
const limitedValuesBuilder = baseBuilder.clone();
|
|
1231
|
-
const allValuesKeys = [];
|
|
1232
|
-
const limitedValuesKeys = [];
|
|
1233
|
-
for (const filterKey of DependencyValueFiltersKeys) {
|
|
1234
|
-
const suppliedFilter = filters?.[filterKey];
|
|
1235
|
-
if (suppliedFilter) {
|
|
1236
|
-
limitedValuesBuilder.whereIn(filterKey, suppliedFilter);
|
|
1237
|
-
limitedValuesKeys.push(filterKey);
|
|
1238
|
-
continue;
|
|
1239
|
-
}
|
|
1240
|
-
allValuesKeys.push(filterKey);
|
|
1241
|
-
}
|
|
1242
|
-
const result = {
|
|
1243
|
-
datasource: [],
|
|
1244
|
-
manager: [],
|
|
1245
|
-
depType: [],
|
|
1246
|
-
depName: [],
|
|
1247
|
-
host: [],
|
|
1248
|
-
packageFile: [],
|
|
1249
|
-
repository: []
|
|
1250
|
-
};
|
|
1251
|
-
const allValues = allValuesKeys.map(
|
|
1252
|
-
async (filterKey) => {
|
|
1253
|
-
const values = await limitedValuesBuilder.clone().select(filterKey).distinct().pluck(filterKey);
|
|
1254
|
-
result[filterKey] = values.filter(is__default.default.string);
|
|
1255
|
-
}
|
|
1256
|
-
);
|
|
1257
|
-
const limitedValues = limitedValuesKeys.map(async (filterKey) => {
|
|
1258
|
-
const values = await baseBuilder.clone().select(filterKey).distinct().pluck(filterKey);
|
|
1259
|
-
result[filterKey] = values.filter(is__default.default.string);
|
|
1260
|
-
});
|
|
1261
|
-
await Promise.all([...allValues, ...limitedValues]);
|
|
1262
|
-
return result;
|
|
1263
|
-
}
|
|
1264
|
-
async deleteDependencies(options) {
|
|
1265
|
-
const targets = await this.getTargets();
|
|
1266
|
-
const modified = await Promise.all(
|
|
1267
|
-
targets.map((target) => this.deleteDependenciesByTarget(target, options))
|
|
1268
|
-
);
|
|
1269
|
-
return modified.reduce((a, b) => a + b, 0);
|
|
1270
|
-
}
|
|
1271
|
-
async deleteDependenciesByTarget({ host, repository }, options) {
|
|
1272
|
-
const offset = getOffset(options);
|
|
1273
|
-
const dependencies = this.client("dependencies").select("run_id", "extractionTimestamp").distinct("host", "repository").where("host", host).andWhere("repository", repository);
|
|
1274
|
-
const toBeDeletedIDs = this.client(dependencies).select("run_id").orderBy("extractionTimestamp", "DESC").offset(offset);
|
|
1275
|
-
return this.client("dependencies").delete().whereIn("run_id", [toBeDeletedIDs]);
|
|
1276
|
-
}
|
|
1277
|
-
}
|
|
1278
|
-
function getOffset(options) {
|
|
1279
|
-
let offset = 0;
|
|
1280
|
-
if (is__default.default.nullOrUndefined(options?.keepLatest) || is__default.default.boolean(options?.keepLatest)) {
|
|
1281
|
-
offset = options?.keepLatest ? 1 : 0;
|
|
1282
|
-
} else {
|
|
1283
|
-
offset = options.keepLatest;
|
|
1284
|
-
}
|
|
1285
|
-
return offset;
|
|
1286
|
-
}
|
|
1287
|
-
|
|
1288
|
-
async function scheduleJobSync(renovateRunner, routerOptions) {
|
|
1289
|
-
const { scheduler, auth, rootConfig, discovery } = routerOptions;
|
|
1290
|
-
const client = new catalogClient.CatalogClient({ discoveryApi: discovery });
|
|
1291
|
-
const pluginConfig = getPluginConfig(rootConfig);
|
|
1292
|
-
const schedule = getScheduleDefinition(pluginConfig, "renovation");
|
|
1293
|
-
if (!schedule.enabled) {
|
|
1294
|
-
return Promise.resolve();
|
|
1295
|
-
}
|
|
1296
|
-
return scheduler.scheduleTask({
|
|
1297
|
-
id: `renovate_scheduled_runs`,
|
|
1298
|
-
...schedule,
|
|
1299
|
-
fn: async () => {
|
|
1300
|
-
const { token } = await auth.getPluginRequestToken({
|
|
1301
|
-
onBehalfOf: await auth.getOwnServiceCredentials(),
|
|
1302
|
-
targetPluginId: "catalog"
|
|
1303
|
-
});
|
|
1304
|
-
const { items: entities } = await client.getEntities(
|
|
1305
|
-
{
|
|
1306
|
-
filter: {
|
|
1307
|
-
[`metadata.annotations.${RENOVATE_ANNOTATION_KEEP_UPDATED}`]: catalogClient.CATALOG_FILTER_EXISTS,
|
|
1308
|
-
[`metadata.annotations.${catalogModel.ANNOTATION_SOURCE_LOCATION}`]: catalogClient.CATALOG_FILTER_EXISTS
|
|
1309
|
-
},
|
|
1310
|
-
fields: [
|
|
1311
|
-
"kind",
|
|
1312
|
-
"metadata.annotations",
|
|
1313
|
-
"metadata.name",
|
|
1314
|
-
"metadata.namespace",
|
|
1315
|
-
"metadata.title"
|
|
1316
|
-
]
|
|
1317
|
-
},
|
|
1318
|
-
{ token }
|
|
1319
|
-
);
|
|
1320
|
-
await renovateRunner.addToQueue(...entities);
|
|
1321
|
-
}
|
|
1322
|
-
});
|
|
1323
|
-
}
|
|
1324
|
-
|
|
1325
|
-
async function scheduleCleanupTask(routerOptions) {
|
|
1326
|
-
const { scheduler, rootConfig, databaseHandler, logger } = routerOptions;
|
|
1327
|
-
const pluginConfig = getPluginConfig(rootConfig);
|
|
1328
|
-
const schedule = getScheduleDefinition(pluginConfig, "cleanup");
|
|
1329
|
-
if (!schedule.enabled) {
|
|
1330
|
-
return Promise.resolve();
|
|
1331
|
-
}
|
|
1332
|
-
const reportsToKeep = pluginConfig.getOptionalNumber("cleanup.minimumReports") ?? -1;
|
|
1333
|
-
const dependencyHistoryKeep = pluginConfig.getOptionalNumber("cleanup.dependencyHistory") ?? -1;
|
|
1334
|
-
return scheduler.scheduleTask({
|
|
1335
|
-
id: `renovate_report_cleanup`,
|
|
1336
|
-
...schedule,
|
|
1337
|
-
fn: async () => {
|
|
1338
|
-
if (reportsToKeep >= 0) {
|
|
1339
|
-
logger.debug("Running report cleanup");
|
|
1340
|
-
const modified = await databaseHandler.deleteReports({
|
|
1341
|
-
keepLatest: reportsToKeep
|
|
1342
|
-
});
|
|
1343
|
-
logger.debug(`Report cleanup completed. ${modified} reports deleted`);
|
|
1344
|
-
}
|
|
1345
|
-
if (dependencyHistoryKeep >= 0) {
|
|
1346
|
-
logger.debug("Running dependency history cleanup");
|
|
1347
|
-
const modified = await databaseHandler.deleteDependencies({
|
|
1348
|
-
keepLatest: dependencyHistoryKeep
|
|
1349
|
-
});
|
|
1350
|
-
logger.debug(
|
|
1351
|
-
`Dependency history cleanup completed. ${modified} dependencies deleted`
|
|
1352
|
-
);
|
|
1353
|
-
}
|
|
1354
|
-
}
|
|
1355
|
-
});
|
|
1356
|
-
}
|
|
1357
|
-
|
|
1358
|
-
const renovatePlugin = backendPluginApi.createBackendPlugin({
|
|
1359
|
-
pluginId: "renovate",
|
|
1360
|
-
register(env) {
|
|
1361
|
-
const runtimes = /* @__PURE__ */ new Map();
|
|
1362
|
-
env.registerExtensionPoint(backstagePluginRenovateNode.renovateRuntimeExtensionPoint, {
|
|
1363
|
-
addRuntime(id, runtime) {
|
|
1364
|
-
if (runtimes.has(id)) {
|
|
1365
|
-
throw new Error(
|
|
1366
|
-
` ${id} has been already registered. Only one wrapper with the same ID is allowed to be registered`
|
|
1367
|
-
);
|
|
1368
|
-
}
|
|
1369
|
-
runtimes.set(id, runtime);
|
|
1370
|
-
}
|
|
1371
|
-
});
|
|
1372
|
-
const queueFactories = /* @__PURE__ */ new Map();
|
|
1373
|
-
env.registerExtensionPoint(backstagePluginRenovateNode.renovateQueueExtensionPoint, {
|
|
1374
|
-
addQueueFactory(id, factory) {
|
|
1375
|
-
if (queueFactories.has(id)) {
|
|
1376
|
-
throw new Error(
|
|
1377
|
-
` ${id} has been already registered. Only one queue with the same ID is allowed to be registered`
|
|
1378
|
-
);
|
|
1379
|
-
}
|
|
1380
|
-
queueFactories.set(id, factory);
|
|
1381
|
-
}
|
|
1382
|
-
});
|
|
1383
|
-
env.registerInit({
|
|
1384
|
-
deps: {
|
|
1385
|
-
rootConfig: backendPluginApi.coreServices.rootConfig,
|
|
1386
|
-
logger: backendPluginApi.coreServices.logger,
|
|
1387
|
-
httpRouter: backendPluginApi.coreServices.httpRouter,
|
|
1388
|
-
database: backendPluginApi.coreServices.database,
|
|
1389
|
-
scheduler: backendPluginApi.coreServices.scheduler,
|
|
1390
|
-
discovery: backendPluginApi.coreServices.discovery,
|
|
1391
|
-
auth: backendPluginApi.coreServices.auth
|
|
1392
|
-
},
|
|
1393
|
-
async init(options) {
|
|
1394
|
-
const { database, httpRouter, logger } = options;
|
|
1395
|
-
const routerOptions = {
|
|
1396
|
-
...options,
|
|
1397
|
-
databaseHandler: await DatabaseHandler.create({ database, logger }),
|
|
1398
|
-
runtimes,
|
|
1399
|
-
queueFactories
|
|
1400
|
-
};
|
|
1401
|
-
const renovateRunner = await RenovateRunner.from(routerOptions);
|
|
1402
|
-
await scheduleJobSync(renovateRunner, routerOptions);
|
|
1403
|
-
await scheduleCleanupTask(routerOptions);
|
|
1404
|
-
httpRouter.use(await createRouter(renovateRunner, routerOptions));
|
|
1405
|
-
httpRouter.addAuthPolicy({
|
|
1406
|
-
path: "/health",
|
|
1407
|
-
allow: "unauthenticated"
|
|
1408
|
-
});
|
|
1409
|
-
}
|
|
1410
|
-
});
|
|
1411
|
-
}
|
|
1412
|
-
});
|
|
1413
|
-
|
|
1414
|
-
exports.createRouter = createRouter;
|
|
1415
|
-
exports.default = renovatePlugin;
|
|
10
|
+
exports.createRouter = router.createRouter;
|
|
11
|
+
exports.default = plugin.renovatePlugin;
|
|
1416
12
|
//# sourceMappingURL=index.cjs.js.map
|