Switch from js-yaml to yaml for better output formatting

This commit is contained in:
Michael B. Gale
2026-02-28 17:55:41 +00:00
parent a85af80f34
commit 0ea8490473
3 changed files with 41 additions and 46 deletions

View File

@@ -5,10 +5,9 @@
"packages": {
"": {
"dependencies": {
"js-yaml": "^4.1.1"
"yaml": "^2.8.2"
},
"devDependencies": {
"@types/js-yaml": "^4.0.9",
"@types/node": "^20.19.9",
"tsx": "^4.21.0",
"typescript": "^5.9.3"
@@ -456,13 +455,6 @@
"node": ">=18"
}
},
"node_modules/@types/js-yaml": {
"version": "4.0.9",
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz",
"integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "20.19.35",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.35.tgz",
@@ -473,12 +465,6 @@
"undici-types": "~6.21.0"
}
},
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"license": "Python-2.0"
},
"node_modules/esbuild": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
@@ -549,18 +535,6 @@
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
}
},
"node_modules/js-yaml": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/resolve-pkg-maps": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
@@ -611,6 +585,21 @@
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true,
"license": "MIT"
},
"node_modules/yaml": {
"version": "2.8.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
"integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
},
"engines": {
"node": ">= 14.6"
},
"funding": {
"url": "https://github.com/sponsors/eemeli"
}
}
}
}

View File

@@ -2,12 +2,11 @@
"private": true,
"description": "Dependencies for the sync.ts",
"dependencies": {
"js-yaml": "^4.1.1"
"yaml": "^2.8.2"
},
"devDependencies": {
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"@types/node": "^20.19.9",
"@types/js-yaml": "^4.0.9"
"tsx": "^4.21.0",
"typescript": "^5.9.3"
}
}

View File

@@ -3,7 +3,7 @@
import * as fs from "fs";
import * as path from "path";
import * as yaml from "js-yaml";
import * as yaml from "yaml";
/**
* Represents workflow input definitions.
@@ -84,30 +84,31 @@ const CHECKS_DIR = path.join(THIS_DIR, "checks");
const OUTPUT_DIR = path.join(THIS_DIR, "new-output");
/**
* Loads and parses a YAML file as a `Specification`.
* Loads and parses a YAML file.
*/
function loadYaml(filePath: string): Specification {
function loadYaml(filePath: string): yaml.Document {
const content = fs.readFileSync(filePath, "utf8");
return yaml.load(content) as Specification;
return yaml.parseDocument(content);
}
/**
* Serialize a value to YAML and write it to a file, prepended with the
* standard header comment.
*/
function writeYaml(filePath: string, data: any): void {
function writeYaml(filePath: string, workflow: any): void {
const header = `# Warning: This file is generated automatically, and should not be modified.
# Instead, please modify the template in the pr-checks directory and run:
# pr-checks/sync.sh
# to regenerate this file.
`;
const yamlStr = yaml.dump(data, {
indent: 2,
lineWidth: -1, // Don't wrap long lines
noRefs: true, // Don't use YAML anchors/aliases
quotingType: "'", // Use single quotes where quoting is needed
forceQuotes: false,
const workflowDoc = new yaml.Document(workflow, {
aliasDuplicateObjects: false,
});
const yamlStr = yaml.stringify(workflowDoc, {
aliasDuplicateObjects: false,
singleQuote: true,
lineWidth: 0,
});
fs.writeFileSync(filePath, stripTrailingWhitespace(header + yamlStr), "utf8");
}
@@ -156,7 +157,8 @@ function main(): void {
for (const file of checkFiles) {
const checkName = path.basename(file, ".yml");
const checkSpecification = loadYaml(file);
const specDocument = loadYaml(file);
const checkSpecification = specDocument.toJS() as Specification;
console.log(`Processing: ${checkName} — "${checkSpecification.name}"`);
@@ -361,7 +363,9 @@ function main(): void {
});
}
steps.push(...checkSpecification.steps);
// Extract the sequence of steps from the YAML document to persist as much formatting as possible.
const specSteps = specDocument.get("steps") as yaml.YAMLSeq;
specSteps.items.unshift(...steps);
const checkJob: Record<string, any> = {
strategy: {
@@ -378,7 +382,7 @@ function main(): void {
},
"timeout-minutes": 45,
"runs-on": "${{ matrix.os }}",
steps,
steps: specSteps,
};
if (checkSpecification.permissions) {
@@ -414,6 +418,9 @@ function main(): void {
extraGroupName += "-${{inputs." + inputName + "}}";
}
const cron = new yaml.Scalar("0 5 * * *");
cron.type = yaml.Scalar.QUOTE_SINGLE;
const workflow = {
name: `PR Check - ${checkSpecification.name}`,
env: {
@@ -430,7 +437,7 @@ function main(): void {
merge_group: {
types: ["checks_requested"],
},
schedule: [{ cron: "0 5 * * *" }],
schedule: [{ cron }],
workflow_dispatch: {
inputs: workflowInputs,
},