storybook/scripts/run-registry.ts

160 lines
4.3 KiB
TypeScript
Raw Normal View History

2020-05-09 11:34:50 +02:00
import { exec } from 'child_process';
import { remove, pathExists } from 'fs-extra';
import chalk from 'chalk';
2020-05-09 11:34:50 +02:00
import path from 'path';
import program from 'commander';
import detectFreePort from 'detect-port';
import fs from 'fs';
2020-05-09 11:34:50 +02:00
import yaml from 'js-yaml';
2020-05-09 11:34:50 +02:00
import startVerdaccioServer from 'verdaccio';
import pLimit from 'p-limit';
// @ts-expect-error (Converted from ts-ignore)
import { maxConcurrentTasks } from './utils/concurrency';
2022-07-23 19:40:03 +02:00
import { listOfPackages } from './utils/list-packages';
2019-04-25 11:44:33 +02:00
2020-05-09 11:34:50 +02:00
program
.option('-O, --open', 'keep process open')
.option('-P, --publish', 'should publish packages')
.option('-p, --port <port>', 'port to run https server on');
2020-05-09 11:34:50 +02:00
program.parse(process.argv);
const logger = console;
2020-05-18 14:58:55 +02:00
const freePort = (port?: number) => port || detectFreePort(port);
2019-04-25 11:44:33 +02:00
const startVerdaccio = (port: number): Promise<any> => {
let resolved = false;
return Promise.race([
2020-05-09 11:34:50 +02:00
new Promise((resolve) => {
const cache = path.join(__dirname, '..', '.verdaccio-cache');
const config = {
2020-11-26 16:55:47 +01:00
...(yaml.safeLoad(
fs.readFileSync(path.join(__dirname, 'verdaccio.yaml'), 'utf8')
) as Record<string, any>),
2020-05-09 11:34:50 +02:00
self_path: cache,
};
2020-05-18 15:09:22 +02:00
const onReady = (webServer: any) => {
2020-05-09 11:34:50 +02:00
webServer.listen(port, () => {
resolved = true;
2020-05-09 11:34:50 +02:00
resolve(webServer);
});
2020-05-09 11:34:50 +02:00
};
startVerdaccioServer(config, 6001, cache, '1.0.0', 'verdaccio', onReady);
}),
2020-05-18 22:29:50 +02:00
new Promise((_, rej) => {
setTimeout(() => {
if (!resolved) {
resolved = true;
rej(new Error(`TIMEOUT - verdaccio didn't start within 10s`));
}
}, 10000);
}),
]);
};
const currentVersion = async () => {
const { version } = (await import('../code/lerna.json')).default;
return version;
};
2020-05-18 14:58:55 +02:00
const publish = (packages: { name: string; location: string }[], url: string) => {
logger.log(`Publishing packages with a concurrency of ${maxConcurrentTasks}`);
const limit = pLimit(maxConcurrentTasks);
2020-09-14 22:20:57 +02:00
let i = 0;
2020-05-09 11:34:50 +02:00
return Promise.all(
packages.map(({ name, location }) =>
limit(
() =>
new Promise((res, rej) => {
logger.log(
`🛫 publishing ${name} (${location.replace(
path.resolve(path.join(__dirname, '..')),
'.'
)})`
);
const command = `cd ${location} && npm publish --registry ${url} --force --access restricted --ignore-scripts`;
2020-05-09 11:34:50 +02:00
exec(command, (e) => {
if (e) {
rej(e);
} else {
2020-09-14 22:20:57 +02:00
i += 1;
logger.log(`${i}/${packages.length} 🛬 successful publish of ${name}!`);
2020-11-26 10:58:09 +01:00
res(undefined);
2020-05-09 11:34:50 +02:00
}
});
})
)
)
);
};
const addUser = (url: string) =>
new Promise((res, rej) => {
logger.log(`👤 add temp user to verdaccio`);
exec(`npx npm-cli-adduser -r "${url}" -a -u user -p password -e user@example.com`, (e) => {
if (e) {
rej(e);
} else {
res();
}
});
});
const run = async () => {
2020-05-09 11:34:50 +02:00
const port = await freePort(program.port);
2019-04-25 11:44:33 +02:00
logger.log(`🌏 found a open port: ${port}`);
2020-05-09 11:34:50 +02:00
const verdaccioUrl = `http://localhost:${port}`;
2019-04-25 11:44:33 +02:00
logger.log(`📐 reading version of storybook`);
logger.log(`🚛 listing storybook packages`);
if (!process.env.CI) {
// when running e2e locally, clear cache to avoid EPUBLISHCONFLICT errors
const verdaccioCache = path.resolve(__dirname, '..', '.verdaccio-cache');
if (await pathExists(verdaccioCache)) {
logger.log(`🗑 cleaning up cache`);
await remove(verdaccioCache);
}
}
2020-05-09 11:34:50 +02:00
logger.log(`🎬 starting verdaccio (this takes ±5 seconds, so be patient)`);
const [verdaccioServer, packages, version] = await Promise.all([
startVerdaccio(port),
listOfPackages(),
currentVersion(),
]);
2019-04-25 11:44:33 +02:00
logger.log(`🌿 verdaccio running on ${verdaccioUrl}`);
// in some environments you need to add a dummy user. always try to add & catch on failure
try {
await addUser(verdaccioUrl);
} catch (e) {
//
}
2020-05-09 11:34:50 +02:00
logger.log(`📦 found ${packages.length} storybook packages at version ${chalk.blue(version)}`);
2020-05-09 11:34:50 +02:00
if (program.publish) {
await publish(packages, verdaccioUrl);
}
2020-05-09 11:34:50 +02:00
if (!program.open) {
verdaccioServer.close();
2019-04-25 11:44:33 +02:00
}
};
2020-05-09 11:34:50 +02:00
run().catch((e) => {
logger.error(e);
process.exit(1);
});