@procedures/gh 0.0.0-stage → 0.2.3
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/LICENSE +21 -0
- package/README.md +51 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/module.d.ts +18 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +101 -0
- package/dist/module.js.map +1 -0
- package/dist/procedures/gh/index.d.ts +14 -0
- package/dist/procedures/gh/index.d.ts.map +1 -0
- package/dist/procedures/gh/index.js +14 -0
- package/dist/procedures/gh/index.js.map +1 -0
- package/dist/procedures/gh/issue/comment.d.ts +12 -0
- package/dist/procedures/gh/issue/comment.d.ts.map +1 -0
- package/dist/procedures/gh/issue/comment.js +14 -0
- package/dist/procedures/gh/issue/comment.js.map +1 -0
- package/dist/procedures/gh/issue/create.d.ts +12 -0
- package/dist/procedures/gh/issue/create.d.ts.map +1 -0
- package/dist/procedures/gh/issue/create.js +17 -0
- package/dist/procedures/gh/issue/create.js.map +1 -0
- package/dist/procedures/gh/issue/list.d.ts +12 -0
- package/dist/procedures/gh/issue/list.d.ts.map +1 -0
- package/dist/procedures/gh/issue/list.js +19 -0
- package/dist/procedures/gh/issue/list.js.map +1 -0
- package/dist/procedures/gh/issue/view.d.ts +12 -0
- package/dist/procedures/gh/issue/view.d.ts.map +1 -0
- package/dist/procedures/gh/issue/view.js +15 -0
- package/dist/procedures/gh/issue/view.js.map +1 -0
- package/dist/procedures/gh/pr/checks.d.ts +12 -0
- package/dist/procedures/gh/pr/checks.d.ts.map +1 -0
- package/dist/procedures/gh/pr/checks.js +23 -0
- package/dist/procedures/gh/pr/checks.js.map +1 -0
- package/dist/procedures/gh/pr/create.d.ts +12 -0
- package/dist/procedures/gh/pr/create.d.ts.map +1 -0
- package/dist/procedures/gh/pr/create.js +21 -0
- package/dist/procedures/gh/pr/create.js.map +1 -0
- package/dist/procedures/gh/pr/list.d.ts +13 -0
- package/dist/procedures/gh/pr/list.d.ts.map +1 -0
- package/dist/procedures/gh/pr/list.js +21 -0
- package/dist/procedures/gh/pr/list.js.map +1 -0
- package/dist/procedures/gh/pr/view.d.ts +12 -0
- package/dist/procedures/gh/pr/view.d.ts.map +1 -0
- package/dist/procedures/gh/pr/view.js +15 -0
- package/dist/procedures/gh/pr/view.js.map +1 -0
- package/dist/procedures/gh/release/list.d.ts +12 -0
- package/dist/procedures/gh/release/list.d.ts.map +1 -0
- package/dist/procedures/gh/release/list.js +14 -0
- package/dist/procedures/gh/release/list.js.map +1 -0
- package/dist/procedures/gh/release/view.d.ts +12 -0
- package/dist/procedures/gh/release/view.d.ts.map +1 -0
- package/dist/procedures/gh/release/view.js +16 -0
- package/dist/procedures/gh/release/view.js.map +1 -0
- package/dist/procedures/gh/run/list.d.ts +12 -0
- package/dist/procedures/gh/run/list.d.ts.map +1 -0
- package/dist/procedures/gh/run/list.js +21 -0
- package/dist/procedures/gh/run/list.js.map +1 -0
- package/dist/procedures/gh/run/rerun.d.ts +12 -0
- package/dist/procedures/gh/run/rerun.d.ts.map +1 -0
- package/dist/procedures/gh/run/rerun.js +17 -0
- package/dist/procedures/gh/run/rerun.js.map +1 -0
- package/dist/procedures/gh/run/view.d.ts +12 -0
- package/dist/procedures/gh/run/view.d.ts.map +1 -0
- package/dist/procedures/gh/run/view.js +15 -0
- package/dist/procedures/gh/run/view.js.map +1 -0
- package/dist/procedures/gh/shared.d.ts +30 -0
- package/dist/procedures/gh/shared.d.ts.map +1 -0
- package/dist/procedures/gh/shared.js +63 -0
- package/dist/procedures/gh/shared.js.map +1 -0
- package/dist/register.d.ts +6 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +8 -0
- package/dist/register.js.map +1 -0
- package/dist/types.d.ts +108 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/package.json +78 -3
- package/src/index.ts +3 -0
- package/src/module.ts +167 -0
- package/src/procedures/gh/index.ts +13 -0
- package/src/procedures/gh/issue/comment.ts +17 -0
- package/src/procedures/gh/issue/create.ts +19 -0
- package/src/procedures/gh/issue/list.ts +21 -0
- package/src/procedures/gh/issue/view.ts +19 -0
- package/src/procedures/gh/pr/checks.ts +25 -0
- package/src/procedures/gh/pr/create.ts +21 -0
- package/src/procedures/gh/pr/list.ts +22 -0
- package/src/procedures/gh/pr/view.ts +19 -0
- package/src/procedures/gh/release/list.ts +17 -0
- package/src/procedures/gh/release/view.ts +20 -0
- package/src/procedures/gh/run/list.ts +22 -0
- package/src/procedures/gh/run/rerun.ts +19 -0
- package/src/procedures/gh/run/view.ts +19 -0
- package/src/procedures/gh/shared.ts +75 -0
- package/src/register.ts +10 -0
- package/src/types.ts +124 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gh.issue.create procedure
|
|
3
|
+
*
|
|
4
|
+
* Open an issue
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ProcedureContext } from "@procedures/client";
|
|
8
|
+
import type { GhIssueCreateInput, GhIssueCreateOutput } from "../../../types.js";
|
|
9
|
+
import { ghArg, repoArgs, runGh, urlOf } from "../shared.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Open an issue
|
|
13
|
+
*/
|
|
14
|
+
export async function ghIssueCreate(input: GhIssueCreateInput, ctx: ProcedureContext): Promise<GhIssueCreateOutput> {
|
|
15
|
+
// --title and --body take their value as the next argument, so a value that starts with "-" is text
|
|
16
|
+
const args = ["issue", "create", "--title", input.title, "--body", input.body, ...repoArgs(input)];
|
|
17
|
+
for (const label of input.labels ?? []) args.push("--label", ghArg("label", label));
|
|
18
|
+
return { url: urlOf(await runGh(args, input, ctx)) };
|
|
19
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gh.issue.list procedure
|
|
3
|
+
*
|
|
4
|
+
* The issues of a repository
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ProcedureContext } from "@procedures/client";
|
|
8
|
+
import type { GhIssueListInput, GhIssueListOutput } from "../../../types.js";
|
|
9
|
+
import { ghArg, ghJson, listArgs, repoArgs } from "../shared.js";
|
|
10
|
+
|
|
11
|
+
const FIELDS = "number,title,state,url,author,labels,assignees,createdAt,updatedAt";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The issues of a repository
|
|
15
|
+
*/
|
|
16
|
+
export async function ghIssueList(input: GhIssueListInput, ctx: ProcedureContext): Promise<GhIssueListOutput> {
|
|
17
|
+
const args = ["issue", "list", "--json", FIELDS, "--state", input.state ?? "open", ...listArgs(input), ...repoArgs(input)];
|
|
18
|
+
if (input.label !== undefined) args.push("--label", ghArg("label", input.label));
|
|
19
|
+
if (input.author !== undefined) args.push("--author", ghArg("author", input.author));
|
|
20
|
+
return { items: await ghJson<Array<Record<string, unknown>>>(args, input, ctx) };
|
|
21
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gh.issue.view procedure
|
|
3
|
+
*
|
|
4
|
+
* One issue, with its comments
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ProcedureContext } from "@procedures/client";
|
|
8
|
+
import type { GhIssueViewInput, GhIssueViewOutput } from "../../../types.js";
|
|
9
|
+
import { ghArg, ghJson, repoArgs } from "../shared.js";
|
|
10
|
+
|
|
11
|
+
const FIELDS = "number,title,state,url,body,author,labels,assignees,comments,createdAt,updatedAt";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* One issue
|
|
15
|
+
*/
|
|
16
|
+
export async function ghIssueView(input: GhIssueViewInput, ctx: ProcedureContext): Promise<GhIssueViewOutput> {
|
|
17
|
+
const args = ["issue", "view", ghArg("issue", input.issue), "--json", FIELDS, ...repoArgs(input)];
|
|
18
|
+
return { item: await ghJson<Record<string, unknown>>(args, input, ctx) };
|
|
19
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gh.pr.checks procedure
|
|
3
|
+
*
|
|
4
|
+
* The checks of a pull request. gh exits with 8 while a check runs: that is a result, not a failure.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ProcedureContext } from "@procedures/client";
|
|
8
|
+
import type { GhPrChecksInput, GhPrChecksOutput } from "../../../types.js";
|
|
9
|
+
import { GhError, ghArg, ghJson, repoArgs } from "../shared.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The checks of a pull request
|
|
13
|
+
*/
|
|
14
|
+
export async function ghPrChecks(input: GhPrChecksInput, ctx: ProcedureContext): Promise<GhPrChecksOutput> {
|
|
15
|
+
const args = ["pr", "checks", ghArg("pr", input.pr), "--json", "name,state,bucket,link,workflow", ...repoArgs(input)];
|
|
16
|
+
try {
|
|
17
|
+
return { items: await ghJson<Array<Record<string, unknown>>>(args, input, ctx) };
|
|
18
|
+
} catch (error) {
|
|
19
|
+
// Exit 8: a check is pending. gh still prints the JSON on stdout, but runGh threw on the exit code
|
|
20
|
+
if (error instanceof GhError && error.exitCode === 8) {
|
|
21
|
+
throw new GhError("gh pr checks: a check is pending, ask again later", 8, error.stderr);
|
|
22
|
+
}
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gh.pr.create procedure
|
|
3
|
+
*
|
|
4
|
+
* Open a pull request
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ProcedureContext } from "@procedures/client";
|
|
8
|
+
import type { GhPrCreateInput, GhPrCreateOutput } from "../../../types.js";
|
|
9
|
+
import { ghArg, repoArgs, runGh, urlOf } from "../shared.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Open a pull request
|
|
13
|
+
*/
|
|
14
|
+
export async function ghPrCreate(input: GhPrCreateInput, ctx: ProcedureContext): Promise<GhPrCreateOutput> {
|
|
15
|
+
// --title and --body take their value as the next argument, so a value that starts with "-" is text
|
|
16
|
+
const args = ["pr", "create", "--title", input.title, "--body", input.body, ...repoArgs(input)];
|
|
17
|
+
if (input.base !== undefined) args.push("--base", ghArg("base", input.base));
|
|
18
|
+
if (input.head !== undefined) args.push("--head", ghArg("head", input.head));
|
|
19
|
+
if (input.draft) args.push("--draft");
|
|
20
|
+
return { url: urlOf(await runGh(args, input, ctx)) };
|
|
21
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gh.pr.list procedure
|
|
3
|
+
*
|
|
4
|
+
* The pull requests of a repository
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ProcedureContext } from "@procedures/client";
|
|
8
|
+
import type { GhPrListInput, GhPrListOutput } from "../../../types.js";
|
|
9
|
+
import { ghArg, ghJson, listArgs, repoArgs } from "../shared.js";
|
|
10
|
+
|
|
11
|
+
export const PR_FIELDS = "number,title,state,url,author,headRefName,baseRefName,isDraft,createdAt,updatedAt";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The pull requests of a repository
|
|
15
|
+
*/
|
|
16
|
+
export async function ghPrList(input: GhPrListInput, ctx: ProcedureContext): Promise<GhPrListOutput> {
|
|
17
|
+
const args = ["pr", "list", "--json", PR_FIELDS, "--state", input.state ?? "open", ...listArgs(input), ...repoArgs(input)];
|
|
18
|
+
if (input.author !== undefined) args.push("--author", ghArg("author", input.author));
|
|
19
|
+
if (input.base !== undefined) args.push("--base", ghArg("base", input.base));
|
|
20
|
+
if (input.head !== undefined) args.push("--head", ghArg("head", input.head));
|
|
21
|
+
return { items: await ghJson<Array<Record<string, unknown>>>(args, input, ctx) };
|
|
22
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gh.pr.view procedure
|
|
3
|
+
*
|
|
4
|
+
* One pull request
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ProcedureContext } from "@procedures/client";
|
|
8
|
+
import type { GhPrViewInput, GhPrViewOutput } from "../../../types.js";
|
|
9
|
+
import { ghArg, ghJson, repoArgs } from "../shared.js";
|
|
10
|
+
|
|
11
|
+
const FIELDS = "number,title,state,url,body,author,headRefName,baseRefName,isDraft,mergeable,reviewDecision,additions,deletions,changedFiles,createdAt,updatedAt";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* One pull request
|
|
15
|
+
*/
|
|
16
|
+
export async function ghPrView(input: GhPrViewInput, ctx: ProcedureContext): Promise<GhPrViewOutput> {
|
|
17
|
+
const args = ["pr", "view", ghArg("pr", input.pr), "--json", FIELDS, ...repoArgs(input)];
|
|
18
|
+
return { item: await ghJson<Record<string, unknown>>(args, input, ctx) };
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gh.release.list procedure
|
|
3
|
+
*
|
|
4
|
+
* The releases of a repository
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ProcedureContext } from "@procedures/client";
|
|
8
|
+
import type { GhReleaseListInput, GhReleaseListOutput } from "../../../types.js";
|
|
9
|
+
import { ghJson, listArgs, repoArgs } from "../shared.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The releases of a repository
|
|
13
|
+
*/
|
|
14
|
+
export async function ghReleaseList(input: GhReleaseListInput, ctx: ProcedureContext): Promise<GhReleaseListOutput> {
|
|
15
|
+
const args = ["release", "list", "--json", "tagName,name,isDraft,isPrerelease,isLatest,publishedAt,createdAt", ...listArgs(input), ...repoArgs(input)];
|
|
16
|
+
return { items: await ghJson<Array<Record<string, unknown>>>(args, input, ctx) };
|
|
17
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gh.release.view procedure
|
|
3
|
+
*
|
|
4
|
+
* One release: the release of a tag, or the latest release
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ProcedureContext } from "@procedures/client";
|
|
8
|
+
import type { GhReleaseViewInput, GhReleaseViewOutput } from "../../../types.js";
|
|
9
|
+
import { ghArg, ghJson, repoArgs } from "../shared.js";
|
|
10
|
+
|
|
11
|
+
const FIELDS = "tagName,name,body,url,isDraft,isPrerelease,publishedAt,createdAt,author,assets";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* One release
|
|
15
|
+
*/
|
|
16
|
+
export async function ghReleaseView(input: GhReleaseViewInput, ctx: ProcedureContext): Promise<GhReleaseViewOutput> {
|
|
17
|
+
const tag = input.tag === undefined ? [] : [ghArg("tag", input.tag)];
|
|
18
|
+
const args = ["release", "view", ...tag, "--json", FIELDS, ...repoArgs(input)];
|
|
19
|
+
return { item: await ghJson<Record<string, unknown>>(args, input, ctx) };
|
|
20
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gh.run.list procedure
|
|
3
|
+
*
|
|
4
|
+
* The workflow runs of a repository
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ProcedureContext } from "@procedures/client";
|
|
8
|
+
import type { GhRunListInput, GhRunListOutput } from "../../../types.js";
|
|
9
|
+
import { ghArg, ghJson, listArgs, repoArgs } from "../shared.js";
|
|
10
|
+
|
|
11
|
+
const FIELDS = "databaseId,workflowName,displayTitle,headBranch,headSha,event,status,conclusion,url,createdAt,updatedAt";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The workflow runs of a repository
|
|
15
|
+
*/
|
|
16
|
+
export async function ghRunList(input: GhRunListInput, ctx: ProcedureContext): Promise<GhRunListOutput> {
|
|
17
|
+
const args = ["run", "list", "--json", FIELDS, ...listArgs({ limit: input.limit ?? 20 }), ...repoArgs(input)];
|
|
18
|
+
if (input.workflow !== undefined) args.push("--workflow", ghArg("workflow", input.workflow));
|
|
19
|
+
if (input.branch !== undefined) args.push("--branch", ghArg("branch", input.branch));
|
|
20
|
+
if (input.status !== undefined) args.push("--status", ghArg("status", input.status));
|
|
21
|
+
return { items: await ghJson<Array<Record<string, unknown>>>(args, input, ctx) };
|
|
22
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gh.run.rerun procedure
|
|
3
|
+
*
|
|
4
|
+
* Run a workflow run again
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ProcedureContext } from "@procedures/client";
|
|
8
|
+
import type { GhRunRerunInput, GhRunRerunOutput } from "../../../types.js";
|
|
9
|
+
import { repoArgs, runGh } from "../shared.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Run a workflow run again
|
|
13
|
+
*/
|
|
14
|
+
export async function ghRunRerun(input: GhRunRerunInput, ctx: ProcedureContext): Promise<GhRunRerunOutput> {
|
|
15
|
+
const args = ["run", "rerun", String(input.run), ...repoArgs(input)];
|
|
16
|
+
if (input.failedOnly) args.push("--failed");
|
|
17
|
+
await runGh(args, input, ctx);
|
|
18
|
+
return { run: input.run };
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gh.run.view procedure
|
|
3
|
+
*
|
|
4
|
+
* One workflow run with its jobs
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ProcedureContext } from "@procedures/client";
|
|
8
|
+
import type { GhRunViewInput, GhRunViewOutput } from "../../../types.js";
|
|
9
|
+
import { ghJson, repoArgs } from "../shared.js";
|
|
10
|
+
|
|
11
|
+
const FIELDS = "databaseId,workflowName,displayTitle,headBranch,headSha,event,status,conclusion,url,createdAt,updatedAt,jobs";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* One workflow run with its jobs
|
|
15
|
+
*/
|
|
16
|
+
export async function ghRunView(input: GhRunViewInput, ctx: ProcedureContext): Promise<GhRunViewOutput> {
|
|
17
|
+
const args = ["run", "view", String(input.run), "--json", FIELDS, ...repoArgs(input)];
|
|
18
|
+
return { item: await ghJson<Record<string, unknown>>(args, input, ctx) };
|
|
19
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The way every gh procedure runs the GitHub CLI: an argument list through `shell.run`, no
|
|
3
|
+
* shell. A value that gh reads as an argument must not start with "-", so it cannot become an
|
|
4
|
+
* option. The output is the JSON of `--json` where gh has it.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ProcedureContext } from "@procedures/client";
|
|
8
|
+
import type { GhCommonInput } from "../../types.js";
|
|
9
|
+
|
|
10
|
+
/** The fields of a call of shell.run. */
|
|
11
|
+
interface ShellRunInput {
|
|
12
|
+
command: string;
|
|
13
|
+
args: string[];
|
|
14
|
+
cwd?: string;
|
|
15
|
+
timeout?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** A failed gh command: its exit code and its error text. */
|
|
19
|
+
export class GhError extends Error {
|
|
20
|
+
override readonly name = "GhError";
|
|
21
|
+
constructor(
|
|
22
|
+
message: string,
|
|
23
|
+
readonly exitCode: number,
|
|
24
|
+
readonly stderr: string,
|
|
25
|
+
) {
|
|
26
|
+
super(message);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** A value that gh reads as an argument (a branch, a tag, a title): it must not start with "-". */
|
|
31
|
+
export function ghArg(name: string, value: string): string {
|
|
32
|
+
if (value.startsWith("-")) throw new Error(`Invalid ${name} (starts with "-"): ${value}`);
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** The option `--repo owner/name`, when the input gives a repository. */
|
|
37
|
+
export function repoArgs(input: GhCommonInput): string[] {
|
|
38
|
+
return input.repo === undefined ? [] : ["--repo", ghArg("repo", input.repo)];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** This function runs `gh <args>` and gives its output. It throws a GhError for a failed command. */
|
|
42
|
+
export async function runGh(args: string[], input: GhCommonInput, ctx: ProcedureContext): Promise<string> {
|
|
43
|
+
const shellInput: ShellRunInput = { command: "gh", args };
|
|
44
|
+
if (input.cwd !== undefined) shellInput.cwd = input.cwd;
|
|
45
|
+
if (input.timeoutMs !== undefined) shellInput.timeout = input.timeoutMs;
|
|
46
|
+
const result = await ctx.client.call<ShellRunInput, { exitCode: number; stdout: string; stderr: string }>(["shell", "run"], shellInput);
|
|
47
|
+
if (result.exitCode !== 0) {
|
|
48
|
+
const text = result.stderr.trim() || result.stdout.trim();
|
|
49
|
+
throw new GhError(`gh ${args[0] ?? ""} ${args[1] ?? ""} failed (exit ${result.exitCode}): ${text}`.trim(), result.exitCode, result.stderr);
|
|
50
|
+
}
|
|
51
|
+
return result.stdout;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** This function runs gh with `--json` and gives the parsed value. */
|
|
55
|
+
export async function ghJson<T>(args: string[], input: GhCommonInput, ctx: ProcedureContext): Promise<T> {
|
|
56
|
+
const output = await runGh(args, input, ctx);
|
|
57
|
+
try {
|
|
58
|
+
return JSON.parse(output) as T;
|
|
59
|
+
} catch {
|
|
60
|
+
throw new GhError(`gh ${args[0] ?? ""} ${args[1] ?? ""} gave no JSON: ${output.slice(0, 200)}`, 0, "");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** The options of a list: its limit and a search. */
|
|
65
|
+
export function listArgs(input: { limit?: number | undefined; search?: string | undefined }): string[] {
|
|
66
|
+
const args = ["--limit", String(input.limit ?? 30)];
|
|
67
|
+
if (input.search !== undefined) args.push("--search", input.search);
|
|
68
|
+
return args;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** The last line of an output that is a URL: gh prints the URL of what it made. */
|
|
72
|
+
export function urlOf(output: string): string {
|
|
73
|
+
const lines = output.trim().split(/\r?\n/);
|
|
74
|
+
return lines.reverse().find((line) => line.startsWith("https://")) ?? lines[0] ?? "";
|
|
75
|
+
}
|
package/src/register.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Importing this file registers the procedures of @procedures/gh in the global registry:
|
|
3
|
+
* `import "@procedures/gh/register"`. The package root registers nothing.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { registerGhProcedures } from "./module.js";
|
|
7
|
+
|
|
8
|
+
export * from "./module.js";
|
|
9
|
+
|
|
10
|
+
registerGhProcedures();
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions of the procedures of this package
|
|
3
|
+
*
|
|
4
|
+
* mark procedure new adds the types of each new procedure here. The zod schemas are in
|
|
5
|
+
* `module.ts`: an exported schema needs a written type (isolatedDeclarations).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** The fields of each gh procedure. */
|
|
9
|
+
export interface GhCommonInput {
|
|
10
|
+
/** The repository as owner/name (default: the repository of the folder) */
|
|
11
|
+
repo?: string | undefined;
|
|
12
|
+
/** The folder where gh runs */
|
|
13
|
+
cwd?: string | undefined;
|
|
14
|
+
/** The time limit of the command, in milliseconds */
|
|
15
|
+
timeoutMs?: number | undefined;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** A list of the JSON objects that gh gives. */
|
|
19
|
+
export interface GhListOutput {
|
|
20
|
+
items: Array<Record<string, unknown>>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** One JSON object that gh gives. */
|
|
24
|
+
export interface GhItemOutput {
|
|
25
|
+
item: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** What gh made: its URL. */
|
|
29
|
+
export interface GhCreatedOutput {
|
|
30
|
+
url: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface GhPrListInput extends GhCommonInput {
|
|
34
|
+
state?: "open" | "closed" | "merged" | "all" | undefined;
|
|
35
|
+
author?: string | undefined;
|
|
36
|
+
base?: string | undefined;
|
|
37
|
+
head?: string | undefined;
|
|
38
|
+
search?: string | undefined;
|
|
39
|
+
limit?: number | undefined;
|
|
40
|
+
}
|
|
41
|
+
export type GhPrListOutput = GhListOutput;
|
|
42
|
+
|
|
43
|
+
export interface GhPrViewInput extends GhCommonInput {
|
|
44
|
+
/** The number, the branch or the URL of the pull request */
|
|
45
|
+
pr: string;
|
|
46
|
+
}
|
|
47
|
+
export type GhPrViewOutput = GhItemOutput;
|
|
48
|
+
|
|
49
|
+
export interface GhPrChecksInput extends GhCommonInput {
|
|
50
|
+
pr: string;
|
|
51
|
+
}
|
|
52
|
+
export type GhPrChecksOutput = GhListOutput;
|
|
53
|
+
|
|
54
|
+
export interface GhPrCreateInput extends GhCommonInput {
|
|
55
|
+
title: string;
|
|
56
|
+
body: string;
|
|
57
|
+
base?: string | undefined;
|
|
58
|
+
head?: string | undefined;
|
|
59
|
+
draft?: boolean | undefined;
|
|
60
|
+
}
|
|
61
|
+
export type GhPrCreateOutput = GhCreatedOutput;
|
|
62
|
+
|
|
63
|
+
export interface GhRunListInput extends GhCommonInput {
|
|
64
|
+
workflow?: string | undefined;
|
|
65
|
+
branch?: string | undefined;
|
|
66
|
+
status?: string | undefined;
|
|
67
|
+
limit?: number | undefined;
|
|
68
|
+
}
|
|
69
|
+
export type GhRunListOutput = GhListOutput;
|
|
70
|
+
|
|
71
|
+
export interface GhRunViewInput extends GhCommonInput {
|
|
72
|
+
/** The id of the run */
|
|
73
|
+
run: number;
|
|
74
|
+
}
|
|
75
|
+
export type GhRunViewOutput = GhItemOutput;
|
|
76
|
+
|
|
77
|
+
export interface GhRunRerunInput extends GhCommonInput {
|
|
78
|
+
run: number;
|
|
79
|
+
/** Only the jobs that failed */
|
|
80
|
+
failedOnly?: boolean | undefined;
|
|
81
|
+
}
|
|
82
|
+
export interface GhRunRerunOutput {
|
|
83
|
+
run: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface GhReleaseListInput extends GhCommonInput {
|
|
87
|
+
limit?: number | undefined;
|
|
88
|
+
}
|
|
89
|
+
export type GhReleaseListOutput = GhListOutput;
|
|
90
|
+
|
|
91
|
+
export interface GhReleaseViewInput extends GhCommonInput {
|
|
92
|
+
/** The tag of the release (default: the latest release) */
|
|
93
|
+
tag?: string | undefined;
|
|
94
|
+
}
|
|
95
|
+
export type GhReleaseViewOutput = GhItemOutput;
|
|
96
|
+
|
|
97
|
+
export interface GhIssueListInput extends GhCommonInput {
|
|
98
|
+
state?: "open" | "closed" | "all" | undefined;
|
|
99
|
+
label?: string | undefined;
|
|
100
|
+
author?: string | undefined;
|
|
101
|
+
search?: string | undefined;
|
|
102
|
+
limit?: number | undefined;
|
|
103
|
+
}
|
|
104
|
+
export type GhIssueListOutput = GhListOutput;
|
|
105
|
+
|
|
106
|
+
export interface GhIssueViewInput extends GhCommonInput {
|
|
107
|
+
/** The number or the URL of the issue */
|
|
108
|
+
issue: string;
|
|
109
|
+
}
|
|
110
|
+
export type GhIssueViewOutput = GhItemOutput;
|
|
111
|
+
|
|
112
|
+
export interface GhIssueCreateInput extends GhCommonInput {
|
|
113
|
+
title: string;
|
|
114
|
+
body: string;
|
|
115
|
+
labels?: string[] | undefined;
|
|
116
|
+
}
|
|
117
|
+
export type GhIssueCreateOutput = GhCreatedOutput;
|
|
118
|
+
|
|
119
|
+
export interface GhIssueCommentInput extends GhCommonInput {
|
|
120
|
+
/** The number or the URL of the issue or the pull request */
|
|
121
|
+
issue: string;
|
|
122
|
+
body: string;
|
|
123
|
+
}
|
|
124
|
+
export type GhIssueCommentOutput = GhCreatedOutput;
|