@theholocron/holocron-plugin-github 5.0.0-alpha.380 → 5.0.0-alpha.381
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/index.d.mts +2 -2
- package/dist/index.mjs +40 -16
- package/package.json +6 -6
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AddedItem, Auth, AuthError, BoardItem, BoardItemInput, BoardState, BoardSummary, BoardTemplate, Ci, CiRun, CiRunFilter, EnsureReport, Environment, Environments, ImportOptions, ImportResult, Issue, IssueRecord, IssueSearchFilter, IssueSelector, Issues, LabelDef, LifecycleResult, LifecycleSlot, MoveReport, PagesConfig, PluginToken, Projects, PullRequest, RepoRef, RepoSettings, ResolveTokenInput, Ruleset, SecretScope, Secrets, Source, SourceBranch, SourceFile, SourceRepoInfo, SourceRulesetDetail, SourceSecurity, SourceTeamMember, SyncResult, TeamEntry, TeamEntry as TeamEntry$1, TeamPermission, TeamPermission as TeamPermission$1, TrackerDoctorReport, TrackerUser, VerifyTokenFailure, VerifyTokenResult, VerifyTokenResult as VerifyTokenResult$1, VerifyTokenSuccess, createFeatureResolver } from "@theholocron/cli";
|
|
1
|
+
import { AddedItem, Auth, AuthError, BoardItem, BoardItemInput, BoardState, BoardSummary, BoardTemplate, Ci, CiRun, CiRunFilter, EnsureReport, Environment, Environments, ExportInfo, ImportOptions, ImportResult, Issue, IssueRecord, IssueSearchFilter, IssueSelector, Issues, LabelDef, LifecycleResult, LifecycleSlot, MoveReport, PagesConfig, PluginToken, Projects, PullRequest, RepoRef, RepoSettings, ResolveTokenInput, Ruleset, SecretScope, Secrets, Source, SourceBranch, SourceFile, SourceRepoInfo, SourceRulesetDetail, SourceSecurity, SourceTeamMember, SyncResult, TeamEntry, TeamEntry as TeamEntry$1, TeamPermission, TeamPermission as TeamPermission$1, TrackerDoctorReport, TrackerUser, VerifyTokenFailure, VerifyTokenResult, VerifyTokenResult as VerifyTokenResult$1, VerifyTokenSuccess, createFeatureResolver } from "@theholocron/cli";
|
|
2
2
|
import { GitHubClient, GitHubClientOptions, GraphQLClient, createGitHubClient } from "@theholocron/github-client";
|
|
3
3
|
/** Resolves the token for read-only GitHub access (`HOLOCRON_READ_TOKEN`, keyring key `github.read`). */
|
|
4
4
|
export declare const resolveReadToken: import("@theholocron/cli").FeatureResolver;
|
|
@@ -105,7 +105,7 @@ export declare class GitHubIssues implements Issues {
|
|
|
105
105
|
/** Checks the authenticated user, the repo and the label-backed lifecycle slots, and reports what resolves. */
|
|
106
106
|
doctor(): Promise<TrackerDoctorReport>;
|
|
107
107
|
/** Reads issues with their comments, priority label, parent and blockers, for `holocron migrate`. */
|
|
108
|
-
export(selector: IssueSelector): Promise<IssueRecord[]>;
|
|
108
|
+
export(selector: IssueSelector, info?: ExportInfo): Promise<IssueRecord[]>;
|
|
109
109
|
/** Makes the records as issues; one already made by an earlier run is skipped. */
|
|
110
110
|
import(records: IssueRecord[], options?: ImportOptions): Promise<ImportResult[]>;
|
|
111
111
|
/** Like `import`, and it also updates what an earlier import or sync made, for `holocron sync issues`. */
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import { AuthError, MissingTokenError, ProviderApiError, connectionProbe, createFeatureResolver } from "@theholocron/cli";
|
|
2
|
+
import { AuthError, MissingTokenError, ProviderApiError, connectionProbe, createFeatureResolver, pickByCreation, readKeysLimited } from "@theholocron/cli";
|
|
3
3
|
import { createGitHubClient, createGitHubClient as createGitHubClient$1 } from "@theholocron/github-client";
|
|
4
4
|
import { mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
@@ -209,24 +209,48 @@ function explainSecondaryLimit(err) {
|
|
|
209
209
|
if (err instanceof ProviderApiError && (err.status === 403 || err.status === 429) && String(err.details).includes("secondary rate limit")) return /* @__PURE__ */ new Error("GitHub's secondary rate limit stopped the export. It limits bursts of requests, not the hourly quota, and nothing has been written. Wait a couple of minutes and run the command again.");
|
|
210
210
|
return err;
|
|
211
211
|
}
|
|
212
|
-
/**
|
|
213
|
-
|
|
214
|
-
|
|
212
|
+
/**
|
|
213
|
+
* Reads the issues `selector` names, with their comments, priority label, parent and blockers.
|
|
214
|
+
*
|
|
215
|
+
* With `limit`, only that many survivors of the other filters are read, from the `order` end of the creation order. A
|
|
216
|
+
* list of keys is sorted by issue number (which rises with creation in one repository) before anything is fetched, then
|
|
217
|
+
* fetched a few at a time until enough are kept; a listing already carries `created_at`, so it is cut before the
|
|
218
|
+
* per-issue comment and link requests. `info.matched` receives how many the selection matched before the cut.
|
|
219
|
+
*/
|
|
220
|
+
async function exportIssues(client, repo, selector, info = {}) {
|
|
221
|
+
return readIssues(client, repo, selector, info).catch((err) => {
|
|
215
222
|
throw explainSecondaryLimit(err);
|
|
216
223
|
});
|
|
217
224
|
}
|
|
218
|
-
async function readIssues(client, repo, selector) {
|
|
225
|
+
async function readIssues(client, repo, selector, info) {
|
|
219
226
|
const [owner = "", name = ""] = repo.split("/", 2);
|
|
220
|
-
let raw;
|
|
221
|
-
if (selector.keys) raw = await mapLimit(selector.keys, EXPORT_CONCURRENCY, (k) => client.issues.getIssue(repo, parseNumber(k)));
|
|
222
|
-
else if (selector.milestone) {
|
|
223
|
-
const milestone = await findMilestone(client, repo, selector.milestone);
|
|
224
|
-
if (!milestone) throw new Error(`Milestone "${selector.milestone}" not found in ${repo}.`);
|
|
225
|
-
raw = await listAll(client, repo, { milestone: String(milestone.number) });
|
|
226
|
-
} else if (selector.all) raw = await listAll(client, repo, {});
|
|
227
|
-
else throw new Error("export needs keys, a milestone or all");
|
|
228
227
|
const since = selector.since ? Date.parse(selector.since) : void 0;
|
|
229
|
-
const
|
|
228
|
+
const survives = (i) => !i.pull_request && !(selector.openOnly && i.state === "closed") && (since === void 0 || Date.parse(i.updated_at) >= since);
|
|
229
|
+
const { limit, order = "oldest" } = selector;
|
|
230
|
+
let issues;
|
|
231
|
+
if (selector.keys) {
|
|
232
|
+
const fetch = (k) => client.issues.getIssue(repo, parseNumber(k));
|
|
233
|
+
info.matched = selector.keys.length;
|
|
234
|
+
issues = limit === void 0 ? (await mapLimit(selector.keys, EXPORT_CONCURRENCY, fetch)).filter(survives) : await readKeysLimited({
|
|
235
|
+
keys: selector.keys,
|
|
236
|
+
order,
|
|
237
|
+
limit,
|
|
238
|
+
concurrency: EXPORT_CONCURRENCY,
|
|
239
|
+
fetch,
|
|
240
|
+
keep: survives
|
|
241
|
+
});
|
|
242
|
+
} else {
|
|
243
|
+
let raw;
|
|
244
|
+
if (selector.milestone) {
|
|
245
|
+
const milestone = await findMilestone(client, repo, selector.milestone);
|
|
246
|
+
if (!milestone) throw new Error(`Milestone "${selector.milestone}" not found in ${repo}.`);
|
|
247
|
+
raw = await listAll(client, repo, { milestone: String(milestone.number) });
|
|
248
|
+
} else if (selector.all) raw = await listAll(client, repo, {});
|
|
249
|
+
else throw new Error("export needs keys, a milestone or all");
|
|
250
|
+
issues = raw.filter(survives);
|
|
251
|
+
info.matched = issues.length;
|
|
252
|
+
if (limit !== void 0) issues = pickByCreation(issues, (i) => i.created_at ?? i.updated_at, order, limit);
|
|
253
|
+
}
|
|
230
254
|
const records = [];
|
|
231
255
|
for (const issue of issues) {
|
|
232
256
|
const comments = await client.issues.listComments(repo, issue.number);
|
|
@@ -628,8 +652,8 @@ var GitHubIssues = class {
|
|
|
628
652
|
};
|
|
629
653
|
}
|
|
630
654
|
/** Reads issues with their comments, priority label, parent and blockers, for `holocron migrate`. */
|
|
631
|
-
export(selector) {
|
|
632
|
-
return exportIssues(this.client, this.repo, selector);
|
|
655
|
+
export(selector, info) {
|
|
656
|
+
return exportIssues(this.client, this.repo, selector, info);
|
|
633
657
|
}
|
|
634
658
|
/** Makes the records as issues; one already made by an earlier run is skipped. */
|
|
635
659
|
import(records, options) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/holocron-plugin-github",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.381",
|
|
4
4
|
"description": "Holocron plugin for GitHub. Implements source, ci, secrets, environments, and issues capabilities against the GitHub REST API.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ci",
|
|
@@ -44,13 +44,13 @@
|
|
|
44
44
|
"tsx": "4.23.15",
|
|
45
45
|
"typescript": "^5.9.3",
|
|
46
46
|
"vitest": "^5.1.0",
|
|
47
|
-
"@theholocron/cli": "5.0.0-alpha.
|
|
48
|
-
"@theholocron/
|
|
47
|
+
"@theholocron/cli": "5.0.0-alpha.381",
|
|
48
|
+
"@theholocron/eslint-config": "^8.9.0-alpha.12",
|
|
49
49
|
"@theholocron/fs-utils": "^1.17.0-alpha.2",
|
|
50
|
+
"@theholocron/github-client": "^1.58.0-alpha.22",
|
|
51
|
+
"@theholocron/misc-utils": "^1.17.0-alpha.2",
|
|
50
52
|
"@theholocron/http-client": "^1.58.0-alpha.22",
|
|
51
|
-
"@theholocron/eslint-config": "^8.9.0-alpha.12",
|
|
52
53
|
"@theholocron/tsconfig": "^8.9.0-alpha.12",
|
|
53
|
-
"@theholocron/misc-utils": "^1.17.0-alpha.2",
|
|
54
54
|
"@theholocron/vitest-config": "^8.9.0-alpha.12",
|
|
55
55
|
"@theholocron/tsdown-config": "^8.9.0-alpha.12"
|
|
56
56
|
},
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"@theholocron/fs-utils": "^1.16.0",
|
|
59
59
|
"@theholocron/github-client": "^1.58.0",
|
|
60
60
|
"@theholocron/misc-utils": "^1.16.0",
|
|
61
|
-
"@theholocron/cli": "5.0.0-alpha.
|
|
61
|
+
"@theholocron/cli": "5.0.0-alpha.381"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
64
|
"node": ">=22"
|