bstack 0.2.2 → 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/README.md +14 -26
- package/dist/bstack.js +15 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
# bstack
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Convert series of commits in a local branch into native GitHub stacked pull requests.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g bstack
|
|
9
|
+
```
|
|
8
10
|
|
|
9
|
-
-
|
|
10
|
-
- `gh cli` plus the `github/gh-stack` extension (authenticated)
|
|
11
|
+
Install and authenticate the GitHub CLI with the `github/gh-stack` extension:
|
|
11
12
|
|
|
12
|
-
```
|
|
13
|
+
```
|
|
14
|
+
gh auth login
|
|
13
15
|
gh extension install github/gh-stack
|
|
14
|
-
npm install bstack -g
|
|
15
16
|
```
|
|
16
17
|
|
|
17
18
|
## Use
|
|
18
19
|
|
|
19
|
-
Create one commit per
|
|
20
|
+
Create one commit per change, then publish the stack:
|
|
20
21
|
|
|
21
22
|
```bash
|
|
22
23
|
git switch -c my-feature
|
|
@@ -25,7 +26,9 @@ git commit -am "feat: add the API"
|
|
|
25
26
|
bstack
|
|
26
27
|
```
|
|
27
28
|
|
|
28
|
-
Run `bstack` again after amending or rebasing commits.
|
|
29
|
+
Run `bstack` again after amending or rebasing commits.
|
|
30
|
+
|
|
31
|
+
New PRs are ready for review by default. Pass `--draft` to create draft PRs.
|
|
29
32
|
|
|
30
33
|
Checkout a stack through one of its PRs:
|
|
31
34
|
|
|
@@ -34,24 +37,9 @@ bstack checkout 123
|
|
|
34
37
|
bstack checkout https://github.com/owner/repo/pull/123
|
|
35
38
|
```
|
|
36
39
|
|
|
37
|
-
The first publish adds a stable `Bstack-Id` trailer to each commit and rewrites their hashes. The working tree must be clean. Merge commits and signed commits that need trailers are not supported.
|
|
38
|
-
|
|
39
40
|
Use `--dry-run` to inspect without publishing and `--quiet` to hide progress logs.
|
|
40
41
|
|
|
41
|
-
##
|
|
42
|
-
|
|
43
|
-
Install dependencies and run the checks with pnpm:
|
|
42
|
+
## References
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
pnpm run type-check
|
|
48
|
-
pnpm test
|
|
49
|
-
pnpm run lint
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Build the Node.js CLI with tsdown:
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
pnpm run build
|
|
56
|
-
node dist/bstack.js --help
|
|
57
|
-
```
|
|
44
|
+
- [ezyang/ghstack](https://github.com/ezyang/ghstack)
|
|
45
|
+
- [github/gh-stack](https://github.com/github/gh-stack)
|
package/dist/bstack.js
CHANGED
|
@@ -5,7 +5,7 @@ import { randomUUID } from "node:crypto";
|
|
|
5
5
|
import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { dirname } from "node:path";
|
|
7
7
|
//#region package.json
|
|
8
|
-
var version = "0.
|
|
8
|
+
var version = "0.3.0";
|
|
9
9
|
//#endregion
|
|
10
10
|
//#region src/command.ts
|
|
11
11
|
var CommandError = class extends Error {
|
|
@@ -368,7 +368,7 @@ var GhPlatform = class {
|
|
|
368
368
|
]).stdout;
|
|
369
369
|
return normalizePullRequest(JSON.parse(raw));
|
|
370
370
|
}
|
|
371
|
-
createPullRequest(change, base,
|
|
371
|
+
createPullRequest(change, base, draft) {
|
|
372
372
|
const args = [
|
|
373
373
|
"pr",
|
|
374
374
|
"create",
|
|
@@ -381,13 +381,13 @@ var GhPlatform = class {
|
|
|
381
381
|
"--body",
|
|
382
382
|
change.body
|
|
383
383
|
];
|
|
384
|
-
if (
|
|
384
|
+
if (draft) args.push("--draft");
|
|
385
385
|
this.gh(args);
|
|
386
386
|
const created = this.pullRequestForBranch(change.remoteBranch);
|
|
387
387
|
if (!created) throw new Error(`GitHub did not return the PR created for ${change.remoteBranch}`);
|
|
388
388
|
return created;
|
|
389
389
|
}
|
|
390
|
-
linkStack(branches, base, remote,
|
|
390
|
+
linkStack(branches, base, remote, draft) {
|
|
391
391
|
const args = [
|
|
392
392
|
"stack",
|
|
393
393
|
"link",
|
|
@@ -396,18 +396,18 @@ var GhPlatform = class {
|
|
|
396
396
|
"--remote",
|
|
397
397
|
remote
|
|
398
398
|
];
|
|
399
|
-
if (
|
|
399
|
+
if (!draft) args.push("--open");
|
|
400
400
|
args.push(...branches);
|
|
401
401
|
this.gh(args);
|
|
402
402
|
}
|
|
403
|
-
appendToStack(stackNumber, branches, remote,
|
|
403
|
+
appendToStack(stackNumber, branches, remote, draft) {
|
|
404
404
|
const args = [
|
|
405
405
|
"stack",
|
|
406
406
|
"link",
|
|
407
407
|
"--remote",
|
|
408
408
|
remote
|
|
409
409
|
];
|
|
410
|
-
if (
|
|
410
|
+
if (!draft) args.push("--open");
|
|
411
411
|
args.push(String(stackNumber), ...branches);
|
|
412
412
|
this.gh(args);
|
|
413
413
|
}
|
|
@@ -554,20 +554,20 @@ function syncStack(repository, github, options) {
|
|
|
554
554
|
if (changes.length === 1) {
|
|
555
555
|
if (evolution.kind === "partial") reporter.progress("Updating this down-stack prefix while preserving higher pull requests");
|
|
556
556
|
reporter.progress(existing[0] ? "Using the existing pull request" : "Creating a pull request");
|
|
557
|
-
pullRequests = [existing[0] ?? github.createPullRequest(changes[0], base, options.
|
|
557
|
+
pullRequests = [existing[0] ?? github.createPullRequest(changes[0], base, options.draft)];
|
|
558
558
|
} else {
|
|
559
559
|
if (evolution.kind === "full") {
|
|
560
560
|
reporter.progress(`Linking ${changes.length} pull requests as a native GitHub stack`);
|
|
561
|
-
github.linkStack(changes.map((change) => change.remoteBranch), base, remote, options.
|
|
561
|
+
github.linkStack(changes.map((change) => change.remoteBranch), base, remote, options.draft);
|
|
562
562
|
} else if (evolution.kind === "rebuild") {
|
|
563
563
|
reporter.progress(`Rebuilding stack #${evolution.stackNumber} to insert pull requests`);
|
|
564
564
|
github.unstack(evolution.stackNumber);
|
|
565
565
|
try {
|
|
566
|
-
github.linkStack(changes.map((change) => change.remoteBranch), base, remote, options.
|
|
566
|
+
github.linkStack(changes.map((change) => change.remoteBranch), base, remote, options.draft);
|
|
567
567
|
} catch (error) {
|
|
568
568
|
reporter.progress("Rebuild failed; restoring the previous native GitHub stack");
|
|
569
569
|
try {
|
|
570
|
-
github.linkStack(previous.changes.map((change) => change.remoteBranch), base, remote,
|
|
570
|
+
github.linkStack(previous.changes.map((change) => change.remoteBranch), base, remote, true);
|
|
571
571
|
} catch (rollbackError) {
|
|
572
572
|
throw new Error(`Stack rebuild failed: ${errorMessage(error)}\nRestoring the previous stack also failed: ${errorMessage(rollbackError)}`);
|
|
573
573
|
}
|
|
@@ -575,7 +575,7 @@ function syncStack(repository, github, options) {
|
|
|
575
575
|
}
|
|
576
576
|
} else if (evolution.kind === "append") {
|
|
577
577
|
reporter.progress(`Appending ${evolution.branches.length} pull request${evolution.branches.length === 1 ? "" : "s"} to stack #${evolution.stackNumber}`);
|
|
578
|
-
github.appendToStack(evolution.stackNumber, evolution.branches, remote, options.
|
|
578
|
+
github.appendToStack(evolution.stackNumber, evolution.branches, remote, options.draft);
|
|
579
579
|
} else if (evolution.kind === "partial") reporter.progress("Updating this down-stack prefix while preserving higher pull requests");
|
|
580
580
|
else reporter.progress("The native GitHub stack already has the correct members");
|
|
581
581
|
pullRequests = changes.map((change, index) => {
|
|
@@ -673,7 +673,7 @@ Usage:
|
|
|
673
673
|
Options:
|
|
674
674
|
--base <branch> Stack trunk; defaults to the GitHub default branch
|
|
675
675
|
--remote <name> Git remote; defaults to remote.pushDefault or origin
|
|
676
|
-
--
|
|
676
|
+
--draft Create draft PRs instead of ready-for-review PRs
|
|
677
677
|
--dry-run Inspect the stack without rewriting commits or pushing
|
|
678
678
|
--quiet Hide progress logs; the final summary is still printed
|
|
679
679
|
--same-base Refuse checkout if it would change the current merge base
|
|
@@ -687,7 +687,7 @@ function main() {
|
|
|
687
687
|
options: {
|
|
688
688
|
base: { type: "string" },
|
|
689
689
|
remote: { type: "string" },
|
|
690
|
-
|
|
690
|
+
draft: {
|
|
691
691
|
type: "boolean",
|
|
692
692
|
default: false
|
|
693
693
|
},
|
|
@@ -746,7 +746,7 @@ function main() {
|
|
|
746
746
|
const result = syncStack(repository, github, {
|
|
747
747
|
base: values.base,
|
|
748
748
|
remote: values.remote,
|
|
749
|
-
|
|
749
|
+
draft: values.draft,
|
|
750
750
|
dryRun: values["dry-run"],
|
|
751
751
|
reporter
|
|
752
752
|
});
|