@theholocron/holocron-plugin-github 5.0.0-alpha.19 → 5.0.0-alpha.191
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 +13 -24
- package/dist/index.mjs +70 -24
- package/package.json +17 -13
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { GitHubClient, GitHubClientOptions, createGitHubClient } from "@theholocron/github-client";
|
|
2
|
-
import { Auth, AuthError, Ci, CiRun, CiRunFilter, Environment, Environments, Issue, IssueSearchFilter, Issues, LabelDef, LifecycleResult, LifecycleSlot, PagesConfig, PullRequest, RepoRef, RepoSettings, ResolveTokenInput, Ruleset, SecretScope, Secrets, Source, TeamEntry, TeamEntry as TeamEntry$1, TeamPermission, TrackerDoctorReport, TrackerUser, createFeatureResolver } from "@theholocron/cli";
|
|
2
|
+
import { Auth, AuthError, Ci, CiRun, CiRunFilter, Environment, Environments, Issue, IssueSearchFilter, Issues, LabelDef, LifecycleResult, LifecycleSlot, PagesConfig, PullRequest, RepoRef, RepoSettings, ResolveTokenInput, Ruleset, SecretScope, Secrets, Source, TeamEntry, TeamEntry as TeamEntry$1, TeamPermission, TrackerDoctorReport, TrackerUser, VerifyTokenFailure, VerifyTokenResult, VerifyTokenResult as VerifyTokenResult$1, VerifyTokenSuccess, createFeatureResolver } from "@theholocron/cli";
|
|
3
3
|
//#region src/auth.d.ts
|
|
4
4
|
declare const resolveReadToken: (input?: ResolveTokenInput) => string;
|
|
5
5
|
declare const resolveIssuesToken: (input?: ResolveTokenInput) => string;
|
|
6
6
|
declare const resolveSyncToken: (input?: ResolveTokenInput) => string;
|
|
7
7
|
declare const resolveReleaseToken: (input?: ResolveTokenInput) => string;
|
|
8
8
|
declare const resolveAdminToken: (input?: ResolveTokenInput) => string;
|
|
9
|
+
declare const resolveSecretsToken: (input?: ResolveTokenInput) => string;
|
|
9
10
|
declare const resolveDeployToken: (input?: ResolveTokenInput) => string;
|
|
10
11
|
declare const resolveOrgToken: (input?: ResolveTokenInput) => string;
|
|
11
12
|
//#endregion
|
|
@@ -106,9 +107,16 @@ interface SecretsOptions {
|
|
|
106
107
|
declare class GitHubSecrets implements Secrets {
|
|
107
108
|
private readonly client;
|
|
108
109
|
private readonly opts;
|
|
110
|
+
private readonly orgClient?;
|
|
109
111
|
readonly key: "secrets";
|
|
110
112
|
readonly providerName = "github";
|
|
111
|
-
|
|
113
|
+
/**
|
|
114
|
+
* `client` handles repo and environment scopes; `orgClient`, when given, handles
|
|
115
|
+
* the organization scope. They differ when a dedicated org-only token exists:
|
|
116
|
+
* it can write org secrets but not repo ones, and `github.admin` is the reverse.
|
|
117
|
+
*/
|
|
118
|
+
constructor(client: GitHubClient, opts: SecretsOptions, orgClient?: GitHubClient | undefined);
|
|
119
|
+
private clientFor;
|
|
112
120
|
listSecrets(scope: SecretScope): Promise<string[]>;
|
|
113
121
|
setSecret(scope: SecretScope, name: string, value: string): Promise<void>;
|
|
114
122
|
deleteSecret(scope: SecretScope, name: string): Promise<void>;
|
|
@@ -184,30 +192,11 @@ declare function syncTeams(client: GitHubClient, repo: string, teams: TeamEntry[
|
|
|
184
192
|
declare function encryptSecret(publicKeyBase64: string, value: string): Promise<string>;
|
|
185
193
|
//#endregion
|
|
186
194
|
//#region src/verify-token.d.ts
|
|
187
|
-
/**
|
|
188
|
-
* `verifyToken` — plugin-level export used by `holocron auth set` +
|
|
189
|
-
* `holocron auth check`. Hits `GET /user` and translates the response
|
|
190
|
-
* into the normalized `VerifyTokenResult` shape.
|
|
191
|
-
*
|
|
192
|
-
* Kept as a standalone function (not a capability method) so the auth
|
|
193
|
-
* command can call it without initializing the full plugin — plugin
|
|
194
|
-
* construction requires an already-resolved token, which is exactly
|
|
195
|
-
* what we don't have yet at bootstrap time.
|
|
196
|
-
*/
|
|
197
|
-
interface VerifyTokenSuccess {
|
|
198
|
-
ok: true;
|
|
199
|
-
subject: string;
|
|
200
|
-
}
|
|
201
|
-
interface VerifyTokenFailure {
|
|
202
|
-
ok: false;
|
|
203
|
-
message: string;
|
|
204
|
-
}
|
|
205
|
-
type VerifyTokenResult = VerifyTokenSuccess | VerifyTokenFailure;
|
|
206
195
|
interface VerifyTokenOptions {
|
|
207
196
|
baseUrl?: string;
|
|
208
197
|
fetch?: typeof fetch;
|
|
209
198
|
}
|
|
210
|
-
declare function verifyToken(token: string, opts?: VerifyTokenOptions): Promise<VerifyTokenResult>;
|
|
199
|
+
declare function verifyToken(token: string, opts?: VerifyTokenOptions): Promise<VerifyTokenResult$1>;
|
|
211
200
|
//#endregion
|
|
212
201
|
//#region src/index.d.ts
|
|
213
202
|
interface GitHubPluginOptions extends ResolveTokenInput {
|
|
@@ -233,7 +222,7 @@ interface PluginContext {
|
|
|
233
222
|
repoRoot: string;
|
|
234
223
|
}
|
|
235
224
|
declare function source(ctx: PluginContext, orgClient?: GitHubClient): Source;
|
|
236
|
-
declare function secrets(ctx: PluginContext): Secrets;
|
|
225
|
+
declare function secrets(ctx: PluginContext, orgClient?: GitHubClient): Secrets;
|
|
237
226
|
declare function environments(ctx: PluginContext): Environments;
|
|
238
227
|
declare function ci(ctx: PluginContext): Ci;
|
|
239
228
|
declare function issues(ctx: PluginContext): Issues;
|
|
@@ -253,4 +242,4 @@ declare function createPlugin(options: GitHubPluginOptions): {
|
|
|
253
242
|
*/
|
|
254
243
|
declare const AUTH_HINT: string;
|
|
255
244
|
//#endregion
|
|
256
|
-
export { AUTH_HINT, type Auth, AuthError, type CanonicalLabel, GitHubCi, type GitHubClientOptions, GitHubEnvironments, GitHubIssues, GitHubPluginOptions, GitHubSecrets, GitHubSource, type NormalizedTeamEntry, PluginContext, type ResolveTokenInput, type TeamEntry, type TeamPermission, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, ci, createFeatureResolver, createGitHubClient, createPlugin, encryptSecret, environments, issues, normalizeTeamEntry, resolveAdminToken, resolveDeployToken, resolveIssuesToken, resolveOrgToken, resolveReadToken, resolveReleaseToken, resolveSyncToken, secrets, source, syncLabels, syncTeams, verifyToken };
|
|
245
|
+
export { AUTH_HINT, type Auth, AuthError, type CanonicalLabel, GitHubCi, type GitHubClientOptions, GitHubEnvironments, GitHubIssues, GitHubPluginOptions, GitHubSecrets, GitHubSource, type NormalizedTeamEntry, PluginContext, type ResolveTokenInput, type TeamEntry, type TeamPermission, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, ci, createFeatureResolver, createGitHubClient, createPlugin, encryptSecret, environments, issues, normalizeTeamEntry, resolveAdminToken, resolveDeployToken, resolveIssuesToken, resolveOrgToken, resolveReadToken, resolveReleaseToken, resolveSecretsToken, resolveSyncToken, secrets, source, syncLabels, syncTeams, verifyToken };
|
package/dist/index.mjs
CHANGED
|
@@ -3,6 +3,8 @@ import { createGitHubClient, createGitHubClient as createGitHubClient$1 } from "
|
|
|
3
3
|
import { AuthError, createFeatureResolver } from "@theholocron/cli";
|
|
4
4
|
import { mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
|
+
import { findRootSync } from "@theholocron/fs-utils";
|
|
7
|
+
import { errorMessage } from "@theholocron/misc-utils";
|
|
6
8
|
//#region src/auth.ts
|
|
7
9
|
const resolveReadToken = createFeatureResolver({
|
|
8
10
|
envName: "HOLOCRON_READ_TOKEN",
|
|
@@ -24,6 +26,10 @@ const resolveAdminToken = createFeatureResolver({
|
|
|
24
26
|
envName: "HOLOCRON_ADMIN_TOKEN",
|
|
25
27
|
keyringKey: "github.admin"
|
|
26
28
|
});
|
|
29
|
+
const resolveSecretsToken = createFeatureResolver({
|
|
30
|
+
envName: "HOLOCRON_SECRETS_TOKEN",
|
|
31
|
+
keyringKey: "github.secrets"
|
|
32
|
+
});
|
|
27
33
|
const resolveDeployToken = createFeatureResolver({
|
|
28
34
|
envName: "HOLOCRON_DEPLOY_TOKEN",
|
|
29
35
|
keyringKey: "github.deploy"
|
|
@@ -374,27 +380,38 @@ async function encryptSecret(publicKeyBase64, value) {
|
|
|
374
380
|
var GitHubSecrets = class {
|
|
375
381
|
client;
|
|
376
382
|
opts;
|
|
383
|
+
orgClient;
|
|
377
384
|
key = "secrets";
|
|
378
385
|
providerName = "github";
|
|
379
|
-
|
|
386
|
+
/**
|
|
387
|
+
* `client` handles repo and environment scopes; `orgClient`, when given, handles
|
|
388
|
+
* the organization scope. They differ when a dedicated org-only token exists:
|
|
389
|
+
* it can write org secrets but not repo ones, and `github.admin` is the reverse.
|
|
390
|
+
*/
|
|
391
|
+
constructor(client, opts, orgClient) {
|
|
380
392
|
this.client = client;
|
|
381
393
|
this.opts = opts;
|
|
394
|
+
this.orgClient = orgClient;
|
|
395
|
+
}
|
|
396
|
+
clientFor(scope) {
|
|
397
|
+
return scope.kind === "organization" ? this.orgClient ?? this.client : this.client;
|
|
382
398
|
}
|
|
383
399
|
async listSecrets(scope) {
|
|
384
|
-
return this.
|
|
400
|
+
return this.clientFor(scope).secrets.listSecrets(this.opts.repo, toGHScope(scope));
|
|
385
401
|
}
|
|
386
402
|
async setSecret(scope, name, value) {
|
|
387
403
|
const ghScope = toGHScope(scope);
|
|
388
|
-
const
|
|
404
|
+
const client = this.clientFor(scope);
|
|
405
|
+
const pk = await client.secrets.getPublicKey(this.opts.repo, ghScope);
|
|
389
406
|
const body = {
|
|
390
407
|
encrypted_value: await encryptSecret(pk.key, value),
|
|
391
408
|
key_id: pk.key_id
|
|
392
409
|
};
|
|
393
410
|
if (scope.kind === "organization") body.visibility = "all";
|
|
394
|
-
await
|
|
411
|
+
await client.secrets.putSecret(this.opts.repo, ghScope, name, body);
|
|
395
412
|
}
|
|
396
413
|
async deleteSecret(scope, name) {
|
|
397
|
-
await this.
|
|
414
|
+
await this.clientFor(scope).secrets.deleteSecret(this.opts.repo, toGHScope(scope), name);
|
|
398
415
|
}
|
|
399
416
|
};
|
|
400
417
|
function toGHScope(scope) {
|
|
@@ -496,8 +513,11 @@ var GitHubSource = class {
|
|
|
496
513
|
this.owner = owner;
|
|
497
514
|
this.name = name;
|
|
498
515
|
this.repo = opts.repo;
|
|
499
|
-
this.repoRoot = opts.repoRoot
|
|
500
|
-
|
|
516
|
+
this.repoRoot = findRootSync(opts.repoRoot, ".git", {
|
|
517
|
+
fallback: "start",
|
|
518
|
+
realpath: true
|
|
519
|
+
});
|
|
520
|
+
this.workflowDir = join(this.repoRoot, ".github", "workflows");
|
|
501
521
|
this.orgClient = opts.orgClient;
|
|
502
522
|
this.baseUrl = opts.baseUrl;
|
|
503
523
|
this.fetchImpl = opts.fetch;
|
|
@@ -652,16 +672,6 @@ async function ensureDir(path) {
|
|
|
652
672
|
}
|
|
653
673
|
//#endregion
|
|
654
674
|
//#region src/verify-token.ts
|
|
655
|
-
/**
|
|
656
|
-
* `verifyToken` — plugin-level export used by `holocron auth set` +
|
|
657
|
-
* `holocron auth check`. Hits `GET /user` and translates the response
|
|
658
|
-
* into the normalized `VerifyTokenResult` shape.
|
|
659
|
-
*
|
|
660
|
-
* Kept as a standalone function (not a capability method) so the auth
|
|
661
|
-
* command can call it without initializing the full plugin — plugin
|
|
662
|
-
* construction requires an already-resolved token, which is exactly
|
|
663
|
-
* what we don't have yet at bootstrap time.
|
|
664
|
-
*/
|
|
665
675
|
async function verifyToken(token, opts = {}) {
|
|
666
676
|
const client = createGitHubClient({
|
|
667
677
|
token,
|
|
@@ -677,7 +687,7 @@ async function verifyToken(token, opts = {}) {
|
|
|
677
687
|
} catch (err) {
|
|
678
688
|
return {
|
|
679
689
|
ok: false,
|
|
680
|
-
message:
|
|
690
|
+
message: errorMessage(err)
|
|
681
691
|
};
|
|
682
692
|
}
|
|
683
693
|
}
|
|
@@ -692,8 +702,8 @@ function source(ctx, orgClient) {
|
|
|
692
702
|
fetch: ctx.options.fetch
|
|
693
703
|
});
|
|
694
704
|
}
|
|
695
|
-
function secrets(ctx) {
|
|
696
|
-
return new GitHubSecrets(ctx.client, { repo: ctx.repo });
|
|
705
|
+
function secrets(ctx, orgClient) {
|
|
706
|
+
return new GitHubSecrets(ctx.client, { repo: ctx.repo }, orgClient);
|
|
697
707
|
}
|
|
698
708
|
function environments(ctx) {
|
|
699
709
|
return new GitHubEnvironments(ctx.client, { repo: ctx.repo });
|
|
@@ -708,10 +718,11 @@ function issues(ctx) {
|
|
|
708
718
|
}
|
|
709
719
|
function createPlugin(options) {
|
|
710
720
|
function makeCtx(resolver) {
|
|
721
|
+
const token = resolver(options);
|
|
711
722
|
return {
|
|
712
723
|
options,
|
|
713
724
|
client: createGitHubClient$1({
|
|
714
|
-
token
|
|
725
|
+
token,
|
|
715
726
|
baseUrl: options.baseUrl,
|
|
716
727
|
fetch: options.fetch
|
|
717
728
|
}),
|
|
@@ -719,10 +730,45 @@ function createPlugin(options) {
|
|
|
719
730
|
repoRoot: options.repoRoot ?? process.cwd()
|
|
720
731
|
};
|
|
721
732
|
}
|
|
733
|
+
/** A token, or undefined when that feature token is simply not configured. */
|
|
734
|
+
function tryResolve(resolver) {
|
|
735
|
+
try {
|
|
736
|
+
return resolver(options);
|
|
737
|
+
} catch (err) {
|
|
738
|
+
if (err instanceof AuthError) return void 0;
|
|
739
|
+
throw err;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* Organization secrets need an org-resource-owner token (`github.secrets`);
|
|
744
|
+
* repo and environment secrets need `github.admin`. Each scope prefers its own
|
|
745
|
+
* token and falls back to the other, so a setup with only one of them keeps
|
|
746
|
+
* working, and an explicit `--token` serves both. With neither configured this
|
|
747
|
+
* fails exactly as the admin-token capabilities do.
|
|
748
|
+
*/
|
|
749
|
+
function makeSecrets() {
|
|
750
|
+
const secretsToken = tryResolve(resolveSecretsToken);
|
|
751
|
+
const adminToken = tryResolve(resolveAdminToken);
|
|
752
|
+
if (!secretsToken && !adminToken) resolveAdminToken(options);
|
|
753
|
+
const clientFor = (token) => createGitHubClient$1({
|
|
754
|
+
token,
|
|
755
|
+
baseUrl: options.baseUrl,
|
|
756
|
+
fetch: options.fetch
|
|
757
|
+
});
|
|
758
|
+
const repoClient = clientFor(adminToken ?? secretsToken);
|
|
759
|
+
const orgClient = clientFor(secretsToken ?? adminToken);
|
|
760
|
+
return secrets({
|
|
761
|
+
options,
|
|
762
|
+
client: repoClient,
|
|
763
|
+
repo: options.repo,
|
|
764
|
+
repoRoot: options.repoRoot ?? process.cwd()
|
|
765
|
+
}, orgClient);
|
|
766
|
+
}
|
|
722
767
|
function makeOrgClient() {
|
|
723
768
|
try {
|
|
769
|
+
const token = resolveOrgToken(options);
|
|
724
770
|
return createGitHubClient$1({
|
|
725
|
-
token
|
|
771
|
+
token,
|
|
726
772
|
baseUrl: options.baseUrl,
|
|
727
773
|
fetch: options.fetch
|
|
728
774
|
});
|
|
@@ -735,7 +781,7 @@ function createPlugin(options) {
|
|
|
735
781
|
capabilities: {
|
|
736
782
|
source: () => source(makeCtx(resolveAdminToken), makeOrgClient()),
|
|
737
783
|
ci: () => ci(makeCtx(resolveReadToken)),
|
|
738
|
-
secrets: () =>
|
|
784
|
+
secrets: () => makeSecrets(),
|
|
739
785
|
environments: () => environments(makeCtx(resolveAdminToken)),
|
|
740
786
|
issues: () => issues(makeCtx(resolveIssuesToken))
|
|
741
787
|
}
|
|
@@ -747,4 +793,4 @@ function createPlugin(options) {
|
|
|
747
793
|
*/
|
|
748
794
|
const AUTH_HINT = "generate fine-grained Personal Access Tokens at https://github.com/settings/tokens (one per feature — see docs/tokens.md for required scopes per operation), then run: holocron auth set github.<feature> <PAT>";
|
|
749
795
|
//#endregion
|
|
750
|
-
export { AUTH_HINT, AuthError, GitHubCi, GitHubEnvironments, GitHubIssues, GitHubSecrets, GitHubSource, ci, createFeatureResolver, createGitHubClient, createPlugin, encryptSecret, environments, issues, normalizeTeamEntry, resolveAdminToken, resolveDeployToken, resolveIssuesToken, resolveOrgToken, resolveReadToken, resolveReleaseToken, resolveSyncToken, secrets, source, syncLabels, syncTeams, verifyToken };
|
|
796
|
+
export { AUTH_HINT, AuthError, GitHubCi, GitHubEnvironments, GitHubIssues, GitHubSecrets, GitHubSource, ci, createFeatureResolver, createGitHubClient, createPlugin, encryptSecret, environments, issues, normalizeTeamEntry, resolveAdminToken, resolveDeployToken, resolveIssuesToken, resolveOrgToken, resolveReadToken, resolveReleaseToken, resolveSecretsToken, resolveSyncToken, secrets, source, syncLabels, syncTeams, verifyToken };
|
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.191",
|
|
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",
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
"plugin",
|
|
10
10
|
"source"
|
|
11
11
|
],
|
|
12
|
-
"homepage": "https://github.com/theholocron/holocron/tree/main/
|
|
12
|
+
"homepage": "https://github.com/theholocron/holocron/tree/main/plugins/holocron-plugin-github#readme",
|
|
13
13
|
"bugs": "https://github.com/theholocron/holocron/issues",
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
16
16
|
"url": "git+https://github.com/theholocron/holocron.git",
|
|
17
|
-
"directory": "
|
|
17
|
+
"directory": "plugins/holocron-plugin-github"
|
|
18
18
|
},
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"author": "Newton Koumantzelis",
|
|
@@ -34,12 +34,14 @@
|
|
|
34
34
|
"libsodium-wrappers": "^0.8.4"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@theholocron/eslint-config": "^8.
|
|
38
|
-
"@theholocron/
|
|
39
|
-
"@theholocron/
|
|
40
|
-
"@theholocron/
|
|
41
|
-
"@theholocron/
|
|
42
|
-
"@theholocron/
|
|
37
|
+
"@theholocron/eslint-config": "^8.8.2",
|
|
38
|
+
"@theholocron/fs-utils": "^1.16.0",
|
|
39
|
+
"@theholocron/github-client": "^1.43.1",
|
|
40
|
+
"@theholocron/http-client": "^1.43.1",
|
|
41
|
+
"@theholocron/misc-utils": "^1.16.0",
|
|
42
|
+
"@theholocron/tsconfig": "^8.8.2",
|
|
43
|
+
"@theholocron/tsdown-config": "^8.8.2",
|
|
44
|
+
"@theholocron/vitest-config": "^8.8.2",
|
|
43
45
|
"@types/node": "^26",
|
|
44
46
|
"@vitest/coverage-v8": "^4.1.11",
|
|
45
47
|
"@vitest/eslint-plugin": "^1.6.27",
|
|
@@ -47,14 +49,16 @@
|
|
|
47
49
|
"eslint-plugin-n": "^18.3.0",
|
|
48
50
|
"globals": "^17.11.0",
|
|
49
51
|
"tsdown": "^0.22.14",
|
|
50
|
-
"tsx": "4.23.
|
|
52
|
+
"tsx": "4.23.15",
|
|
51
53
|
"typescript": "^5.9.3",
|
|
52
54
|
"vitest": "^4.1.11",
|
|
53
|
-
"@theholocron/cli": "5.0.0-alpha.
|
|
55
|
+
"@theholocron/cli": "5.0.0-alpha.191"
|
|
54
56
|
},
|
|
55
57
|
"peerDependencies": {
|
|
56
|
-
"@theholocron/
|
|
57
|
-
"@theholocron/
|
|
58
|
+
"@theholocron/fs-utils": "^1.16.0",
|
|
59
|
+
"@theholocron/github-client": "^1.43.1",
|
|
60
|
+
"@theholocron/misc-utils": "^1.16.0",
|
|
61
|
+
"@theholocron/cli": "5.0.0-alpha.191"
|
|
58
62
|
},
|
|
59
63
|
"engines": {
|
|
60
64
|
"node": ">=22"
|