@salesforce/plugin-release-management
Version:
A plugin for preparing and publishing npm packages
120 lines • 5.04 kB
JavaScript
/*
* Copyright (c) 2020, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
/* eslint-disable no-await-in-loop */
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { exec as execSync } from 'node:child_process';
import { promisify } from 'node:util';
import chalk from 'chalk';
import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
import { Messages, SfError } from '@salesforce/core';
import { Duration, parseJson, ThrottledPromiseAll } from '@salesforce/kit';
import { testJITInstall } from '../../../jit.js';
const exec = promisify(execSync);
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-release-management', 'cli.tarballs.smoke');
export default class SmokeTest extends SfCommand {
static summary = messages.getMessage('description');
static description = messages.getMessage('description');
static examples = messages.getMessages('examples');
static flags = {
verbose: Flags.boolean({
summary: messages.getMessage('flags.verbose.summary'),
}),
};
flags;
async run() {
this.flags = (await this.parse(SmokeTest)).flags;
await this.smokeTest(path.join('tmp', 'sf', 'bin', 'sf'));
}
async smokeTest(executable) {
await Promise.all([
this.execute(executable, '--version'),
this.execute(executable, '--help'),
this.execute(executable, 'plugins --core'),
this.testInstall(executable, '@salesforce/plugin-settings', 'latest'),
]);
// This tests JIT installs on the generated tarball
// The cli/jit/install/test.ts command tests against a "local" version (e.g. npm install)
// If this test continues to be flakey, it could be removed
await this.testJITInstall(executable);
await this.initializeAllCommands(executable);
}
async testJITInstall(executable) {
await testJITInstall({
jsonEnabled: this.jsonEnabled(),
executable,
manifestPath: path.join('tmp', 'sf', 'oclif.manifest.json'),
});
}
async testInstall(executable, plugin, tag) {
await this.execute(executable, `plugins:install ${plugin}${tag ? `@${tag}` : ''}`);
await this.verifyInstall(plugin, executable);
}
async verifyInstall(plugin, executable, silent = false) {
const fileData = await fs.promises.readFile(path.join(os.homedir(), '.local', 'share', path.basename(executable), 'package.json'), 'utf-8');
const packageJson = parseJson(fileData);
if (!packageJson.dependencies?.[plugin]) {
if (silent) {
return false;
}
else {
throw new SfError(`Failed to install ${plugin}\n`);
}
}
else if (!silent) {
this.log('✅ ', chalk.green(`Verified installation of ${plugin}\n`));
return true;
}
return true;
}
async initializeAllCommands(executable) {
this.styledHeader("Initializing help for all 'sf' commands");
// Ran into memory issues when running all commands at once. Now we run them in batches of 10.
const throttledPromise = new ThrottledPromiseAll({
concurrency: 10,
timeout: Duration.minutes(10),
});
const allCommands = await this.getAllCommands(executable);
const executePromise = async (command) => this.flags.verbose
? this.execute(executable, `${command} --help`)
: this.nonVerboseCommandExecution(executable, command);
throttledPromise.add(allCommands, executePromise);
await throttledPromise.all();
}
async getAllCommands(executable) {
const commandsJson = JSON.parse(await this.execute(executable, 'commands --json', true));
return commandsJson.map((c) => c.id);
}
async nonVerboseCommandExecution(executable, command) {
try {
await this.execute(executable, `${command} --help`, true);
this.log(`${executable} ${command} --help ${chalk.green('PASSED')}`);
}
catch (err) {
this.log(`${executable} ${command} --help ${chalk.red('FAILED')}`);
throw err;
}
}
async execute(executable, args, silent = false) {
const command = `${executable} ${args}`;
try {
const { stdout } = await exec(command, { maxBuffer: 1024 * 1024 * 100 });
if (!silent) {
this.styledHeader(command);
this.log(stdout);
}
return stdout;
}
catch (e) {
const err = e;
throw new SfError(`Failed: ${command}.\n ${err.message}`, 'SMOKE_TEST_FAILURE', [], err);
}
}
}
//# sourceMappingURL=smoke.js.map