ekohacks 0.2.0 → 0.3.0
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 +1 -0
- package/dist/infrastructure/git.js +9 -1
- package/dist/logic/release.js +1 -0
- package/dist/logic/ship.js +12 -5
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -11,12 +11,13 @@ export class GitWrapper {
|
|
|
11
11
|
return stdout;
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
|
-
static createNull({ branch = 'main', dirty = false, behindOrigin = false, existingBranches = [], } = {}) {
|
|
14
|
+
static createNull({ branch = 'main', dirty = false, behindOrigin = false, existingBranches = [], versionOnMain = '0.0.0', } = {}) {
|
|
15
15
|
const outputs = {
|
|
16
16
|
'rev-parse --abbrev-ref HEAD': `${branch}\n`,
|
|
17
17
|
'status --porcelain': dirty ? ' M some-file.ts\n' : '',
|
|
18
18
|
'rev-parse main': behindOrigin ? 'local\n' : 'shared\n',
|
|
19
19
|
'rev-parse origin/main': 'shared\n',
|
|
20
|
+
'show origin/main:package.json': `${JSON.stringify({ version: versionOnMain })}\n`,
|
|
20
21
|
};
|
|
21
22
|
for (const existing of existingBranches) {
|
|
22
23
|
outputs[`branch --list ${existing}`] = ` ${existing}\n`;
|
|
@@ -38,6 +39,13 @@ export class GitWrapper {
|
|
|
38
39
|
async branchExists(branch) {
|
|
39
40
|
return (await this.runGit(['branch', '--list', branch])).trim() !== '';
|
|
40
41
|
}
|
|
42
|
+
// The version main carries on origin, not in this checkout: the Release targets
|
|
43
|
+
// GitHub's main, so a stale local package.json must not answer for it.
|
|
44
|
+
async versionOnMain() {
|
|
45
|
+
await this.runGit(['fetch', 'origin', 'main']);
|
|
46
|
+
const manifest = await this.runGit(['show', 'origin/main:package.json']);
|
|
47
|
+
return JSON.parse(manifest).version;
|
|
48
|
+
}
|
|
41
49
|
async mainInSyncWithOrigin() {
|
|
42
50
|
await this.runGit(['fetch', 'origin', 'main']);
|
|
43
51
|
const local = (await this.runGit(['rev-parse', 'main'])).trim();
|
package/dist/logic/release.js
CHANGED
package/dist/logic/ship.js
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
2
2
|
import { changelogEntryFor } from './changelog.js';
|
|
3
3
|
import { GhWrapper } from '../infrastructure/gh.js';
|
|
4
|
+
import { GitWrapper } from '../infrastructure/git.js';
|
|
4
5
|
import { NpmWrapper } from '../infrastructure/npm.js';
|
|
5
|
-
// The tail of RELEASING.md as a policy: cut
|
|
6
|
-
// gate, follow the run to green, and only
|
|
7
|
-
//
|
|
8
|
-
// confirm answering yes.
|
|
9
|
-
export const ship = async ({ version, changelog, pkg, gh, npm, confirm, confirmRelease = () => Promise.resolve(true), narrate, pollDelayMs = 15_000, findRunAttempts = 8, registryAttempts = 20, workflow = 'publish.yml', }) => {
|
|
6
|
+
// The tail of RELEASING.md as a policy: refuse a cut that has not landed on main, cut
|
|
7
|
+
// the GitHub Release, approve the publish gate, follow the run to green, and only
|
|
8
|
+
// report success once the registry serves the version. The one human decision stays
|
|
9
|
+
// human: the gate is never approved without the confirm answering yes.
|
|
10
|
+
export const ship = async ({ version, changelog, pkg, gh, git, npm, confirm, confirmRelease = () => Promise.resolve(true), narrate, pollDelayMs = 15_000, findRunAttempts = 8, registryAttempts = 20, workflow = 'publish.yml', }) => {
|
|
11
|
+
const onMain = await git.versionOnMain();
|
|
12
|
+
if (onMain !== version) {
|
|
13
|
+
return {
|
|
14
|
+
stopped: `main carries ${onMain ?? 'no version'}, not ${version}: the cut looks unfinished, run ekohacks release cut ${version}`,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
10
17
|
const tag = `v${version}`;
|
|
11
18
|
if (!(await confirmRelease(`cut release ${tag}?`))) {
|
|
12
19
|
return { stopped: 'release not approved' };
|