ekohacks 0.5.0 → 0.5.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.
@@ -15,11 +15,15 @@ export class GhWrapper {
15
15
  });
16
16
  }));
17
17
  }
18
- static createNull({ prNumber = 1, checkRounds = [[]], waitingRunRounds = [undefined], runRounds = [{ concluded: true, passed: true, url: 'https://github.com/nulled/nulled' }], } = {}) {
18
+ static createNull({ prNumber = 1, checkRounds = [[]], waitingRunRounds = [undefined], runRounds = [{ concluded: true, passed: true, url: 'https://github.com/nulled/nulled' }], existingReleases = [], } = {}) {
19
19
  let round = 0;
20
20
  let runRound = 0;
21
21
  let waitingRound = 0;
22
22
  return new GhWrapper((args) => {
23
+ if (args[0] === 'release' && args[1] === 'view') {
24
+ const exists = existingReleases.includes(args[2] ?? '');
25
+ return Promise.resolve({ exitCode: exists ? 0 : 1, stdout: '', stderr: '' });
26
+ }
23
27
  if (args[0] === 'run' && args[1] === 'view') {
24
28
  const index = Math.min(runRound, runRounds.length - 1);
25
29
  runRound += 1;
@@ -197,6 +201,12 @@ export class GhWrapper {
197
201
  this.releaseTrackers.push(tracker);
198
202
  return { data: tracker };
199
203
  }
204
+ // gh release view exits 0 when the release exists and non-zero when it does not, the same
205
+ // shape branchExists reads from git, so existence is in the exit code, not the output.
206
+ async releaseExists(tag) {
207
+ const result = await this.runGh(['release', 'view', tag]);
208
+ return result.exitCode === 0;
209
+ }
200
210
  async createRelease(options) {
201
211
  const result = await this.runGh([
202
212
  'release',
@@ -15,12 +15,20 @@ export const ship = async ({ version, changelog, pkg, gh, git, npm, confirm, con
15
15
  };
16
16
  }
17
17
  const tag = `v${version}`;
18
- if (!(await confirmRelease(`cut release ${tag}?`))) {
19
- return { stopped: 'release not approved' };
18
+ // A Release already cut is the resume point: the publish is stalled behind its gate, so step
19
+ // over the cut the confirm has nothing to confirm and the create would 422 — and pick up at
20
+ // the gate. The gate's own confirm still asks, so resuming approves nothing a human did not.
21
+ if (await gh.releaseExists(tag)) {
22
+ narrate(`release ${tag} already cut`);
23
+ }
24
+ else {
25
+ if (!(await confirmRelease(`cut release ${tag}?`))) {
26
+ return { stopped: 'release not approved' };
27
+ }
28
+ const notes = changelogEntryFor(changelog, version) ?? '';
29
+ await gh.createRelease({ tag, title: tag, notes });
30
+ narrate(`release ${tag} cut`);
20
31
  }
21
- const notes = changelogEntryFor(changelog, version) ?? '';
22
- await gh.createRelease({ tag, title: tag, notes });
23
- narrate(`release ${tag} cut`);
24
32
  // The run takes a few seconds to appear after the release event, so a miss here is
25
33
  // usually the race, not a missing workflow: ask again briefly before giving up.
26
34
  let waiting = await gh.waitingRun(workflow);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ekohacks",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "The EkoHacks CLI: our everyday operations, automated one small command at a time.",
5
5
  "repository": {
6
6
  "type": "git",