Skip to content

Commit

Permalink
Add release scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
rtivital committed Dec 21, 2023
1 parent 95b3fde commit 9387f0f
Show file tree
Hide file tree
Showing 6 changed files with 876 additions and 7 deletions.
18 changes: 15 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,28 @@
"postcss-nested": "^6.0.1"
},
"devDependencies": {
"@types/fs-extra": "^11",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.1",
"@types/postcss-mixins": "^9.0.0",
"@types/signale": "^1",
"@typescript-eslint/eslint-plugin": "^5.60.0",
"@typescript-eslint/parser": "^5.60.0",
"eslint": "^8.43.0",
"esno": "^4.0.0",
"execa": "^8.0.1",
"fs-extra": "^11.2.0",
"jest": "^29.5.0",
"new-github-release-url": "^2.0.0",
"open": "^10.0.0",
"postcss": "^8.4.24",
"prettier": "^2.8.8",
"signale": "^1.4.0",
"simple-git": "^3.21.0",
"ts-jest": "^29.1.0",
"tsc": "^2.0.4",
"typescript": "^5.1.3"
"typescript": "^5.1.3",
"version-next": "^1.0.2"
},
"scripts": {
"build": "tsc --project tsconfig.json && echo 'declare module \"postcss-preset-mantine\";' > dist/index.d.ts",
Expand All @@ -33,11 +43,13 @@
"typecheck": "tsc --noEmit",
"jest": "jest",
"prepublish": "yarn test && yarn build",
"test": "npm run lint && npm run format:check && npm run typecheck && npm run jest"
"test": "npm run lint && npm run format:check && npm run typecheck && npm run jest",
"clean": "rm -rf dist",
"release": "esno scripts/release"
},
"repository": {
"type": "git",
"url": "[email protected]:rtivital/postcss-preset-mantine.git"
"url": "[email protected]:mantinedev/postcss-preset-mantine.git"
},
"keywords": [
"postcss",
Expand Down
110 changes: 110 additions & 0 deletions scripts/release.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import path from 'node:path';
import chalk from 'chalk';
import fs from 'fs-extra';
import yargs from 'yargs';
import open from 'open';
import githubRelease from 'new-github-release-url';
import SimpleGit from 'simple-git';
import { hideBin } from 'yargs/helpers';
import execa from 'execa';
import signale from 'signale';
import { getNextVersion, VersionStage, VersionIncrement } from 'version-next';
import { run } from './run';
import { updateVersion } from './update-version';

function getRepositoryInfo(gitUrl: string) {
const [user, repo] = gitUrl.replace('git+https://github.com/', '').replace('.git', '').split('/');
return { user, repo };
}

const packageJsonPath = path.join(process.cwd(), 'package.json');
const packageJson = fs.readJsonSync(packageJsonPath);
const { argv } = yargs(hideBin(process.argv)) as any;
const git = SimpleGit();

const versionIncrement: VersionIncrement = argv._[0] || 'patch';
const versionStage: VersionStage | undefined = argv.stage;

async function release() {
await run(git.pull(), {
info: 'Pulling the latest changes from the remote repository',
success: 'The latest changes have been pulled from the remote repository',
error: 'Failed to pull the latest changes from the remote repository',
});

const gitStatus = await git.status();

if (gitStatus.files.length > 0) {
signale.error(
'Working directory is not clean, commit all changes before publishing the package.'
);

process.exit(1);
}

const nextVersion = getNextVersion(packageJson.version, {
type: versionIncrement,
stage: versionStage,
});

signale.info(
`Publishing next ${chalk.cyan(versionIncrement)} version of ${chalk.cyan(
packageJson.name
)} to npm.`
);

signale.info(
`Current version: ${chalk.cyan(packageJson.version)}, next version: ${chalk.cyan(nextVersion)}`
);

await run(execa('yarn'), {
info: 'Installing fresh dependencies',
success: 'Fresh dependencies have been installed',
error: 'Failed to install fresh dependencies',
});

await run(execa('yarn', ['run', 'clean']), {
info: 'Removing dist directory',
success: 'dist directory has been removed',
error: 'Failed to remove dist directory',
});

await run(execa('yarn', ['run', 'build']), {
info: 'Building the package',
success: 'The package has been built',
error: 'Failed to build the package',
});

const revertVersion = await updateVersion(nextVersion);

await run(
execa('yarn', [
'npm',
'publish',
'--access',
'public',
'--tag',
versionStage ? 'next' : 'latest',
]),
{
info: 'Publishing the package to npm',
success: 'The package has been published to npm',
error: 'Failed to publish the package to npm',
},
revertVersion
);

await git.add([packageJsonPath]);
await git.commit(`Release ${nextVersion}`);
await git.push();

open(
githubRelease({
...getRepositoryInfo(packageJson.repository.url),
tag: nextVersion,
title: nextVersion,
})
);
}

release();
29 changes: 29 additions & 0 deletions scripts/run.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import signale from 'signale';

interface RunMessages {
info: string;
success: string;
error: string;
}

export async function run<T>(
script: Promise<T>,
messages: RunMessages,
onError?: () => Promise<void>
) {
signale.info(messages.info);
try {
const response = await script;
signale.success(messages.success);
return response;
} catch (err) {
signale.error(messages.error);
signale.error(err);

if (onError) {
await onError();
}

process.exit(1);
}
}
14 changes: 14 additions & 0 deletions scripts/update-version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import path from 'node:path';
import fs from 'fs-extra';

export async function updateVersion(version: string) {
const packageJsonPath = path.join(process.cwd(), 'package.json');
const originalPackageJson = await fs.readJson(packageJsonPath);

const updatedPackageJson = { ...originalPackageJson };
updatedPackageJson.version = version;

await fs.writeJson(packageJsonPath, updatedPackageJson, { spaces: 2 });

return () => fs.writeJson(packageJsonPath, originalPackageJson, { spaces: 2 });
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
"compilerOptions": {
"lib": ["es2018", "dom"],
"outDir": "./dist",
"rootDir": "./src",
"target": "esnext",
"module": "CommonJS",
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
"declaration": false
},
"include": ["./scripts", "./src"],
"exclude": ["node_modules", "dist", "src/**/*.test.ts", "src/tests/**"]
}
Loading

0 comments on commit 9387f0f

Please sign in to comment.