Skip to content

Commit

Permalink
feat: setup tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
syi0808 committed Oct 7, 2024
1 parent a96349b commit 521a391
Show file tree
Hide file tree
Showing 13 changed files with 367 additions and 111 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ You can have either package.json or jsr.json.

- Notify new version

- Required missing information
- Checking required information
- Select SemVer increment or specify new version
- Enter the tag for this pre-release version in npm: (if version is prerelease)
- Select the tag for this pre-release version in npm: (if version is prerelease)

- Prerequisite checks = skip-pre (for safety deploy)
- Prerequisite checks = skip-pre (for deployment reliability)
- Checking if remote history is clean...
- Checking if the local working tree is clean…
- Checking if commits exist since the last release...
Expand Down
65 changes: 25 additions & 40 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import cac from 'cac';
import type { OptionConfig } from 'cac/deno/Option.js';
import enquirer from 'enquirer';
import semver, { SemVer } from 'semver';
import c from 'tinyrainbow';
import semver from 'semver';
import { pubm } from './index.js';
import type { Options } from './types/options.js';
import { version } from './utils/version.js';
import { requiredMissingInformationTasks } from './tasks/required-missing-information.js';
import { version } from './utils/package-json.js';

const { prompt } = enquirer;
const { RELEASE_TYPES } = semver;

interface CliOptions {
Expand All @@ -16,6 +14,8 @@ interface CliOptions {
preview?: boolean;
branch: string;
anyBranch?: boolean;
preCheck: boolean;
conditionCheck: boolean;
cleanup: boolean;
tests: boolean;
build: boolean;
Expand Down Expand Up @@ -53,6 +53,16 @@ const options: {
description: 'Show tasks without actually executing publish',
options: { type: Boolean },
},
{
rawName: '--no-pre-check',
description: 'Skip prerequisites check task',
options: { type: Boolean },
},
{
rawName: '--no-condition-check',
description: 'Skip required conditions check task',
options: { type: Boolean },
},
{
rawName: '--no-cleanup',
description: 'Skip cleaning the `node_modules` directory',
Expand Down Expand Up @@ -122,53 +132,28 @@ function resolveCliOptions(options: CliOptions): Options {
skipTests: !options.tests,
skipBuild: !options.build,
registries: options.registry?.split(','),
skipPrerequisitesCheck: !options.preCheck,
skipConditionsCheck: !options.conditionCheck,
};
}

cli
.command('[version]')
.action(async (versionArg, options: Omit<CliOptions, 'version'>) => {
.action(async (nextVersion, options: Omit<CliOptions, 'version'>) => {
console.clear();

const currentVersion = await version();
let nextVersion = versionArg;

if (!nextVersion) {
nextVersion = (
await prompt<{ version: string }>({
type: 'select',
choices: RELEASE_TYPES.map((releaseType) => {
const increasedVersion = new SemVer(currentVersion)
.inc(releaseType)
.toString();

return {
message: `${releaseType} ${c.dim(increasedVersion)}`,
name: increasedVersion,
};
}).concat([
{ message: 'Custom version (specify)', name: 'specific' },
]),
message: 'Select SemVer increment or specify new version',
name: 'version',
})
).version;
const context = {
version: nextVersion,
tag: options.tag,
};

if (nextVersion === 'specific') {
nextVersion = (
await prompt<{ version: string }>({
type: 'input',
message: 'Version',
name: 'version',
})
).version;
}
}
await requiredMissingInformationTasks().run(context);

await pubm(
resolveCliOptions({
...options,
version: nextVersion,
version: context.version,
tag: context.tag,
}),
);
});
Expand Down
19 changes: 12 additions & 7 deletions src/registry/npm.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { exec } from 'tinyexec';
import { Registry } from './registry.js';

// const NPM_DEFAULT_REGISTRIES = new Set([
// // https://docs.npmjs.com/cli/v10/using-npm/registry
// 'https://registry.npmjs.org',
// // https://docs.npmjs.com/cli/v10/commands/npm-profile#registry
// 'https://registry.npmjs.org/',
// ]);

export class NpmRegistry extends Registry {
constructor(public packageName: string) {
super();
}

async npm(args: string[]) {
return (await exec('npm', args, { throwOnError: true })).stdout;
}

async distTags() {
return Object.keys(
JSON.parse(
await this.npm(['view', this.packageName, 'dist-tags', '--json']),
),
);
}

async checkPermission() {
return '';
}
Expand Down
1 change: 1 addition & 0 deletions src/registry/registry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export abstract class Registry {
abstract ping(): Promise<boolean>;
abstract distTags(): Promise<string[]>;
abstract getVersion(): Promise<string>;
abstract publish(): Promise<boolean>;
}
4 changes: 2 additions & 2 deletions src/tasks/jsr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const jsrPubmTasks: ListrTask<Ctx> = {
.prompt(ListrEnquirerPromptAdapter)
.run<boolean>({
type: 'password',
message: 'jsr OTP code: ',
message: 'jsr OTP code',
});

if (response === '123123') throw new Error('error');
Expand All @@ -35,7 +35,7 @@ export const jsrPubmTasks: ListrTask<Ctx> = {
.prompt(ListrEnquirerPromptAdapter)
.run<boolean>({
type: 'password',
message: 'jsr OTP code: ',
message: 'jsr OTP code',
});

resolve();
Expand Down
4 changes: 2 additions & 2 deletions src/tasks/npm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const npmPubmTasks: ListrTask<Ctx> = {
.prompt(ListrEnquirerPromptAdapter)
.run<boolean>({
type: 'password',
message: 'npm OTP code: ',
message: 'npm OTP code',
});

if (response === '123123') throw new Error('asd');
Expand All @@ -35,7 +35,7 @@ export const npmPubmTasks: ListrTask<Ctx> = {
.prompt(ListrEnquirerPromptAdapter)
.run<boolean>({
type: 'password',
message: 'npm OTP code: ',
message: 'npm OTP code',
});

resolve();
Expand Down
68 changes: 54 additions & 14 deletions src/tasks/prerequisites-check.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,57 @@
import { type ListrTask, delay } from 'listr2';
import { Listr, type ListrTask, delay } from 'listr2';
import type { Ctx } from './runner.js';

export const prerequisitesCheckTask: ListrTask<Ctx> = {
title: 'Prerequisites check (for deployment reliability)',
task: (_, parentTask) =>
parentTask.newListr([
{
title: 'prerequisite 1',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
export const prerequisitesCheckTask: (
options?: Omit<ListrTask<Ctx>, 'title' | 'task'>,
) => Listr<Ctx> = (options) =>
new Listr({
...options,
exitOnError: true,
title: 'Prerequisites check (for deployment reliability)',
task: (_, parentTask) =>
parentTask.newListr([
{
title: 'Checking if remote history is clean',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
exitOnError: true,
},
]),
};
{
title: 'Checking if the local working tree is clean',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
{
title: 'Checking if commits exist since the last release',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
{
title: 'Confirming new files and new dependencies',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
{
title: 'Checking if the package has never been deployed',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
{
skip: () => true,
title: 'Checking package name availability',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
]),
});
93 changes: 79 additions & 14 deletions src/tasks/required-conditions-check.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,82 @@
import { type ListrTask, delay } from 'listr2';
import { Listr, type ListrTask, delay } from 'listr2';
import type { Ctx } from './runner.js';

export const requiredConditionsCheckTask: ListrTask<Ctx> = {
title: 'Required conditions check (for pubm tasks)',
task: (_, parentTask) =>
parentTask.newListr([
{
title: 'prerequisite 1 ',
task: async () => {
// console.log('All good');
await delay(1000);
export const requiredConditionsCheckTask: (
options?: Omit<ListrTask<Ctx>, 'title' | 'task'>,
) => Listr<Ctx> = (options) =>
new Listr({
...options,
title: 'Required conditions check (for pubm tasks)',
task: (_, parentTask) =>
parentTask.newListr(
[
{
title: 'Ping registries',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
{
title: 'Checking if test and build scripts exist',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
{
title: 'Checking package manager version',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
{
skip: () => true,
title: 'Verifying user authentication',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
{
title: 'Checking git version',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
{
title: 'Checking git remote',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
{
title: 'Checking git tag existence',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
{
title: 'Verifying current branch is a release branch',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
{
title: 'Checking if registry cli are installed',
task: async (_, task) => {
task.output = 'All good';
await delay(1000);
},
},
],
{
concurrent: true,
},
exitOnError: true,
},
]),
};
),
});
Loading

0 comments on commit 521a391

Please sign in to comment.