diff --git a/common/fixYamlHashes.js b/common/fixYamlHashes.js new file mode 100644 index 000000000..bf317ef23 --- /dev/null +++ b/common/fixYamlHashes.js @@ -0,0 +1,110 @@ +import fs from 'node:fs/promises'; +import { createHash } from 'node:crypto'; +import path from 'node:path'; +import process from 'node:process'; +import { fileURLToPath } from 'node:url'; +import YAML from 'yaml'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +async function sha512Base64(filePath) { + const buf = await fs.readFile(filePath); + const h = createHash('sha512'); + h.update(buf); + return h.digest('base64'); +} + +async function fileSize(filePath) { + const st = await fs.stat(filePath); + return st.size; +} + +async function fixOneYaml(ymlPath, distDir) { + let raw; + try { + raw = await fs.readFile(ymlPath, 'utf8'); + } catch (e) { + console.error(`✗ Cannot read ${ymlPath}:`, e.message); + return; + } + + let doc; + try { + doc = YAML.parse(raw); + } catch (e) { + console.error(`✗ Cannot parse YAML ${ymlPath}:`, e.message); + return; + } + + if (!doc || !Array.isArray(doc.files)) { + console.warn(`! ${path.basename(ymlPath)} has no 'files' array — skipped.`); + return; + } + + let changed = false; + + // Update each files[i].sha512 and files[i].size based on files[i].url + for (const entry of doc.files) { + if (!entry?.url) continue; + + const target = path.resolve(distDir, entry.url); + try { + const [hash, size] = await Promise.all([sha512Base64(target), fileSize(target)]); + if (entry.sha512 !== hash || entry.size !== size) { + console.log(`• ${path.basename(ymlPath)}: refresh ${entry.url}`); + entry.sha512 = hash; + entry.size = size; + changed = true; + } + } catch (e) { + console.warn( + `! Missing or unreadable file for ${entry.url} (referenced by ${path.basename(ymlPath)}): ${e.message}` + ); + } + } + + // Update top-level sha512 for the primary "path" file if present + if (doc.path) { + const primary = path.resolve(distDir, doc.path); + try { + const hash = await sha512Base64(primary); + if (doc.sha512 !== hash) { + console.log(`• ${path.basename(ymlPath)}: refresh top-level sha512 for path=${doc.path}`); + doc.sha512 = hash; + changed = true; + } + } catch (e) { + console.warn(`! Primary 'path' file not found for ${path.basename(ymlPath)}: ${doc.path} (${e.message})`); + } + } + + if (changed) { + const out = YAML.stringify(doc); + await fs.writeFile(ymlPath, out, 'utf8'); + console.log(`✓ Updated ${path.basename(ymlPath)}`); + } else { + console.log(`= No changes for ${path.basename(ymlPath)}`); + } +} + +async function main() { + const distDir = path.resolve(process.argv[2] ?? path.join(__dirname, '..', 'app', 'dist')); + const entries = await fs.readdir(distDir); + const ymls = entries.filter(f => f.toLowerCase().endsWith('.yml')); + + if (ymls.length === 0) { + console.warn(`No .yml files found in ${distDir}`); + return; + } + + console.log(`Scanning ${distDir}`); + for (const y of ymls) { + await fixOneYaml(path.join(distDir, y), distDir); + } +} + +main().catch(err => { + console.error(err); + process.exit(1); +}); diff --git a/package.json b/package.json index 24d09866a..fe0d62ab2 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "generatePadFile": "node generatePadFile", "fillPackagedPlugins": "node fillPackagedPlugins", "resetPackagedPlugins": "node resetPackagedPlugins", + "fixYmlHashes": "cd common && yarn init -y && yarn add yaml -W && cd .. && node common/fixYmlHashes.js app/dist", "prettier": "prettier --write packages/api/src && prettier --write packages/datalib/src && prettier --write packages/filterparser/src && prettier --write packages/sqltree/src && prettier --write packages/tools/src && prettier --write packages/types && prettier --write packages/web/src && prettier --write app/src", "copy:docker:build": "copyfiles packages/api/dist/* docker -f && copyfiles packages/web/public/* docker -u 2 && copyfiles \"packages/web/public/**/*\" docker -u 2 && copyfiles \"plugins/dist/**/*\" docker/plugins -u 2", "copy:packer:build": "copyfiles packages/api/dist/* packer/build -f && copyfiles packages/web/public/* packer/build -u 2 && copyfiles \"packages/web/public/**/*\" packer/build -u 2 && copyfiles \"plugins/dist/**/*\" packer/build/plugins -u 2 && copyfiles packer/install-packages.sh packer/build -f && yarn install:drivers:packer", diff --git a/workflow-templates/build-app.tpl.yaml b/workflow-templates/build-app.tpl.yaml index 750d99d30..e4b9025ac 100644 --- a/workflow-templates/build-app.tpl.yaml +++ b/workflow-templates/build-app.tpl.yaml @@ -209,6 +209,11 @@ jobs: timestamp-rfc3161: http://timestamp.acs.microsoft.com timestamp-digest: SHA256 + - name: Fix YML hashes + if: matrix.os == 'windows-2022' + run: | + yarn run fixYmlHashes + - name: Copy artifacts run: | mkdir artifacts