From 6b54599ca7c123ebeef0bfc151b4b66ab5ae7870 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sat, 31 Aug 2024 06:59:34 -0700 Subject: [PATCH 1/4] Get publish script working on Windows/node 20 Part of #5135 --- bin/publish.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bin/publish.js b/bin/publish.js index 1f47a82bb2..7587b475e6 100644 --- a/bin/publish.js +++ b/bin/publish.js @@ -9,7 +9,9 @@ const os = require('os'); const path = require('path'); // Setup auth -fs.writeFileSync(`${process.env['HOME']}/.npmrc`, `//registry.npmjs.org/:_authToken=${process.env['NPM_AUTH_TOKEN']}`); +if (process.env['NPM_AUTH_TOKEN']) { + fs.writeFileSync(`${process.env['HOME']}/.npmrc`, `//registry.npmjs.org/:_authToken=${process.env['NPM_AUTH_TOKEN']}`); +} const isDryRun = process.argv.includes('--dry'); if (isDryRun) { @@ -118,7 +120,11 @@ function asArray(value) { } function getPublishedVersions(packageJson, version, tag) { - const versionsProcess = cp.spawnSync(os.platform === 'win32' ? 'npm.cmd' : 'npm', ['view', packageJson.name, 'versions', '--json']); + const versionsProcess = cp.spawnSync( + os.platform === 'win32' ? 'npm.cmd' : 'npm', + ['view', packageJson.name, 'versions', '--json'], + { shell: true } + ); if (versionsProcess.stdout.length === 0 && versionsProcess.stderr) { const err = versionsProcess.stderr.toString(); if (err.indexOf('404 Not Found - GET https://registry.npmjs.org/@xterm') > 0) { From 7ebbb86b506fbb7135955b9d88a3b9b56c5825d8 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sat, 31 Aug 2024 07:18:52 -0700 Subject: [PATCH 2/4] Set peer dependencies and commit in published package.json The commit will allow us to link published releases to the exact code version. Fixes #5135 --- bin/publish.js | 60 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/bin/publish.js b/bin/publish.js index 7587b475e6..639febbc41 100644 --- a/bin/publish.js +++ b/bin/publish.js @@ -18,14 +18,25 @@ if (isDryRun) { console.log('Publish dry run'); } +const allAddons = process.argv.includes('--all-addons'); +if (allAddons) { + console.log('Publish all addons'); +} + +const repoCommit = getRepoCommit(); const changedFiles = getChangedFilesInCommit('HEAD'); -// Publish xterm if any files were changed outside of the addons directory -let isStableRelease = false; -if (changedFiles.some(e => e.search(/^addons\//) === -1)) { - isStableRelease = checkAndPublishPackage(path.resolve(__dirname, '..')); - checkAndPublishPackage(path.resolve(__dirname, '../headless')); -} +// Always publish xterm, technically this isn't needed if +// `changedFiles.some(e => e.search(/^addons\//)`, but it's here for convenience to get the right +// peer dependencies for addons. +const result = checkAndPublishPackage(path.resolve(__dirname, '..'), repoCommit); +const isStableRelease = result.isStableRelease; +const peerDependencies = { + '@xterm/xterm': `^${result.nextVersion}`, +}; +checkAndPublishPackage(path.resolve(__dirname, '../headless'), repoCommit); + +// Addon peer dependencies // Publish addons if any files were changed inside of the addon const addonPackageDirs = [ @@ -44,9 +55,9 @@ const addonPackageDirs = [ console.log(`Checking if addons need to be published`); for (const p of addonPackageDirs) { const addon = path.basename(p); - if (changedFiles.some(e => e.includes(addon))) { + if (allAddons || changedFiles.some(e => e.includes(addon))) { console.log(`Try publish ${addon}`); - checkAndPublishPackage(p); + checkAndPublishPackage(p, repoCommit, peerDependencies); } } @@ -55,7 +66,7 @@ if (isStableRelease) { updateWebsite(); } -function checkAndPublishPackage(packageDir) { +function checkAndPublishPackage(packageDir, repoCommit, peerDependencies) { const packageJson = require(path.join(packageDir, 'package.json')); // Determine if this is a stable or beta release @@ -69,7 +80,24 @@ function checkAndPublishPackage(packageDir) { // Set the version in package.json const packageJsonFile = path.join(packageDir, 'package.json'); packageJson.version = nextVersion; - console.log(`Set version of ${packageJsonFile} to ${nextVersion}`); + + // Set the commit in package.json + if (repoCommit) { + packageJson.commit = repoCommit; + console.log(`Set commit of ${packageJsonFile} to ${repoCommit}`); + } else { + throw new Error(`No commit set`); + } + + // Set peer dependencies + if (peerDependencies) { + packageJson.peerDependencies = peerDependencies; + console.log(`Set peerDependencies of ${packageJsonFile} to ${JSON.stringify(peerDependencies)}`); + } else { + console.log(`Skipping peerDependencies`); + } + + // Write new package.json fs.writeFileSync(packageJsonFile, JSON.stringify(packageJson, null, 2)); // Publish @@ -92,7 +120,17 @@ function checkAndPublishPackage(packageDir) { console.groupEnd(); - return isStableRelease; + return { isStableRelease, nextVersion }; +} + +function getRepoCommit() { + const commitProcess = cp.spawnSync('git', ['log', '-1', '--format="%H"']); + if (commitProcess.stdout.length === 0 && commitProcess.stderr) { + const err = versionsProcess.stderr.toString(); + throw new Error('Could not get repo commit\n' + err); + } + const output = commitProcess.stdout.toString().trim(); + return output.replace(/^"/, '').replace(/"$/, ''); } function getNextBetaVersion(packageJson) { From 9a9ccbe29cc64e4969211ae04f51454a11b88188 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sat, 31 Aug 2024 07:24:50 -0700 Subject: [PATCH 3/4] Improve logging in publish script --- bin/publish.js | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/bin/publish.js b/bin/publish.js index 639febbc41..4175c40f8b 100644 --- a/bin/publish.js +++ b/bin/publish.js @@ -13,14 +13,15 @@ if (process.env['NPM_AUTH_TOKEN']) { fs.writeFileSync(`${process.env['HOME']}/.npmrc`, `//registry.npmjs.org/:_authToken=${process.env['NPM_AUTH_TOKEN']}`); } +log('Configuration:', 'green') const isDryRun = process.argv.includes('--dry'); if (isDryRun) { - console.log('Publish dry run'); + log(' Publish dry run'); } const allAddons = process.argv.includes('--all-addons'); if (allAddons) { - console.log('Publish all addons'); + log(' Publish all addons'); } const repoCommit = getRepoCommit(); @@ -52,11 +53,10 @@ const addonPackageDirs = [ path.resolve(__dirname, '../addons/addon-web-links'), path.resolve(__dirname, '../addons/addon-webgl') ]; -console.log(`Checking if addons need to be published`); +log(`Checking if addons need to be published`, 'green'); for (const p of addonPackageDirs) { const addon = path.basename(p); if (allAddons || changedFiles.some(e => e.includes(addon))) { - console.log(`Try publish ${addon}`); checkAndPublishPackage(p, repoCommit, peerDependencies); } } @@ -75,7 +75,7 @@ function checkAndPublishPackage(packageDir, repoCommit, peerDependencies) { // Get the next version let nextVersion = isStableRelease ? packageJson.version : getNextBetaVersion(packageJson); - console.log(`Publishing version: ${nextVersion}`); + log(`Publishing version: ${nextVersion}`, 'green'); // Set the version in package.json const packageJsonFile = path.join(packageDir, 'package.json'); @@ -84,7 +84,7 @@ function checkAndPublishPackage(packageDir, repoCommit, peerDependencies) { // Set the commit in package.json if (repoCommit) { packageJson.commit = repoCommit; - console.log(`Set commit of ${packageJsonFile} to ${repoCommit}`); + log(`Set commit of ${packageJsonFile} to ${repoCommit}`); } else { throw new Error(`No commit set`); } @@ -92,9 +92,9 @@ function checkAndPublishPackage(packageDir, repoCommit, peerDependencies) { // Set peer dependencies if (peerDependencies) { packageJson.peerDependencies = peerDependencies; - console.log(`Set peerDependencies of ${packageJsonFile} to ${JSON.stringify(peerDependencies)}`); + log(`Set peerDependencies of ${packageJsonFile} to ${JSON.stringify(peerDependencies)}`); } else { - console.log(`Skipping peerDependencies`); + log(`Skipping peerDependencies`); } // Write new package.json @@ -108,18 +108,16 @@ function checkAndPublishPackage(packageDir, repoCommit, peerDependencies) { if (isDryRun) { args.push('--dry-run'); } - console.log(`Spawn: npm ${args.join(' ')}`); + log(`Spawn: npm ${args.join(' ')}`); const result = cp.spawnSync('npm', args, { cwd: packageDir, stdio: 'inherit' }); if (result.status) { - console.error(`Spawn exited with code ${result.status}`); + error(`Spawn exited with code ${result.status}`); process.exit(result.status); } - console.groupEnd(); - return { isStableRelease, nextVersion }; } @@ -196,10 +194,29 @@ function getChangedFilesInCommit(commit) { } function updateWebsite() { - console.log('Updating website'); + log('Updating website', 'green'); const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'website-')); const packageJson = require(path.join(path.resolve(__dirname, '..'), 'package.json')); if (!isDryRun) { cp.spawnSync('sh', [path.join(__dirname, 'update-website.sh'), packageJson.version], { cwd, stdio: [process.stdin, process.stdout, process.stderr] }); } } + +/** + * @param {string} message + */ +function log(message, color) { + let colorSequence = ''; + switch (color) { + case 'green': { + colorSequence = '\x1b[32m'; + break; + } + } + console.info([ + `[\x1b[2m${new Date().toLocaleTimeString('en-GB')}\x1b[0m] `, + colorSequence, + message, + '\x1b[0m', + ].join('')); +} From 13d078ecc7a86cdd15fb44dbad53c72cc79d1638 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sat, 31 Aug 2024 07:26:12 -0700 Subject: [PATCH 4/4] Only set peerDependencies if the xterm version is beta --- bin/publish.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/publish.js b/bin/publish.js index 4175c40f8b..0a43b7c483 100644 --- a/bin/publish.js +++ b/bin/publish.js @@ -32,9 +32,9 @@ const changedFiles = getChangedFilesInCommit('HEAD'); // peer dependencies for addons. const result = checkAndPublishPackage(path.resolve(__dirname, '..'), repoCommit); const isStableRelease = result.isStableRelease; -const peerDependencies = { +const peerDependencies = result.nextVersion.includes('beta') ? { '@xterm/xterm': `^${result.nextVersion}`, -}; +} : undefined; checkAndPublishPackage(path.resolve(__dirname, '../headless'), repoCommit); // Addon peer dependencies