@backstage/plugin-scaffolder-backend 0.15.24 → 0.16.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 +34 -0
- package/config.d.ts +0 -25
- package/dist/index.cjs.js +50 -44
- package/dist/index.cjs.js.map +1 -1
- package/package.json +25 -23
- package/dist/index.d.ts +0 -508
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder-backend
|
|
2
2
|
|
|
3
|
+
## 0.16.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 661594bf43: **BREAKING**: Updated `TemplateAction` and related types to have its type parameter extend `JsonObject` instead of `InputBase`. The `createTemplateAction` has also been updated to pass through the `TInput` type parameter to the return type, meaning the `TemplateAction` retains its type. This can lead to breakages during type checking especially within tests.
|
|
8
|
+
- 8db2b671c6: **BREAKING**: `ctx.token` is now `ctx.secrets.backstageToken` in Actions. Please update any of your Actions that might call out to Backstage API's with this token.
|
|
9
|
+
- 5a1594330e: **BREAKING** - Removed the `CatalogEntityClient` export. This is no longer provider by this package,
|
|
10
|
+
but you can implement one pretty simply yourself using the `CatalogApi` and applying filters to fetch templates.
|
|
11
|
+
- 7d3471db94: Remove the previously deprecated `scaffolder.provider` config for all providers.
|
|
12
|
+
This config is no longer used anywhere, and adopters should use [`integrations` config](https://backstage.io/docs/integrations) instead.
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5
|
|
17
|
+
- 3e59f90b51: Fix error handling of the `runCommand` helper to return `Error`
|
|
18
|
+
instance.
|
|
19
|
+
- c77c5c7eb6: Added `backstage.role` to `package.json`
|
|
20
|
+
- 216725b434: Updated to use new names for `parseLocationRef` and `stringifyLocationRef`
|
|
21
|
+
- e72d371296: Use `TemplateEntityV1beta2` from `@backstage/plugin-scaffolder-common` instead
|
|
22
|
+
of `@backstage/catalog-model`.
|
|
23
|
+
- 1433045c08: Removed unused `helmet` dependency.
|
|
24
|
+
- 27eccab216: Replaces use of deprecated catalog-model constants.
|
|
25
|
+
- Updated dependencies
|
|
26
|
+
- @backstage/plugin-scaffolder-common@0.2.0
|
|
27
|
+
- @backstage/plugin-catalog-backend@0.21.4
|
|
28
|
+
- @backstage/backend-common@0.10.8
|
|
29
|
+
- @backstage/catalog-client@0.7.0
|
|
30
|
+
- @backstage/errors@0.2.1
|
|
31
|
+
- @backstage/integration@0.7.3
|
|
32
|
+
- @backstage/catalog-model@0.10.0
|
|
33
|
+
- @backstage/config@0.1.14
|
|
34
|
+
- @backstage/types@0.1.2
|
|
35
|
+
- @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.0
|
|
36
|
+
|
|
3
37
|
## 0.15.24
|
|
4
38
|
|
|
5
39
|
### Patch Changes
|
package/config.d.ts
CHANGED
|
@@ -28,30 +28,5 @@ export interface Config {
|
|
|
28
28
|
* The commit message used when new components are created.
|
|
29
29
|
*/
|
|
30
30
|
defaultCommitMessage?: string;
|
|
31
|
-
/**
|
|
32
|
-
* @deprecated Replaced by parameters for the publish:github action
|
|
33
|
-
*/
|
|
34
|
-
github?: {
|
|
35
|
-
[key: string]: string;
|
|
36
|
-
};
|
|
37
|
-
/**
|
|
38
|
-
* @deprecated Use the Gitlab integration instead
|
|
39
|
-
*/
|
|
40
|
-
gitlab?: {
|
|
41
|
-
api: { [key: string]: string };
|
|
42
|
-
};
|
|
43
|
-
/**
|
|
44
|
-
* @deprecated Use the Azure integration instead
|
|
45
|
-
*/
|
|
46
|
-
azure?: {
|
|
47
|
-
baseUrl: string;
|
|
48
|
-
api: { [key: string]: string };
|
|
49
|
-
};
|
|
50
|
-
/**
|
|
51
|
-
* @deprecated Use the Bitbucket integration instead
|
|
52
|
-
*/
|
|
53
|
-
bitbucket?: {
|
|
54
|
-
api: { [key: string]: string };
|
|
55
|
-
};
|
|
56
31
|
};
|
|
57
32
|
}
|
package/dist/index.cjs.js
CHANGED
|
@@ -685,7 +685,7 @@ const runCommand = async ({
|
|
|
685
685
|
});
|
|
686
686
|
process.on("close", (code) => {
|
|
687
687
|
if (code !== 0) {
|
|
688
|
-
return reject(`Command ${command} failed, exit code: ${code}`);
|
|
688
|
+
return reject(new Error(`Command ${command} failed, exit code: ${code}`));
|
|
689
689
|
}
|
|
690
690
|
return resolve();
|
|
691
691
|
});
|
|
@@ -2414,7 +2414,7 @@ class HandlebarsWorkflowRunner {
|
|
|
2414
2414
|
this.handlebars.registerHelper("eq", (a, b) => a === b);
|
|
2415
2415
|
}
|
|
2416
2416
|
async execute(task) {
|
|
2417
|
-
var _a, _b
|
|
2417
|
+
var _a, _b;
|
|
2418
2418
|
if (!isValidTaskSpec$1(task.spec)) {
|
|
2419
2419
|
throw new errors.InputError(`Task spec is not a valid v1beta2 task spec`);
|
|
2420
2420
|
}
|
|
@@ -2517,8 +2517,7 @@ class HandlebarsWorkflowRunner {
|
|
|
2517
2517
|
logger: taskLogger,
|
|
2518
2518
|
logStream: stream$1,
|
|
2519
2519
|
input,
|
|
2520
|
-
|
|
2521
|
-
secrets: (_c = task.secrets) != null ? _c : {},
|
|
2520
|
+
secrets: (_b = task.secrets) != null ? _b : {},
|
|
2522
2521
|
workspacePath,
|
|
2523
2522
|
async createTemporaryDirectory() {
|
|
2524
2523
|
const tmpDir = await fs__default["default"].mkdtemp(`${workspacePath}_step-${step.id}-`);
|
|
@@ -2644,7 +2643,7 @@ class NunjucksWorkflowRunner {
|
|
|
2644
2643
|
});
|
|
2645
2644
|
}
|
|
2646
2645
|
async execute(task) {
|
|
2647
|
-
var _a, _b, _c, _d
|
|
2646
|
+
var _a, _b, _c, _d;
|
|
2648
2647
|
if (!isValidTaskSpec(task.spec)) {
|
|
2649
2648
|
throw new errors.InputError("Wrong template version executed with the workflow engine");
|
|
2650
2649
|
}
|
|
@@ -2688,14 +2687,10 @@ class NunjucksWorkflowRunner {
|
|
|
2688
2687
|
}
|
|
2689
2688
|
const tmpDirs = new Array();
|
|
2690
2689
|
const stepOutput = {};
|
|
2691
|
-
if (!task.spec.metadata) {
|
|
2692
|
-
console.warn("DEPRECATION NOTICE: metadata is undefined. metadata will be required in the future.");
|
|
2693
|
-
}
|
|
2694
2690
|
await action.handler({
|
|
2695
2691
|
baseUrl: task.spec.baseUrl,
|
|
2696
2692
|
input,
|
|
2697
|
-
|
|
2698
|
-
secrets: (_e = task.secrets) != null ? _e : {},
|
|
2693
|
+
secrets: (_d = task.secrets) != null ? _d : {},
|
|
2699
2694
|
logger: taskLogger,
|
|
2700
2695
|
logStream: streamLogger,
|
|
2701
2696
|
workspacePath,
|
|
@@ -2787,28 +2782,6 @@ class TaskWorker {
|
|
|
2787
2782
|
}
|
|
2788
2783
|
}
|
|
2789
2784
|
|
|
2790
|
-
class CatalogEntityClient {
|
|
2791
|
-
constructor(catalogClient) {
|
|
2792
|
-
this.catalogClient = catalogClient;
|
|
2793
|
-
}
|
|
2794
|
-
async findTemplate(templateName, options) {
|
|
2795
|
-
const { items: templates } = await this.catalogClient.getEntities({
|
|
2796
|
-
filter: {
|
|
2797
|
-
kind: "template",
|
|
2798
|
-
"metadata.name": templateName
|
|
2799
|
-
}
|
|
2800
|
-
}, options);
|
|
2801
|
-
if (templates.length !== 1) {
|
|
2802
|
-
if (templates.length > 1) {
|
|
2803
|
-
throw new errors.ConflictError("Templates lookup resulted in multiple matches");
|
|
2804
|
-
} else {
|
|
2805
|
-
throw new errors.NotFoundError("Template not found");
|
|
2806
|
-
}
|
|
2807
|
-
}
|
|
2808
|
-
return templates[0];
|
|
2809
|
-
}
|
|
2810
|
-
}
|
|
2811
|
-
|
|
2812
2785
|
async function getWorkingDirectory(config, logger) {
|
|
2813
2786
|
if (!config.has("backend.workingDirectory")) {
|
|
2814
2787
|
return os__default["default"].tmpdir();
|
|
@@ -2826,14 +2799,14 @@ async function getWorkingDirectory(config, logger) {
|
|
|
2826
2799
|
}
|
|
2827
2800
|
function getEntityBaseUrl(entity) {
|
|
2828
2801
|
var _a, _b;
|
|
2829
|
-
let location = (_a = entity.metadata.annotations) == null ? void 0 : _a[catalogModel.
|
|
2802
|
+
let location = (_a = entity.metadata.annotations) == null ? void 0 : _a[catalogModel.ANNOTATION_SOURCE_LOCATION];
|
|
2830
2803
|
if (!location) {
|
|
2831
|
-
location = (_b = entity.metadata.annotations) == null ? void 0 : _b[catalogModel.
|
|
2804
|
+
location = (_b = entity.metadata.annotations) == null ? void 0 : _b[catalogModel.ANNOTATION_LOCATION];
|
|
2832
2805
|
}
|
|
2833
2806
|
if (!location) {
|
|
2834
2807
|
return void 0;
|
|
2835
2808
|
}
|
|
2836
|
-
const { type, target } = catalogModel.
|
|
2809
|
+
const { type, target } = catalogModel.parseLocationRef(location);
|
|
2837
2810
|
if (type === "url") {
|
|
2838
2811
|
return target;
|
|
2839
2812
|
} else if (type === "file") {
|
|
@@ -2841,6 +2814,34 @@ function getEntityBaseUrl(entity) {
|
|
|
2841
2814
|
}
|
|
2842
2815
|
return void 0;
|
|
2843
2816
|
}
|
|
2817
|
+
async function findTemplate({
|
|
2818
|
+
entityRef,
|
|
2819
|
+
token,
|
|
2820
|
+
catalogApi
|
|
2821
|
+
}) {
|
|
2822
|
+
const parsedEntityRef = catalogModel.parseEntityRef(entityRef, {
|
|
2823
|
+
defaultKind: "template",
|
|
2824
|
+
defaultNamespace: "default"
|
|
2825
|
+
});
|
|
2826
|
+
const { items } = await catalogApi.getEntities({
|
|
2827
|
+
filter: {
|
|
2828
|
+
kind: "template",
|
|
2829
|
+
"metadata.name": parsedEntityRef.name,
|
|
2830
|
+
"metadata.namespace": parsedEntityRef.namespace
|
|
2831
|
+
}
|
|
2832
|
+
}, {
|
|
2833
|
+
token
|
|
2834
|
+
});
|
|
2835
|
+
const templates = items.filter((entity) => entity.kind === "Template");
|
|
2836
|
+
if (templates.length !== 1) {
|
|
2837
|
+
if (templates.length > 1) {
|
|
2838
|
+
throw new errors.ConflictError("Templates lookup resulted in multiple matches");
|
|
2839
|
+
} else {
|
|
2840
|
+
throw new errors.NotFoundError("Template not found");
|
|
2841
|
+
}
|
|
2842
|
+
}
|
|
2843
|
+
return templates[0];
|
|
2844
|
+
}
|
|
2844
2845
|
|
|
2845
2846
|
function isSupportedTemplate(entity) {
|
|
2846
2847
|
return entity.apiVersion === "backstage.io/v1beta2" || entity.apiVersion === "scaffolder.backstage.io/v1beta3";
|
|
@@ -2861,7 +2862,6 @@ async function createRouter(options) {
|
|
|
2861
2862
|
} = options;
|
|
2862
2863
|
const logger = parentLogger.child({ plugin: "scaffolder" });
|
|
2863
2864
|
const workingDirectory = await getWorkingDirectory(config, logger);
|
|
2864
|
-
const entityClient = new CatalogEntityClient(catalogClient);
|
|
2865
2865
|
const integrations = integration.ScmIntegrations.fromConfig(config);
|
|
2866
2866
|
let taskBroker;
|
|
2867
2867
|
if (!options.taskBroker) {
|
|
@@ -2904,7 +2904,9 @@ async function createRouter(options) {
|
|
|
2904
2904
|
if (kind.toLowerCase() !== "template") {
|
|
2905
2905
|
throw new errors.InputError(`Invalid kind, only 'Template' kind is supported`);
|
|
2906
2906
|
}
|
|
2907
|
-
const template = await
|
|
2907
|
+
const template = await findTemplate({
|
|
2908
|
+
catalogApi: catalogClient,
|
|
2909
|
+
entityRef: { kind, namespace, name },
|
|
2908
2910
|
token: getBearerToken(req.headers.authorization)
|
|
2909
2911
|
});
|
|
2910
2912
|
if (isSupportedTemplate(template)) {
|
|
@@ -2936,11 +2938,18 @@ async function createRouter(options) {
|
|
|
2936
2938
|
const templateName = req.body.templateName;
|
|
2937
2939
|
const values = req.body.values;
|
|
2938
2940
|
const token = getBearerToken(req.headers.authorization);
|
|
2939
|
-
const template = await
|
|
2940
|
-
|
|
2941
|
+
const template = await findTemplate({
|
|
2942
|
+
catalogApi: catalogClient,
|
|
2943
|
+
entityRef: {
|
|
2944
|
+
name: templateName
|
|
2945
|
+
},
|
|
2946
|
+
token: getBearerToken(req.headers.authorization)
|
|
2941
2947
|
});
|
|
2942
2948
|
let taskSpec;
|
|
2943
2949
|
if (isSupportedTemplate(template)) {
|
|
2950
|
+
if (template.apiVersion === "backstage.io/v1beta2") {
|
|
2951
|
+
logger.warn(`Scaffolding ${catalogModel.stringifyEntityRef(template)} with deprecated apiVersion ${template.apiVersion}. Please migrate the template to backstage.io/v1beta3. https://backstage.io/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3`);
|
|
2952
|
+
}
|
|
2944
2953
|
for (const parameters of [(_a = template.spec.parameters) != null ? _a : []].flat()) {
|
|
2945
2954
|
const result2 = jsonschema.validate(values, parameters);
|
|
2946
2955
|
if (!result2.valid) {
|
|
@@ -3061,13 +3070,11 @@ function getBearerToken(header) {
|
|
|
3061
3070
|
|
|
3062
3071
|
class ScaffolderEntitiesProcessor {
|
|
3063
3072
|
constructor() {
|
|
3064
|
-
this.validators = [
|
|
3065
|
-
catalogModel.entityKindSchemaValidator(pluginScaffolderCommon.templateEntityV1beta3Schema)
|
|
3066
|
-
];
|
|
3073
|
+
this.validators = [pluginScaffolderCommon.templateEntityV1beta3Validator];
|
|
3067
3074
|
}
|
|
3068
3075
|
async validateEntityKind(entity) {
|
|
3069
3076
|
for (const validator of this.validators) {
|
|
3070
|
-
if (validator(entity)) {
|
|
3077
|
+
if (await validator.check(entity)) {
|
|
3071
3078
|
return true;
|
|
3072
3079
|
}
|
|
3073
3080
|
}
|
|
@@ -3111,7 +3118,6 @@ Object.defineProperty(exports, 'createFetchCookiecutterAction', {
|
|
|
3111
3118
|
enumerable: true,
|
|
3112
3119
|
get: function () { return pluginScaffolderBackendModuleCookiecutter.createFetchCookiecutterAction; }
|
|
3113
3120
|
});
|
|
3114
|
-
exports.CatalogEntityClient = CatalogEntityClient;
|
|
3115
3121
|
exports.DatabaseTaskStore = DatabaseTaskStore;
|
|
3116
3122
|
exports.OctokitProvider = OctokitProvider;
|
|
3117
3123
|
exports.ScaffolderEntitiesProcessor = ScaffolderEntitiesProcessor;
|