ekohacks 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +11 -2
- package/dist/logic/cut.js +6 -1
- package/dist/logic/release.js +2 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// The thin shell: read the repo's files, wire the real wrappers, print one line per
|
|
3
3
|
// check and per step, exit 0 only when the command ran to its end. Everything worth
|
|
4
4
|
// testing lives below.
|
|
5
|
-
import { readFileSync } from 'node:fs';
|
|
5
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
6
6
|
import { createInterface } from 'node:readline/promises';
|
|
7
7
|
import { GhWrapper } from './infrastructure/gh.js';
|
|
8
8
|
import { GitWrapper } from './infrastructure/git.js';
|
|
@@ -22,9 +22,16 @@ if (command !== 'release' || version === undefined) {
|
|
|
22
22
|
console.error('usage: ekohacks release [preflight|cut|ship] <version> [--yes]');
|
|
23
23
|
process.exit(2);
|
|
24
24
|
}
|
|
25
|
+
for (const file of ['CHANGELOG.md', 'package.json', 'package-lock.json']) {
|
|
26
|
+
if (!existsSync(file)) {
|
|
27
|
+
console.error(`stopped: no ${file} in this directory`);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
25
31
|
const read = (file) => readFileSync(file, 'utf8');
|
|
26
32
|
const changelog = read('CHANGELOG.md');
|
|
27
|
-
const
|
|
33
|
+
const manifest = JSON.parse(read('package.json'));
|
|
34
|
+
const pkg = manifest.name;
|
|
28
35
|
const confirm = async (question) => {
|
|
29
36
|
const readline = createInterface({ input: process.stdin, output: process.stdout });
|
|
30
37
|
const answer = await readline.question(`${question} (y/n) `);
|
|
@@ -45,6 +52,7 @@ if (subcommand === undefined) {
|
|
|
45
52
|
confirm,
|
|
46
53
|
narrate,
|
|
47
54
|
yes,
|
|
55
|
+
currentVersion: manifest.version,
|
|
48
56
|
});
|
|
49
57
|
if ('stopped' in result) {
|
|
50
58
|
console.error(`stopped: ${result.stopped}`);
|
|
@@ -91,6 +99,7 @@ const result = await cut({
|
|
|
91
99
|
npm: NpmWrapper.create(),
|
|
92
100
|
gh: GhWrapper.create(),
|
|
93
101
|
narrate,
|
|
102
|
+
currentVersion: manifest.version,
|
|
94
103
|
});
|
|
95
104
|
if ('stopped' in result) {
|
|
96
105
|
console.error(`stopped: ${result.stopped}`);
|
package/dist/logic/cut.js
CHANGED
|
@@ -7,11 +7,16 @@ import { NpmWrapper } from '../infrastructure/npm.js';
|
|
|
7
7
|
// release PR, wait for CI, merge on green. It refuses to start unless preflight passed,
|
|
8
8
|
// and every stop names the reason so a human can pick up by hand. The caller supplies the
|
|
9
9
|
// wrappers and hears each step through narrate.
|
|
10
|
-
export const cut = async ({ version, changelog, report, git, npm, gh, narrate, confirm = () => Promise.resolve(true), pollDelayMs = 15_000, }) => {
|
|
10
|
+
export const cut = async ({ version, changelog, report, git, npm, gh, narrate, confirm = () => Promise.resolve(true), currentVersion, pollDelayMs = 15_000, }) => {
|
|
11
11
|
const failed = report.checks.filter((check) => !check.passed);
|
|
12
12
|
if (failed.length > 0) {
|
|
13
13
|
return { stopped: `preflight failed: ${failed.map((check) => check.name).join(', ')}` };
|
|
14
14
|
}
|
|
15
|
+
if (currentVersion === version) {
|
|
16
|
+
return {
|
|
17
|
+
stopped: `package.json is already at ${version}: the cut looks finished, run ekohacks release ship ${version}`,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
15
20
|
const branch = `release/v${version}`;
|
|
16
21
|
if (await git.branchExists(branch)) {
|
|
17
22
|
return { stopped: `branch ${branch} already exists from an earlier cut` };
|
package/dist/logic/release.js
CHANGED
|
@@ -9,7 +9,7 @@ import { ProcessRunner } from '../infrastructure/process.js';
|
|
|
9
9
|
// the first failure with that stage's own reason. No stage's logic lives here — this
|
|
10
10
|
// policy only composes the three and decides which pauses --yes may skip: the merge and
|
|
11
11
|
// the Release. The gate always asks.
|
|
12
|
-
export const release = async ({ version, changelog, lockfile, pkg, git, npm, gh, runner, confirm, narrate, yes = false, pollDelayMs, findRunAttempts, registryAttempts, }) => {
|
|
12
|
+
export const release = async ({ version, changelog, lockfile, pkg, git, npm, gh, runner, confirm, narrate, yes = false, currentVersion, pollDelayMs, findRunAttempts, registryAttempts, }) => {
|
|
13
13
|
const report = await preflight({ version, changelog, npm, pkg, git, lockfile, runner });
|
|
14
14
|
for (const check of report.checks) {
|
|
15
15
|
narrate(check.passed ? `ok ${check.name}` : `FAIL ${check.name}: ${check.reason}`);
|
|
@@ -24,6 +24,7 @@ export const release = async ({ version, changelog, lockfile, pkg, git, npm, gh,
|
|
|
24
24
|
gh,
|
|
25
25
|
narrate,
|
|
26
26
|
confirm: skippable,
|
|
27
|
+
currentVersion,
|
|
27
28
|
pollDelayMs,
|
|
28
29
|
});
|
|
29
30
|
if ('stopped' in cutResult) {
|