update publish script
This commit is contained in:
committed by
Carl-Gerhard Lindesvärd
parent
c5d7807584
commit
42736655c2
@@ -2,9 +2,8 @@ import { execSync } from 'node:child_process';
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import arg from 'arg';
|
import arg from 'arg';
|
||||||
import semver from 'semver';
|
import type { ReleaseType } from 'semver';
|
||||||
|
import semver, { RELEASE_TYPES } from 'semver';
|
||||||
const sdkPackages = ['sdk', 'react-native', 'web', 'nextjs', 'express'];
|
|
||||||
|
|
||||||
const workspacePath = (relativePath: string) =>
|
const workspacePath = (relativePath: string) =>
|
||||||
path.resolve(__dirname, '../../', relativePath);
|
path.resolve(__dirname, '../../', relativePath);
|
||||||
@@ -14,13 +13,15 @@ function savePackageJson(absPath: string, data: Record<string, any>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function exit(message: string, error?: unknown) {
|
function exit(message: string, error?: unknown) {
|
||||||
console.log(`❌ ${message}`);
|
console.log(`\n\n❌ ${message}`);
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.log(`Error: ${error.message}`);
|
console.log(`Error: ${error.message}`);
|
||||||
console.log(error);
|
console.log(error);
|
||||||
} else if (typeof error === 'string') {
|
} else if (typeof error === 'string') {
|
||||||
console.log(`Error: ${error}`);
|
console.log(`Error: ${error}`);
|
||||||
}
|
}
|
||||||
|
console.log('\n');
|
||||||
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,36 +36,111 @@ function checkUncommittedChanges() {
|
|||||||
execSync('git diff HEAD --exit-code');
|
execSync('git diff HEAD --exit-code');
|
||||||
console.log('✅ No uncommitted changes');
|
console.log('✅ No uncommitted changes');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
exit('Uncommitted changes', error);
|
exit('Uncommitted changes');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNextVersion(version: string, type: ReleaseType) {
|
||||||
|
const nextVersion = semver.inc(version, type);
|
||||||
|
if (!nextVersion) {
|
||||||
|
throw new Error('Invalid version');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.startsWith('pre')) {
|
||||||
|
return nextVersion.replace(/-.*$/, '-beta');
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPackageJson = {
|
||||||
|
type?: string;
|
||||||
|
name: string;
|
||||||
|
version: string;
|
||||||
|
dependencies: Record<string, string>;
|
||||||
|
devDependencies: Record<string, string>;
|
||||||
|
};
|
||||||
|
|
||||||
|
type IPackageJsonWithExtra = IPackageJson & {
|
||||||
|
nextVersion: string;
|
||||||
|
localPath: string;
|
||||||
|
};
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
const args = arg({
|
const args = arg({
|
||||||
// Types
|
'--name': String,
|
||||||
'--version': String,
|
|
||||||
'--test': Boolean,
|
'--test': Boolean,
|
||||||
'--skip-git': Boolean,
|
'--skip-git': Boolean,
|
||||||
// Aliases
|
// Semver
|
||||||
'-v': '--version',
|
'--type': String, // major, minor, patch, premajor, preminor, prepatch, or prerelease
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!args['--skip-git']) {
|
if (!args['--skip-git']) {
|
||||||
checkUncommittedChanges();
|
checkUncommittedChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
const version = args['--version'];
|
const pkgName = args['--name'];
|
||||||
|
const type = args['--type'] as ReleaseType;
|
||||||
const test = args['--test'];
|
const test = args['--test'];
|
||||||
|
const packages: Record<string, IPackageJsonWithExtra> = {};
|
||||||
|
const registry = test
|
||||||
|
? 'http://localhost:4873'
|
||||||
|
: 'https://registry.npmjs.org';
|
||||||
|
|
||||||
if (version && !semver.valid(version)) {
|
if (!RELEASE_TYPES.includes(type)) {
|
||||||
return console.error('Version is not valid');
|
return exit(
|
||||||
|
`Invalid release type. Valid types are: ${RELEASE_TYPES.join(', ')}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
if (!pkgName) {
|
||||||
for (const name of sdkPackages) {
|
return exit('--name is requred');
|
||||||
const properties: Record<string, unknown> = {
|
}
|
||||||
|
|
||||||
|
// Get all SDKs
|
||||||
|
const sdks = fs
|
||||||
|
.readdirSync(workspacePath('./packages/sdks'), {
|
||||||
|
withFileTypes: true,
|
||||||
|
})
|
||||||
|
.filter((item) => item.isDirectory() && !item.name.match(/^[._]/))
|
||||||
|
.map((item) => item.name);
|
||||||
|
|
||||||
|
// Get all SDK package.json
|
||||||
|
for (const name of sdks) {
|
||||||
|
const pkgJson = fs.readFileSync(
|
||||||
|
workspacePath(`./packages/sdks/${name}/package.json`),
|
||||||
|
'utf-8'
|
||||||
|
);
|
||||||
|
const parsed = JSON.parse(pkgJson) as IPackageJsonWithExtra;
|
||||||
|
parsed.nextVersion = getNextVersion(parsed.version, type);
|
||||||
|
parsed.localPath = `./packages/sdks/${name}`;
|
||||||
|
packages[parsed.name] = parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
const target = packages[pkgName];
|
||||||
|
|
||||||
|
if (!target) {
|
||||||
|
return exit('Selected package does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find if any package is dependent on the target
|
||||||
|
const dependents: string[] = [target.name];
|
||||||
|
function findDependents(visitPackageName: string) {
|
||||||
|
Object.entries(packages).forEach(([_name, pkg]) => {
|
||||||
|
if (pkg.dependencies?.[visitPackageName]) {
|
||||||
|
dependents.push(pkg.name);
|
||||||
|
findDependents(pkg.name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
findDependents(target.name);
|
||||||
|
|
||||||
|
function updatePackageJsonForRelease(name: string) {
|
||||||
|
const { nextVersion, localPath, ...restPkgJson } = packages[name]!;
|
||||||
|
const newPkgJson = JSON.parse(
|
||||||
|
JSON.stringify({
|
||||||
|
...restPkgJson,
|
||||||
private: false,
|
private: false,
|
||||||
version,
|
|
||||||
type: 'module',
|
type: 'module',
|
||||||
main: './dist/index.js',
|
main: './dist/index.js',
|
||||||
module: './dist/index.mjs',
|
module: './dist/index.mjs',
|
||||||
@@ -74,58 +150,72 @@ function main() {
|
|||||||
import: './dist/index.js',
|
import: './dist/index.js',
|
||||||
require: './dist/index.cjs',
|
require: './dist/index.cjs',
|
||||||
},
|
},
|
||||||
};
|
version: nextVersion,
|
||||||
|
dependencies: Object.entries(restPkgJson.dependencies).reduce(
|
||||||
|
(acc, [depName, depVersion]) => {
|
||||||
|
const dep = packages[depName];
|
||||||
|
if (!dep) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
// Not sure if I even should have type: module for any sdk
|
return {
|
||||||
if (name === 'nextjs') {
|
...acc,
|
||||||
delete properties.type;
|
[depName]: dependents.includes(depName)
|
||||||
}
|
? dep.nextVersion
|
||||||
|
: depVersion,
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
};
|
||||||
const pkgJson = require(
|
},
|
||||||
workspacePath(`./packages/sdks/${name}/package.json`)
|
|
||||||
);
|
|
||||||
savePackageJson(workspacePath(`./packages/sdks/${name}/package.json`), {
|
|
||||||
...pkgJson,
|
|
||||||
...properties,
|
|
||||||
dependencies: Object.entries(pkgJson.dependencies).reduce(
|
|
||||||
(acc, [depName, depVersion]) => ({
|
|
||||||
...acc,
|
|
||||||
[depName]: depName.startsWith('@openpanel') ? version : depVersion,
|
|
||||||
}),
|
|
||||||
{}
|
{}
|
||||||
),
|
),
|
||||||
});
|
})
|
||||||
|
) as IPackageJson;
|
||||||
|
|
||||||
|
if (name === '@openpanel/nextjs') {
|
||||||
|
delete newPkgJson.type;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
exit('Update JSON files', error);
|
savePackageJson(workspacePath(`${localPath}/package.json`), newPkgJson);
|
||||||
|
packages[name]!.dependencies = newPkgJson.dependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('✅ Update JSON files');
|
dependents.forEach((dependent) => {
|
||||||
|
console.log(
|
||||||
|
`📦 ${dependent} · Old Version: ${packages[dependent]?.version} · Next Version: ${packages[dependent]?.nextVersion}`
|
||||||
|
);
|
||||||
|
updatePackageJsonForRelease(dependent);
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
dependents.forEach((dependent) => {
|
||||||
for (const name of sdkPackages) {
|
console.log(`🔨 Building ${dependent}`);
|
||||||
execSync('pnpm build', {
|
execSync('pnpm build', {
|
||||||
cwd: workspacePath(`./packages/sdks/${name}`),
|
cwd: workspacePath(packages[dependent]!.localPath),
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
} catch (error) {
|
|
||||||
exit('Failed build packages', error);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('✅ Built packages');
|
// Publish
|
||||||
|
dependents.forEach((dependent) => {
|
||||||
|
console.log(`🚀 Publishing ${dependent} to ${registry}`);
|
||||||
|
execSync(`npm publish --access=public --registry ${registry}`, {
|
||||||
|
cwd: workspacePath(packages[dependent]!.localPath),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
if (!test) {
|
// Restoring package.json
|
||||||
try {
|
const filesToRestore = dependents
|
||||||
for (const name of sdkPackages) {
|
.map((dependent) => workspacePath(packages[dependent]!.localPath))
|
||||||
execSync('npm publish --access=public', {
|
.join(' ');
|
||||||
cwd: workspacePath(`./packages/sdks/${name}`),
|
|
||||||
});
|
execSync(`git checkout ${filesToRestore}`);
|
||||||
}
|
|
||||||
} catch (error) {
|
// // Save new versions only 😈
|
||||||
exit('Failed publish packages', error);
|
dependents.forEach((dependent) => {
|
||||||
}
|
const { nextVersion, localPath, ...restPkgJson } = packages[dependent]!;
|
||||||
}
|
console.log(`🚀 Saving ${dependent} (${nextVersion})`);
|
||||||
|
savePackageJson(workspacePath(`${localPath}/package.json`), {
|
||||||
|
...restPkgJson,
|
||||||
|
version: nextVersion,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
console.log('✅ All done!');
|
console.log('✅ All done!');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user