Refactored into a script using zod based on feedback
Signed-off-by: Andre Wanlin <awanlin@spotify.com>
This commit is contained in:
@@ -3,8 +3,8 @@ on:
|
||||
# NOTE: If you change these you must update ci-noop.yml as well
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'microsite/**'
|
||||
- 'beps/**'
|
||||
- "microsite/**"
|
||||
- "beps/**"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -121,20 +121,8 @@ jobs:
|
||||
- name: verify doc links
|
||||
run: node scripts/verify-links.js
|
||||
|
||||
- name: verify plugin directory files
|
||||
run: |
|
||||
if find ./microsite/data/plugins -maxdepth 1 -type f ! \( -name "*.yaml" \) | grep -q .; then
|
||||
find ./microsite/data/plugins -maxdepth 1 -type f ! \( -name "*.yaml" \)
|
||||
echo "Error: Non-YAML files found"
|
||||
exit 1
|
||||
else
|
||||
echo "Success: All files in are YAML files (based on extension)."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
- name: verify plugin directory schema
|
||||
run: yarn ajv validate -s microsite/data/plugin-schema.json -d "microsite/data/plugins/*.yaml" -c ajv-formats
|
||||
|
||||
- name: verify plugin directory
|
||||
run: node scripts/verify-plugin-directory.js
|
||||
- name: build all packages
|
||||
run: yarn backstage-cli repo build --all
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ addedDate: # The date plugin added to directory E.g. '2022-10-01' quotes are req
|
||||
You can validate your YAML file is correct by running the following from the root of the repo:
|
||||
|
||||
1. First run `yarn install`
|
||||
2. Then run `yarn ajv validate -s microsite/data/plugin-schema.json -d "microsite/data/plugins/<plugin-name>.yaml" -c ajv-formats` where `<plugin-name>` is the name of your plugin
|
||||
2. Then run `node ./scripts/verify-plugin-directory.js`
|
||||
|
||||
If there are any errors they will be listed and you will need to correct them. We run this same check as part of the CI.
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-06/schema#",
|
||||
"$ref": "#/definitions/plugin",
|
||||
"definitions": {
|
||||
"plugin": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"author": {
|
||||
"type": "string"
|
||||
},
|
||||
"authorUrl": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"category": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"documentation": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"iconUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"npmPackageName": {
|
||||
"type": "string"
|
||||
},
|
||||
"addedDate": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"order": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"addedDate",
|
||||
"author",
|
||||
"authorUrl",
|
||||
"category",
|
||||
"description",
|
||||
"documentation",
|
||||
"npmPackageName",
|
||||
"title"
|
||||
],
|
||||
"title": "plugin"
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -152,8 +152,6 @@
|
||||
"@types/memjs": "^1.3.3",
|
||||
"@types/node": "^22.13.14",
|
||||
"@types/webpack": "^5.28.0",
|
||||
"ajv-cli": "^5.0.0",
|
||||
"ajv-formats": "^3.0.1",
|
||||
"array-to-table": "^1.0.1",
|
||||
"command-exists": "^1.2.9",
|
||||
"cross-env": "^10.0.0",
|
||||
@@ -181,7 +179,8 @@
|
||||
"ts-morph": "^24.0.0",
|
||||
"typedoc": "^0.28.0",
|
||||
"typescript": "~5.7.0",
|
||||
"vite": "^7.1.5"
|
||||
"vite": "^7.1.5",
|
||||
"zod": "^3.25.76"
|
||||
},
|
||||
"packageManager": "yarn@4.8.1",
|
||||
"engines": {
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env node
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const fs = require('fs-extra');
|
||||
const { resolve, join } = require('node:path');
|
||||
const yaml = require('js-yaml');
|
||||
const z = require('zod');
|
||||
|
||||
const configSchema = z.object({
|
||||
title: z.string(),
|
||||
author: z.string(),
|
||||
authorUrl: z.string().url(),
|
||||
category: z.string(),
|
||||
description: z.string(),
|
||||
documentation: z.string().url(),
|
||||
iconUrl: z.string().optional(),
|
||||
npmPackageName: z.string(),
|
||||
addedDate: z.coerce.date(),
|
||||
order: z.number().optional(),
|
||||
});
|
||||
|
||||
async function main() {
|
||||
const rootPath = resolve(__dirname, '..');
|
||||
const pluginDirectoryPath = resolve(rootPath, 'microsite', 'data', 'plugins');
|
||||
|
||||
const pluginDirectoryFiles = await fs.readdir(pluginDirectoryPath);
|
||||
|
||||
let hasErrors = false;
|
||||
for (const pluginDirectoryFile of pluginDirectoryFiles) {
|
||||
if (!pluginDirectoryFile.toLocaleLowerCase().includes('.yaml')) {
|
||||
hasErrors = true;
|
||||
console.log(`${pluginDirectoryFile} is missing the '.yaml' extension`);
|
||||
}
|
||||
|
||||
const pluginDirectoryFilePath = join(
|
||||
pluginDirectoryPath,
|
||||
pluginDirectoryFile,
|
||||
);
|
||||
|
||||
const pluginDataYaml = yaml.load(
|
||||
fs.readFileSync(pluginDirectoryFilePath, { encoding: 'utf-8' }),
|
||||
);
|
||||
|
||||
try {
|
||||
configSchema.parse(pluginDataYaml);
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
console.log(
|
||||
`YAML data validation failed for ${pluginDirectoryFile}:`,
|
||||
error.errors,
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
`An unexpected error occurred for ${pluginDirectoryFile}:`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasErrors) {
|
||||
throw new Error(
|
||||
'There was an error verifying the Plugin Directory data files, review the output for guidance on what corrections are needed',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
main(process.argv.slice(2)).catch(error => {
|
||||
console.error(error.stack || error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -24306,28 +24306,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ajv-cli@npm:^5.0.0":
|
||||
version: 5.0.0
|
||||
resolution: "ajv-cli@npm:5.0.0"
|
||||
dependencies:
|
||||
ajv: "npm:^8.0.0"
|
||||
fast-json-patch: "npm:^2.0.0"
|
||||
glob: "npm:^7.1.0"
|
||||
js-yaml: "npm:^3.14.0"
|
||||
json-schema-migrate: "npm:^2.0.0"
|
||||
json5: "npm:^2.1.3"
|
||||
minimist: "npm:^1.2.0"
|
||||
peerDependencies:
|
||||
ts-node: ">=9.0.0"
|
||||
peerDependenciesMeta:
|
||||
ts-node:
|
||||
optional: true
|
||||
bin:
|
||||
ajv: dist/index.js
|
||||
checksum: 10/bd755f7f34602356c5c65bf947f3ba8d73b31859296b275eb3b112d2c14e125fcfca71bac9c8d4242a006fc62e9c868be3cf4652ebc6a8df08fe16f83ee9080c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ajv-draft-04@npm:^1.0.0, ajv-draft-04@npm:~1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "ajv-draft-04@npm:1.0.0"
|
||||
@@ -31196,13 +31174,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fast-deep-equal@npm:^2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "fast-deep-equal@npm:2.0.1"
|
||||
checksum: 10/b701835a87985e0ec4925bdf1f0c1e7eb56309b5d12d534d5b4b69d95a54d65bb16861c081781ead55f73f12d6c60ba668713391ee7fbf6b0567026f579b7b0b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3":
|
||||
version: 3.1.3
|
||||
resolution: "fast-deep-equal@npm:3.1.3"
|
||||
@@ -31237,15 +31208,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fast-json-patch@npm:^2.0.0":
|
||||
version: 2.2.1
|
||||
resolution: "fast-json-patch@npm:2.2.1"
|
||||
dependencies:
|
||||
fast-deep-equal: "npm:^2.0.1"
|
||||
checksum: 10/802924e8f6e50267c1c92c9a52de59e9e4d448a383c32119e228a17ef17fe90e54f52bb4211a616a9c93e708f873cc39d5df10ae77fe32cd5a22c4b9cb69cae9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fast-json-patch@npm:^3.0.0-1, fast-json-patch@npm:^3.1.0, fast-json-patch@npm:^3.1.1":
|
||||
version: 3.1.1
|
||||
resolution: "fast-json-patch@npm:3.1.1"
|
||||
@@ -32642,7 +32604,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"glob@npm:^7.1.0, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.1.7, glob@npm:^7.2.3":
|
||||
"glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.1.7, glob@npm:^7.2.3":
|
||||
version: 7.2.3
|
||||
resolution: "glob@npm:7.2.3"
|
||||
dependencies:
|
||||
@@ -36058,7 +36020,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"js-yaml@npm:^3.10.0, js-yaml@npm:^3.13.0, js-yaml@npm:^3.13.1, js-yaml@npm:^3.14.0, js-yaml@npm:^3.6.1, js-yaml@npm:^3.8.3":
|
||||
"js-yaml@npm:^3.10.0, js-yaml@npm:^3.13.0, js-yaml@npm:^3.13.1, js-yaml@npm:^3.6.1, js-yaml@npm:^3.8.3":
|
||||
version: 3.14.2
|
||||
resolution: "js-yaml@npm:3.14.2"
|
||||
dependencies:
|
||||
@@ -36309,15 +36271,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"json-schema-migrate@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "json-schema-migrate@npm:2.0.0"
|
||||
dependencies:
|
||||
ajv: "npm:^8.0.0"
|
||||
checksum: 10/bb32718273e0a1bcce5f3926f5c93559ceb209af19abb5af441fc1af937cfba39bab9884ae5461d91c5ba6019ea80067226b7c7a5b073fd8ab53133a981c387f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"json-schema-to-ts@npm:^3.0.0":
|
||||
version: 3.1.1
|
||||
resolution: "json-schema-to-ts@npm:3.1.1"
|
||||
@@ -45561,8 +45514,6 @@ __metadata:
|
||||
"@types/node": "npm:^22.13.14"
|
||||
"@types/webpack": "npm:^5.28.0"
|
||||
"@useoptic/optic": "npm:^1.0.0"
|
||||
ajv-cli: "npm:^5.0.0"
|
||||
ajv-formats: "npm:^3.0.1"
|
||||
array-to-table: "npm:^1.0.1"
|
||||
command-exists: "npm:^1.2.9"
|
||||
cross-env: "npm:^10.0.0"
|
||||
@@ -45592,6 +45543,7 @@ __metadata:
|
||||
typescript: "npm:~5.7.0"
|
||||
vite: "npm:^7.1.5"
|
||||
yaml: "npm:^2.7.0"
|
||||
zod: "npm:^3.25.76"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
|
||||
Reference in New Issue
Block a user