devops: adapt repack-juggler script to work with win (#15254)

This patch:
- Uses some folder in `CWD` instead of `/tmp` on win32 to store
  builds
- Drops usage of `find`, `zip` and `unzip` posix tools. Instead, rely
  on `adm-zip` package.
This commit is contained in:
Andrey Lushnikov 2022-06-30 11:04:59 -07:00 committed by GitHub
parent 0254cd3be7
commit 35720e2fcd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 28 deletions

View File

@ -23,6 +23,7 @@ import * as https from 'https';
import * as os from 'os';
import * as util from 'util';
import * as child_process from 'child_process';
import AdmZip from 'adm-zip';
const existsAsync = path => new Promise(resolve => fs.stat(path, err => resolve(!err)));
@ -49,7 +50,7 @@ if (process.argv[2] === 'firefox' || process.argv[2] === 'ff') {
// Path to jar.mn in the juggler
const JARMN_PATH = path.join(__dirname, browserName, 'juggler', 'jar.mn');
// Workdir for Firefox repackaging
const BUILD_DIRECTORY = `/tmp/repackaged-firefox`;
const BUILD_DIRECTORY = os.platform() === 'win32' ? path.join(__dirname, '__repackaged_firefox__') : `/tmp/repackaged-firefox`;
// Information about currently downloaded build
const BUILD_INFO_PATH = path.join(BUILD_DIRECTORY, 'build-info.json');
// Backup OMNI.JA - the original one before repackaging.
@ -108,27 +109,48 @@ async function ensureFirefoxBuild(browserName, buildNumber, buildPlatform) {
throw new Error(`ERROR: repack-juggler does not support ${buildPlatform}`);
const url = util.format(urlTemplate, buildNumber);
console.log(`Downloading ${browserName} r${buildNumber} for ${buildPlatform} - it might take a few minutes`);
await downloadFile(url, buildZipPath);
await spawnAsync('unzip', [ buildZipPath ], { cwd: BUILD_DIRECTORY });
let downloadedPercentage = 0;
await downloadFile(url, buildZipPath, (downloaded, total) => {
const percentage = Math.round(downloaded / total * 10) * 10;
if (percentage === downloadedPercentage)
return;
downloadedPercentage = percentage;
console.log(`Downloaded: ${downloadedPercentage}%`);
});
const zip = new AdmZip(buildZipPath);
zip.extractAllTo(BUILD_DIRECTORY, false /* overwrite */, true /* keepOriginalPermission */);
const buildInfo = { buildNumber, buildPlatform, browserName };
await fs.promises.writeFile(BUILD_INFO_PATH, JSON.stringify(buildInfo), 'utf8');
return buildInfo;
}
async function listFiles(aPath, files = []) {
const stat = await fs.promises.lstat(aPath);
if (stat.isDirectory()) {
const entries = await fs.promises.readdir(aPath);
await Promise.all(entries.map(entry => listFiles(path.join(aPath, entry), files)));
} else {
files.push(aPath);
}
return files;
}
async function repackageJuggler(browserName, buildInfo) {
const { buildNumber, buildPlatform } = buildInfo;
// Find all omni.ja files in the Firefox build.
const omniPaths = await spawnAsync('find', ['.', '-name', 'omni.ja'], {
cwd: BUILD_DIRECTORY,
}).then(({ stdout }) => stdout.trim().split('\n').map(aPath => path.join(BUILD_DIRECTORY, aPath)));
const omniPaths = (await listFiles(BUILD_DIRECTORY)).filter(filePath => filePath.endsWith('omni.ja'));
// Iterate over all omni.ja files and find one that has juggler inside.
const omniWithJugglerPath = await (async () => {
for (const omniPath of omniPaths) {
const { stdout } = await spawnAsync('unzip', ['-Z1', omniPath], { cwd: BUILD_DIRECTORY });
if (stdout.includes('chrome/juggler'))
return omniPath;
const zip = new AdmZip(omniPath);
for (const zipEntry of zip.getEntries()) {
if (zipEntry.toString().includes('chrome/juggler'))
return omniPath;
}
}
return null;
})();
@ -145,7 +167,12 @@ async function repackageJuggler(browserName, buildInfo) {
await fs.promises.rm(OMNI_EXTRACT_DIR, { recursive: true }).catch(e => {});
await fs.promises.mkdir(OMNI_EXTRACT_DIR);
await spawnAsync('unzip', [OMNI_BACKUP_PATH], { cwd: OMNI_EXTRACT_DIR });
{
// Unzip omni
const zip = new AdmZip(OMNI_BACKUP_PATH);
zip.extractAllTo(OMNI_EXTRACT_DIR, false /* overwrite */, true /* keepOriginalPermission */);
}
// Remove current juggler directory
await fs.promises.rm(OMNI_JUGGLER_DIR, { recursive: true });
// Repopulate with tip-of-tree juggler files
@ -160,9 +187,13 @@ async function repackageJuggler(browserName, buildInfo) {
}
await fs.promises.unlink(omniWithJugglerPath);
await spawnAsync('zip', ['-0', '-qr9XD', omniWithJugglerPath, '.'], { cwd: OMNI_EXTRACT_DIR, stdio: 'inherit' });
{
const zip = new AdmZip();
zip.addLocalFolder(OMNI_EXTRACT_DIR);
zip.writeZip(omniWithJugglerPath);
}
const module = await import(path.join(__dirname, browserName, 'install-preferences.js'));
const module = await import(URL.pathToFileURL(path.join(__dirname, browserName, 'install-preferences.js')));
await module.default.installFirefoxPreferences(path.join(BUILD_DIRECTORY, 'firefox'));
// Output executable path to be used in test.
@ -224,22 +255,6 @@ function downloadFile(url, destinationPath, progressCallback) {
}
}
function spawnAsync(cmd, args, options) {
// console.log(cmd, ...args, 'CWD:', options.cwd);
const process = child_process.spawn(cmd, args, options);
return new Promise(resolve => {
let stdout = '';
let stderr = '';
if (process.stdout)
process.stdout.on('data', data => stdout += data);
if (process.stderr)
process.stderr.on('data', data => stderr += data);
process.on('close', code => resolve({ stdout, stderr, code }));
process.on('error', error => resolve({ stdout, stderr, code: 0, error }));
});
}
function getUbuntuVersionSync() {
if (os.platform() !== 'linux')
return '';

16
package-lock.json generated
View File

@ -31,6 +31,7 @@
"@typescript-eslint/parser": "^5.10.2",
"@vitejs/plugin-react": "^1.3.2",
"@zip.js/zip.js": "^2.4.2",
"adm-zip": "^0.5.9",
"ansi-to-html": "^0.7.2",
"chokidar": "^3.5.3",
"colors": "^1.4.0",
@ -1996,6 +1997,15 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/adm-zip": {
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz",
"integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==",
"dev": true,
"engines": {
"node": ">=6.0"
}
},
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@ -8119,6 +8129,12 @@
"dev": true,
"requires": {}
},
"adm-zip": {
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz",
"integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==",
"dev": true
},
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",

View File

@ -65,6 +65,7 @@
"@typescript-eslint/parser": "^5.10.2",
"@vitejs/plugin-react": "^1.3.2",
"@zip.js/zip.js": "^2.4.2",
"adm-zip": "^0.5.9",
"ansi-to-html": "^0.7.2",
"chokidar": "^3.5.3",
"colors": "^1.4.0",