@theholocron/holocron-plugin-github 5.0.0-alpha.44 → 5.0.0-alpha.442
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 +33 -8
- package/dist/index.d.mts +272 -70
- package/dist/index.mjs +2004 -68
- package/package.json +29 -25
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# `@theholocron/holocron-plugin-github`
|
|
2
2
|
|
|
3
|
-
GitHub plugin for [Holocron](../cli). Implements
|
|
4
|
-
against the GitHub REST
|
|
3
|
+
GitHub plugin for [Holocron](../cli). Implements six capabilities
|
|
4
|
+
against the GitHub REST and GraphQL APIs:
|
|
5
5
|
|
|
6
6
|
| Capability | What this plugin does |
|
|
7
7
|
| -------------- | ---------------------------------------------------------------- |
|
|
@@ -10,6 +10,7 @@ against the GitHub REST API:
|
|
|
10
10
|
| `secrets` | GH Actions secrets (repo + environment + organization) |
|
|
11
11
|
| `environments` | Named deployment environments (reviewers, wait timers) |
|
|
12
12
|
| `issues` | GitHub Issues as a tracker (with lifecycle slots) |
|
|
13
|
+
| `projects` | GitHub Projects v2 boards (GraphQL) |
|
|
13
14
|
|
|
14
15
|
## Install
|
|
15
16
|
|
|
@@ -34,18 +35,19 @@ Each capability resolves its own fine-grained token so a compromised credential
|
|
|
34
35
|
| `HOLOCRON_SYNC_TOKEN` | `github.sync` | `sync-github` command |
|
|
35
36
|
| `HOLOCRON_RELEASE_TOKEN` | `github.release` | semantic-release, GitHub releases |
|
|
36
37
|
| `HOLOCRON_ADMIN_TOKEN` | `github.admin` | `source`, `secrets`, `environments` |
|
|
38
|
+
| `HOLOCRON_ORG_TOKEN` | `github.org` | `projects` |
|
|
37
39
|
|
|
38
40
|
Store tokens once via the keyring so they are picked up automatically:
|
|
39
41
|
|
|
40
42
|
```sh
|
|
41
|
-
holocron
|
|
42
|
-
holocron
|
|
43
|
-
holocron
|
|
44
|
-
holocron
|
|
45
|
-
holocron
|
|
43
|
+
holocron new token github.read ghp_xxx # clone + CI run listing
|
|
44
|
+
holocron new token github.issues ghp_xxx # issue management
|
|
45
|
+
holocron new token github.sync ghp_xxx # sync-github workflow templates
|
|
46
|
+
holocron new token github.release ghp_xxx # semantic-release
|
|
47
|
+
holocron new token github.admin ghp_xxx # setup, secrets, environments
|
|
46
48
|
```
|
|
47
49
|
|
|
48
|
-
See [
|
|
50
|
+
See the [token reference](https://docs.theholocron.dev/holocron/tokens/) for full scope requirements and CI setup.
|
|
49
51
|
|
|
50
52
|
## Config
|
|
51
53
|
|
|
@@ -64,6 +66,29 @@ See [docs/tokens.md](../../docs/tokens.md) for full scope requirements and CI se
|
|
|
64
66
|
|
|
65
67
|
```
|
|
66
68
|
|
|
69
|
+
## `projects` capability
|
|
70
|
+
|
|
71
|
+
GitHub Projects v2 boards over GraphQL, for `list projects`, `new project`, `setup project` (SPEC-0020, #1744). It uses the org token
|
|
72
|
+
(`HOLOCRON_ORG_TOKEN`, keyring `github.org`) with the **Projects** organization permission. Items are keyed `#N` in the
|
|
73
|
+
configured `repo` and `owner/repo#N` elsewhere.
|
|
74
|
+
|
|
75
|
+
| Method | What it does |
|
|
76
|
+
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
77
|
+
| `list` | Every project of the organization, open and closed. `find` is the exact name among the open ones. |
|
|
78
|
+
| `create` | Copies the board `template.source` names (fields, options, views, automation rules, no items), or creates a project and applies the template. |
|
|
79
|
+
| `close` | `updateProjectV2` with `closed: true`. Reversible. |
|
|
80
|
+
| `read` | Statuses, other fields, board and table views and automation rules. |
|
|
81
|
+
| `ensure` | Adds what the template lists and the board lacks (options, fields, views, filters). Never deletes. Rules and view grouping the API cannot set come back as `todos`. |
|
|
82
|
+
| `items` | Each issue or pull request with its status, category, whether it is open and its open blockers. |
|
|
83
|
+
| `setStatus` | Sets an item's status. Idempotent: `transitioned: false` when it is already there. |
|
|
84
|
+
| `move` | Puts open items on another board with status and priority (only where the target has none); closed and merged ones stay and are set to done when theirs is not a done one. |
|
|
85
|
+
| `whoami` | How many boards the token sees, for `holocron doctor`. |
|
|
86
|
+
|
|
87
|
+
`ensure` is safe on a field that has items. `updateProjectV2Field` replaces a single select field's whole option list,
|
|
88
|
+
and an option sent without its `id` blanks the field on every item, so `ensure` reads the field first, sends every
|
|
89
|
+
existing option with its `id` in the template's order (new ones without), and stops when the field cannot be read. It
|
|
90
|
+
also keeps the item values in memory and, if a re-read shows any gone, writes them back by option name and fails.
|
|
91
|
+
|
|
67
92
|
## Status
|
|
68
93
|
|
|
69
94
|
**`v2.0.0-alpha.0`** — published on npm under the `alpha` dist-tag.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,47 +1,65 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
declare const resolveReadToken: (
|
|
5
|
-
|
|
6
|
-
declare const
|
|
7
|
-
|
|
8
|
-
declare const
|
|
9
|
-
|
|
10
|
-
declare const
|
|
11
|
-
|
|
12
|
-
|
|
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, SecretAccess, 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
|
+
import { GitHubClient, GitHubClientOptions, GraphQLClient, createGitHubClient } from "@theholocron/github-client";
|
|
3
|
+
/** Resolves the token for read-only GitHub access (`HOLOCRON_READ_TOKEN`, keyring key `github.read`). */
|
|
4
|
+
export declare const resolveReadToken: import("@theholocron/cli").FeatureResolver;
|
|
5
|
+
/** Resolves the token for issue operations (`HOLOCRON_ISSUES_TOKEN`, keyring key `github.issues`). */
|
|
6
|
+
export declare const resolveIssuesToken: import("@theholocron/cli").FeatureResolver;
|
|
7
|
+
/** Resolves the token for syncing repo files and settings (`HOLOCRON_SYNC_TOKEN`, keyring key `github.sync`). */
|
|
8
|
+
export declare const resolveSyncToken: import("@theholocron/cli").FeatureResolver;
|
|
9
|
+
/** Resolves the token for release operations (`HOLOCRON_RELEASE_TOKEN`, keyring key `github.release`). */
|
|
10
|
+
export declare const resolveReleaseToken: import("@theholocron/cli").FeatureResolver;
|
|
11
|
+
/** Resolves the repo-scoped admin token (`HOLOCRON_ADMIN_TOKEN`, keyring key `github.admin`). */
|
|
12
|
+
export declare const resolveAdminToken: import("@theholocron/cli").FeatureResolver;
|
|
13
|
+
/** Resolves the org-level secrets token (`HOLOCRON_SECRETS_TOKEN`, keyring key `github.secrets`). */
|
|
14
|
+
export declare const resolveSecretsToken: import("@theholocron/cli").FeatureResolver;
|
|
15
|
+
/** Resolves the token for deployment operations (`HOLOCRON_DEPLOY_TOKEN`, keyring key `github.deploy`). */
|
|
16
|
+
export declare const resolveDeployToken: import("@theholocron/cli").FeatureResolver;
|
|
17
|
+
/**
|
|
18
|
+
* Resolves the token for the user-sync files in the org's private config repo (`HOLOCRON_USER_SYNC_TOKEN`, keyring
|
|
19
|
+
* key `github.user-sync`).
|
|
20
|
+
*/
|
|
21
|
+
export declare const resolveUserSyncToken: import("@theholocron/cli").FeatureResolver;
|
|
22
|
+
/** Resolves the org-level token (`HOLOCRON_ORG_TOKEN`, keyring key `github.org`). */
|
|
23
|
+
export declare const resolveOrgToken: import("@theholocron/cli").FeatureResolver;
|
|
13
24
|
interface CiOptions {
|
|
14
25
|
repo: string;
|
|
15
26
|
}
|
|
16
|
-
|
|
27
|
+
/** The GitHub implementation of the `ci` capability, backed by GitHub Actions workflow runs. */
|
|
28
|
+
export declare class GitHubCi implements Ci {
|
|
17
29
|
private readonly client;
|
|
18
30
|
private readonly opts;
|
|
31
|
+
/** Capability key, always `"ci"`. */
|
|
19
32
|
readonly key: "ci";
|
|
33
|
+
/** Provider name, always `"github"`. */
|
|
20
34
|
readonly providerName = "github";
|
|
21
35
|
constructor(client: GitHubClient, opts: CiOptions);
|
|
36
|
+
/** Lists workflow runs for the repo, optionally filtered by branch, status and limit. */
|
|
22
37
|
listRuns(filter?: CiRunFilter): Promise<CiRun[]>;
|
|
38
|
+
/** Fetches one workflow run by id. */
|
|
23
39
|
getRun(id: string | number): Promise<CiRun>;
|
|
24
40
|
private mapRun;
|
|
25
41
|
private mapConclusion;
|
|
26
42
|
}
|
|
27
|
-
//#endregion
|
|
28
|
-
//#region src/capabilities/environments.d.ts
|
|
29
43
|
interface EnvironmentsOptions {
|
|
30
44
|
repo: string;
|
|
31
45
|
}
|
|
32
|
-
|
|
46
|
+
/** The GitHub implementation of the `environments` capability, managing a repo's deployment environments. */
|
|
47
|
+
export declare class GitHubEnvironments implements Environments {
|
|
33
48
|
private readonly client;
|
|
34
49
|
private readonly opts;
|
|
50
|
+
/** Capability key, always `"environments"`. */
|
|
35
51
|
readonly key: "environments";
|
|
52
|
+
/** Provider name, always `"github"`. */
|
|
36
53
|
readonly providerName = "github";
|
|
37
54
|
constructor(client: GitHubClient, opts: EnvironmentsOptions);
|
|
55
|
+
/** Lists the repo's environments with their wait timer, self-review rule and required reviewers. */
|
|
38
56
|
listEnvironments(): Promise<Environment[]>;
|
|
57
|
+
/** Creates or updates an environment, sending only the settings the given environment defines. */
|
|
39
58
|
upsertEnvironment(env: Environment): Promise<void>;
|
|
59
|
+
/** Deletes the named environment. */
|
|
40
60
|
deleteEnvironment(name: string): Promise<void>;
|
|
41
61
|
private flattenReviewers;
|
|
42
62
|
}
|
|
43
|
-
//#endregion
|
|
44
|
-
//#region src/capabilities/issues.d.ts
|
|
45
63
|
interface IssuesOptions {
|
|
46
64
|
repo: string;
|
|
47
65
|
/**
|
|
@@ -55,9 +73,12 @@ interface IssuesOptions {
|
|
|
55
73
|
inReview: string;
|
|
56
74
|
};
|
|
57
75
|
}
|
|
58
|
-
|
|
76
|
+
/** The GitHub implementation of the `issues` capability, backed by GitHub Issues and status labels. */
|
|
77
|
+
export declare class GitHubIssues implements Issues {
|
|
59
78
|
private readonly client;
|
|
79
|
+
/** Capability key, always `"issues"`. */
|
|
60
80
|
readonly key: "issues";
|
|
81
|
+
/** Provider name, always `"github"`. */
|
|
61
82
|
readonly providerName = "github";
|
|
62
83
|
private readonly owner;
|
|
63
84
|
private readonly repoName;
|
|
@@ -65,8 +86,21 @@ declare class GitHubIssues implements Issues {
|
|
|
65
86
|
private readonly labels;
|
|
66
87
|
constructor(client: GitHubClient, opts: IssuesOptions);
|
|
67
88
|
getMyself(): Promise<TrackerUser>;
|
|
89
|
+
/**
|
|
90
|
+
* Searches the repo's issues, newest update first, leaving out pull requests.
|
|
91
|
+
*
|
|
92
|
+
* With `filter.text`, the issues are paged (newest update first, 100 a page, at most 20 pages) and compared
|
|
93
|
+
* client-side, without regard to case, until `limit` matches are found or the issues run out. GitHub's issue
|
|
94
|
+
* search (`GET /search/issues`) is deliberately not used: it indexes the words of a body, so punctuation and an
|
|
95
|
+
* HTML comment such as `<!-- holocron:idea notes/a.md -->` cannot be relied on to match, it is limited to 30
|
|
96
|
+
* requests a minute and it is eventually consistent (an issue made a moment ago may be missing). Paging has none
|
|
97
|
+
* of those limits, at the cost of reading up to 20 pages of a very large repository.
|
|
98
|
+
*/
|
|
68
99
|
search(filter: IssueSearchFilter): Promise<Issue[]>;
|
|
100
|
+
private searchText;
|
|
101
|
+
/** Fetches one issue by its key. */
|
|
69
102
|
get(key: string): Promise<Issue>;
|
|
103
|
+
/** Creates an issue and returns its key as `#<number>`; the milestone is resolved from its title. */
|
|
70
104
|
create(input: {
|
|
71
105
|
summary: string;
|
|
72
106
|
body?: string;
|
|
@@ -76,17 +110,27 @@ declare class GitHubIssues implements Issues {
|
|
|
76
110
|
key: string;
|
|
77
111
|
}>;
|
|
78
112
|
transition(key: string, slot: LifecycleSlot): Promise<LifecycleResult>;
|
|
113
|
+
/** Adds a comment to the issue with the given key. */
|
|
79
114
|
comment(key: string, body: string): Promise<void>;
|
|
115
|
+
/** Checks the authenticated user, the repo and the label-backed lifecycle slots, and reports what resolves. */
|
|
80
116
|
doctor(): Promise<TrackerDoctorReport>;
|
|
117
|
+
/** Reads issues with their comments, priority label, parent and blockers, for `holocron migrate`. */
|
|
118
|
+
export(selector: IssueSelector, info?: ExportInfo): Promise<IssueRecord[]>;
|
|
119
|
+
/** Makes the records as issues; one already made by an earlier run is skipped. */
|
|
120
|
+
import(records: IssueRecord[], options?: ImportOptions): Promise<ImportResult[]>;
|
|
121
|
+
/** Like `import`, and it also updates what an earlier import or sync made, for `holocron sync issues`. */
|
|
122
|
+
sync(records: IssueRecord[], options?: ImportOptions): Promise<SyncResult[]>;
|
|
81
123
|
private resolveMilestone;
|
|
82
124
|
private removeStatusLabels;
|
|
83
125
|
private mapIssue;
|
|
84
126
|
}
|
|
85
|
-
|
|
86
|
-
//#region src/capabilities/labels.d.ts
|
|
127
|
+
/** A label the repo is expected to have. */
|
|
87
128
|
interface CanonicalLabel {
|
|
129
|
+
/** The label's name. */
|
|
88
130
|
readonly name: string;
|
|
131
|
+
/** The label's color, as a hex string. */
|
|
89
132
|
readonly color: string;
|
|
133
|
+
/** The label's description. */
|
|
90
134
|
readonly description: string;
|
|
91
135
|
}
|
|
92
136
|
/**
|
|
@@ -97,36 +141,133 @@ interface CanonicalLabel {
|
|
|
97
141
|
* - DELETEs labels listed in `stale`.
|
|
98
142
|
* - Leaves unrecognised labels that aren't in `stale` untouched.
|
|
99
143
|
*/
|
|
100
|
-
declare function syncLabels(client: GitHubClient, repo: string, canonical: ReadonlyArray<CanonicalLabel>, stale: ReadonlyArray<string>): Promise<string>;
|
|
101
|
-
|
|
102
|
-
|
|
144
|
+
export declare function syncLabels(client: GitHubClient, repo: string, canonical: ReadonlyArray<CanonicalLabel>, stale: ReadonlyArray<string>): Promise<string>;
|
|
145
|
+
/** Options of the GitHub `projects` capability. */
|
|
146
|
+
interface ProjectsOptions {
|
|
147
|
+
/** The repository the provider is configured for, as `owner/name`; its items get the short key `#N`. */
|
|
148
|
+
repo: string;
|
|
149
|
+
}
|
|
150
|
+
/** The GitHub implementation of the `projects` capability, backed by Projects v2. */
|
|
151
|
+
export declare class GitHubProjects implements Projects {
|
|
152
|
+
private readonly graphql;
|
|
153
|
+
/** Capability key, always `"projects"`. */
|
|
154
|
+
readonly key: "projects";
|
|
155
|
+
/** Provider name, always `"github"`. */
|
|
156
|
+
readonly providerName = "github";
|
|
157
|
+
private readonly repo;
|
|
158
|
+
constructor(graphql: GraphQLClient, opts: ProjectsOptions);
|
|
159
|
+
/** Every board of the organization, open and closed. */
|
|
160
|
+
list(owner: string): Promise<BoardSummary[]>;
|
|
161
|
+
/** The open board with exactly this name. */
|
|
162
|
+
find(owner: string, name: string): Promise<BoardSummary | undefined>;
|
|
163
|
+
/**
|
|
164
|
+
* Makes a board. With `template.source` naming an open board it is copied (fields, options, views and automation
|
|
165
|
+
* rules, no items); otherwise the board is created and brought in line with the template.
|
|
166
|
+
*/
|
|
167
|
+
create(owner: string, name: string, template: BoardTemplate): Promise<BoardSummary>;
|
|
168
|
+
/** Closes the board; `updateProjectV2` with `closed: true` is the only way, and reversible. */
|
|
169
|
+
close(_owner: string, board: BoardSummary): Promise<void>;
|
|
170
|
+
/** The live board: statuses, other fields, views and automation rules. */
|
|
171
|
+
read(_owner: string, board: BoardSummary): Promise<BoardState>;
|
|
172
|
+
/**
|
|
173
|
+
* Brings the board in line with the template. Never deletes a field, option or view, and never sends an option
|
|
174
|
+
* list without ids. Stops (throws) when the status field cannot be read.
|
|
175
|
+
*/
|
|
176
|
+
ensure(_owner: string, board: BoardSummary, template: BoardTemplate): Promise<EnsureReport>;
|
|
177
|
+
/**
|
|
178
|
+
* Makes a single select field hold the wanted options in order, every existing one sent with its id. Options the
|
|
179
|
+
* template does not mention stay, after the wanted ones. Returns what changed (`Blocked added`, `order set`).
|
|
180
|
+
*/
|
|
181
|
+
private ensureOptions;
|
|
182
|
+
private createField;
|
|
183
|
+
private createView;
|
|
184
|
+
private updateView;
|
|
185
|
+
/** The board's issues and pull requests with their status, whether they are open and their open blockers. */
|
|
186
|
+
items(_owner: string, board: BoardSummary, template: BoardTemplate): Promise<BoardItem[]>;
|
|
187
|
+
/** Puts an item in a status; `transitioned` is false when it already is there. */
|
|
188
|
+
setStatus(_owner: string, board: BoardSummary, key: string, status: string): Promise<LifecycleResult>;
|
|
189
|
+
/**
|
|
190
|
+
* Puts the open items of `from` on `to` with their status and priority, only where the target has no value;
|
|
191
|
+
* closed and merged ones stay, and are set to the template's done status when theirs is not a done one.
|
|
192
|
+
*/
|
|
193
|
+
move(_owner: string, from: BoardSummary, to: BoardSummary, template: BoardTemplate): Promise<MoveReport>;
|
|
194
|
+
/**
|
|
195
|
+
* Puts issues on the board (`addProjectV2ItemById`, the content id the issue's node id) and sets Status and Priority
|
|
196
|
+
* through the single select update, only where the item has no value yet. A status or priority with no option on
|
|
197
|
+
* the board is reported in `dropped`; no option is ever created, so no value is cleared.
|
|
198
|
+
*/
|
|
199
|
+
addItems(_owner: string, board: BoardSummary, items: BoardItemInput[], template: BoardTemplate): Promise<AddedItem[]>;
|
|
200
|
+
/** The board's own status for an input: the option named like its status, else the template's status of its category. */
|
|
201
|
+
private statusFor;
|
|
202
|
+
/** The node id of an issue, which `addProjectV2ItemById` takes as the content id. */
|
|
203
|
+
private nodeId;
|
|
204
|
+
/** A `holocron doctor` smoke check: how many boards the token sees in the configured repository's organization. */
|
|
205
|
+
whoami(): Promise<{
|
|
206
|
+
ok: boolean;
|
|
207
|
+
boards: number;
|
|
208
|
+
}>;
|
|
209
|
+
/** Sets a single select value by option name; a field or option the board lacks is skipped. */
|
|
210
|
+
private setOption;
|
|
211
|
+
private ownerId;
|
|
212
|
+
private readRaw;
|
|
213
|
+
private fetchItems;
|
|
214
|
+
private keyOf;
|
|
215
|
+
private parseKey;
|
|
216
|
+
}
|
|
103
217
|
interface SecretsOptions {
|
|
104
218
|
repo: string;
|
|
105
219
|
}
|
|
106
|
-
|
|
220
|
+
/** The GitHub implementation of the `secrets` capability, covering repository, environment and organization secrets. */
|
|
221
|
+
export declare class GitHubSecrets implements Secrets {
|
|
107
222
|
private readonly client;
|
|
108
223
|
private readonly opts;
|
|
224
|
+
private readonly orgClient?;
|
|
225
|
+
/** Capability key, always `"secrets"`. */
|
|
109
226
|
readonly key: "secrets";
|
|
227
|
+
/** Provider name, always `"github"`. */
|
|
110
228
|
readonly providerName = "github";
|
|
111
|
-
|
|
229
|
+
/**
|
|
230
|
+
* `client` handles repo and environment scopes; `orgClient`, when given, handles
|
|
231
|
+
* the organization scope. They differ when a dedicated org-only token exists:
|
|
232
|
+
* it can write org secrets but not repo ones, and `github.admin` is the reverse.
|
|
233
|
+
*/
|
|
234
|
+
constructor(client: GitHubClient, opts: SecretsOptions, orgClient?: GitHubClient | undefined);
|
|
235
|
+
/** Repository name to numeric id, so one run asks GitHub once per repository however many secrets name it. */
|
|
236
|
+
private readonly repoIds;
|
|
237
|
+
private clientFor;
|
|
112
238
|
listSecrets(scope: SecretScope): Promise<string[]>;
|
|
113
239
|
setSecret(scope: SecretScope, name: string, value: string): Promise<void>;
|
|
240
|
+
/**
|
|
241
|
+
* Who can read each organization secret, by name (never a value): `selected` ones come with the names of their
|
|
242
|
+
* repositories. Any other scope has no visibility and gives `{}`.
|
|
243
|
+
*/
|
|
244
|
+
listSecretAccess(scope: SecretScope): Promise<Record<string, SecretAccess>>;
|
|
245
|
+
/** The `visibility` (and repository ids) of an organization write. No `visibility` keeps the older default, `all`. */
|
|
246
|
+
private readers;
|
|
247
|
+
private repoId;
|
|
248
|
+
/** Deletes the named secret in the given scope. */
|
|
114
249
|
deleteSecret(scope: SecretScope, name: string): Promise<void>;
|
|
115
250
|
}
|
|
116
|
-
//#endregion
|
|
117
|
-
//#region src/capabilities/source.d.ts
|
|
118
251
|
interface SourceOptions {
|
|
119
252
|
repo: string;
|
|
120
253
|
repoRoot: string;
|
|
121
254
|
/** Secondary client authenticated with HOLOCRON_ORG_TOKEN for org-scoped operations (teams, custom properties). */
|
|
122
255
|
orgClient?: GitHubClient;
|
|
256
|
+
/** Client for the files that link GitHub accounts to other services (HOLOCRON_USER_SYNC_TOKEN); falls back to the org client. */
|
|
257
|
+
userSyncClient?: GitHubClient;
|
|
123
258
|
/** Forwarded to a secondary client created for Pages calls (HOLOCRON_DEPLOY_TOKEN). */
|
|
124
259
|
baseUrl?: string;
|
|
125
260
|
fetch?: typeof fetch;
|
|
126
261
|
}
|
|
127
|
-
|
|
262
|
+
/**
|
|
263
|
+
* The GitHub implementation of the `source` capability: repo settings, rulesets, branch protection, security
|
|
264
|
+
* features and local workflow files.
|
|
265
|
+
*/
|
|
266
|
+
export declare class GitHubSource implements Source {
|
|
128
267
|
private readonly client;
|
|
268
|
+
/** Capability key, always `"source"`. */
|
|
129
269
|
readonly key: "source";
|
|
270
|
+
/** Provider name, always `"github"`. */
|
|
130
271
|
readonly providerName = "github";
|
|
131
272
|
private readonly owner;
|
|
132
273
|
private readonly name;
|
|
@@ -134,83 +275,125 @@ declare class GitHubSource implements Source {
|
|
|
134
275
|
private readonly repoRoot;
|
|
135
276
|
private readonly workflowDir;
|
|
136
277
|
private readonly orgClient?;
|
|
278
|
+
private readonly userSyncClient?;
|
|
137
279
|
private readonly baseUrl?;
|
|
138
280
|
private readonly fetchImpl?;
|
|
139
281
|
constructor(client: GitHubClient, opts: SourceOptions);
|
|
140
282
|
whoami(): Promise<{
|
|
141
283
|
login: string;
|
|
142
284
|
}>;
|
|
285
|
+
/** Returns the repo's owner, name and default branch. */
|
|
143
286
|
getRepo(): Promise<RepoRef>;
|
|
287
|
+
/** Lists the repo's rulesets. */
|
|
144
288
|
listRulesets(): Promise<Ruleset[]>;
|
|
289
|
+
/** Creates a ruleset from the given payload. */
|
|
145
290
|
createRuleset(payload: Record<string, unknown>): Promise<Ruleset>;
|
|
291
|
+
/** Updates the ruleset with the given id from the payload. */
|
|
146
292
|
updateRuleset(id: number, payload: Record<string, unknown>): Promise<Ruleset>;
|
|
293
|
+
/** Updates the repo's settings. */
|
|
147
294
|
updateRepoSettings(settings: RepoSettings): Promise<void>;
|
|
148
295
|
protectBranch(branch: string, payload: Record<string, unknown>): Promise<void>;
|
|
296
|
+
/** Enables Dependabot vulnerability alerts. */
|
|
149
297
|
enableVulnerabilityAlerts(): Promise<void>;
|
|
298
|
+
/** Enables Dependabot automated security fixes. */
|
|
150
299
|
enableAutomatedSecurityFixes(): Promise<void>;
|
|
300
|
+
/** Enables secret scanning. */
|
|
151
301
|
enableSecretScanning(): Promise<void>;
|
|
152
302
|
enableCodeScanning(): Promise<string>;
|
|
153
303
|
disableDefaultCodeScanning(): Promise<void>;
|
|
154
304
|
enableDependencyGraph(): Promise<void>;
|
|
305
|
+
/** Enables private vulnerability reporting. */
|
|
155
306
|
enablePrivateVulnerabilityReporting(): Promise<void>;
|
|
307
|
+
/** Lists the `.yml` and `.yaml` files in `.github/workflows`, sorted by name; empty when the folder is missing. */
|
|
156
308
|
listWorkflowFiles(): Promise<string[]>;
|
|
309
|
+
/** Reads a workflow file's text, or `null` when it does not exist. */
|
|
157
310
|
readWorkflowFile(name: string): Promise<string | null>;
|
|
311
|
+
/** Writes a workflow file, creating `.github/workflows` first when needed. */
|
|
158
312
|
writeWorkflowFile(name: string, contents: string): Promise<void>;
|
|
313
|
+
/** Removes a workflow file; a file that is already gone is not an error. */
|
|
159
314
|
removeWorkflowFile(name: string): Promise<void>;
|
|
160
315
|
writeRepoFile(path: string, contents: string): Promise<void>;
|
|
161
316
|
syncLabels(canonical: ReadonlyArray<LabelDef>, stale: ReadonlyArray<string>): Promise<string>;
|
|
162
317
|
syncProperties(values: Record<string, string | string[]>): Promise<string>;
|
|
318
|
+
getOrgPropertyValues(name: string): Promise<string[] | undefined>;
|
|
319
|
+
addOrgPropertyValues(name: string, values: string[]): Promise<string[]>;
|
|
320
|
+
checkPropertyValues(values: Record<string, string | string[]>): Promise<string[] | undefined>;
|
|
163
321
|
syncTeams(teams: TeamEntry$1[]): Promise<string>;
|
|
322
|
+
teamMembers(teamSlug: string, org?: string): Promise<SourceTeamMember[]>;
|
|
323
|
+
readFile(path: string, repo?: string): Promise<SourceFile | null>;
|
|
324
|
+
writeFile(path: string, content: string, opts: {
|
|
325
|
+
message: string;
|
|
326
|
+
version?: string;
|
|
327
|
+
repo?: string;
|
|
328
|
+
}): Promise<void>;
|
|
164
329
|
syncTopics(topics: string[]): Promise<string>;
|
|
330
|
+
syncVariables(variables: Record<string, string>, opts?: {
|
|
331
|
+
prune?: boolean;
|
|
332
|
+
dryRun?: boolean;
|
|
333
|
+
}): Promise<string>;
|
|
334
|
+
syncOrgVariables(org: string, variables: Record<string, {
|
|
335
|
+
value: string;
|
|
336
|
+
visibility: "all" | "private";
|
|
337
|
+
}>, opts?: {
|
|
338
|
+
prune?: boolean;
|
|
339
|
+
dryRun?: boolean;
|
|
340
|
+
}): Promise<string>;
|
|
341
|
+
listVariables(): Promise<Record<string, string>>;
|
|
342
|
+
listOrgVariables(org: string): Promise<Record<string, {
|
|
343
|
+
value: string;
|
|
344
|
+
visibility: "all" | "private" | "selected";
|
|
345
|
+
}>>;
|
|
346
|
+
getRepoInfo(): Promise<SourceRepoInfo>;
|
|
347
|
+
getProperties(): Promise<Record<string, string | string[]>>;
|
|
348
|
+
listLabels(): Promise<LabelDef[]>;
|
|
349
|
+
listTeamAccess(): Promise<Array<{
|
|
350
|
+
slug: string;
|
|
351
|
+
permission: TeamPermission$1;
|
|
352
|
+
}>>;
|
|
353
|
+
getRulesetDetail(id: number): Promise<SourceRulesetDetail>;
|
|
354
|
+
getSecurity(): Promise<SourceSecurity>;
|
|
165
355
|
syncDescription(description: string): Promise<string>;
|
|
166
356
|
syncHomepage(homepage: string): Promise<string>;
|
|
167
357
|
getPullRequest(number: number, repo?: string): Promise<PullRequest>;
|
|
358
|
+
listPullRequests(state: "open" | "closed", repo?: string): Promise<PullRequest[]>;
|
|
359
|
+
listBranches(repo?: string): Promise<SourceBranch[]>;
|
|
360
|
+
deleteBranch(name: string, repo?: string): Promise<void>;
|
|
361
|
+
listPullRequestCommits(number: number, repo?: string): Promise<string[]>;
|
|
168
362
|
configurePages(config: PagesConfig, token: string): Promise<void>;
|
|
169
363
|
}
|
|
170
|
-
|
|
171
|
-
//#region src/capabilities/teams.d.ts
|
|
364
|
+
/** A team entry with the permission spelled out. */
|
|
172
365
|
interface NormalizedTeamEntry {
|
|
366
|
+
/** The team's slug. */
|
|
173
367
|
slug: string;
|
|
368
|
+
/** The permission the team gets on the repo. */
|
|
174
369
|
permission: TeamPermission;
|
|
175
370
|
}
|
|
176
|
-
|
|
177
|
-
declare function
|
|
178
|
-
|
|
179
|
-
|
|
371
|
+
/** Turns a team entry into slug and permission form; a bare slug gets `push`. */
|
|
372
|
+
export declare function normalizeTeamEntry(entry: TeamEntry): NormalizedTeamEntry;
|
|
373
|
+
/** Grants each team access to the repo and reports the outcome; throws when every team fails. */
|
|
374
|
+
export declare function syncTeams(client: GitHubClient, repo: string, teams: TeamEntry[]): Promise<string>;
|
|
180
375
|
/**
|
|
181
376
|
* Encrypt `value` for the given GitHub-provided base64 public key.
|
|
182
377
|
* Returns the base64 ciphertext to send as `encrypted_value`.
|
|
183
378
|
*/
|
|
184
|
-
declare function encryptSecret(publicKeyBase64: string, value: string): Promise<string>;
|
|
185
|
-
//#endregion
|
|
186
|
-
//#region src/verify-token.d.ts
|
|
379
|
+
export declare function encryptSecret(publicKeyBase64: string, value: string): Promise<string>;
|
|
187
380
|
/**
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
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.
|
|
381
|
+
* Every token this plugin takes, for `holocron doctor tokens`, with what each layer's token must and must not be able
|
|
382
|
+
* to do. The release token is `optional`: only CI's release workflow reads it (from the org secret), so a development
|
|
383
|
+
* environment has no reason to hold it.
|
|
196
384
|
*/
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
subject: string;
|
|
200
|
-
}
|
|
201
|
-
interface VerifyTokenFailure {
|
|
202
|
-
ok: false;
|
|
203
|
-
message: string;
|
|
204
|
-
}
|
|
205
|
-
type VerifyTokenResult = VerifyTokenSuccess | VerifyTokenFailure;
|
|
385
|
+
export declare const tokens: PluginToken[];
|
|
386
|
+
/** Options for `verifyToken`. */
|
|
206
387
|
interface VerifyTokenOptions {
|
|
388
|
+
/** Overrides the API base URL, for tests. */
|
|
207
389
|
baseUrl?: string;
|
|
390
|
+
/** Overrides `fetch`, for tests. */
|
|
208
391
|
fetch?: typeof fetch;
|
|
209
392
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
interface GitHubPluginOptions extends ResolveTokenInput {
|
|
393
|
+
/** Checks a token against `GET /user` and returns who it belongs to, or why it failed. */
|
|
394
|
+
export declare function verifyToken(token: string, opts?: VerifyTokenOptions): Promise<VerifyTokenResult$1>;
|
|
395
|
+
/** Options for the GitHub plugin. */
|
|
396
|
+
export interface GitHubPluginOptions extends ResolveTokenInput {
|
|
214
397
|
/** "owner/name" — e.g., "theholocron/holocron". Required. */
|
|
215
398
|
repo: string;
|
|
216
399
|
/** Absolute path to the working repo root. Used by `source`'s
|
|
@@ -218,7 +401,9 @@ interface GitHubPluginOptions extends ResolveTokenInput {
|
|
|
218
401
|
repoRoot?: string;
|
|
219
402
|
/** Lifecycle slot → label name. Used by the `issues` capability. */
|
|
220
403
|
labels?: {
|
|
404
|
+
/** Label that marks an issue as in progress. */
|
|
221
405
|
inProgress: string;
|
|
406
|
+
/** Label that marks an issue as in review. */
|
|
222
407
|
inReview: string;
|
|
223
408
|
};
|
|
224
409
|
/** Override base URL for tests. Defaults to https://api.github.com. */
|
|
@@ -226,31 +411,48 @@ interface GitHubPluginOptions extends ResolveTokenInput {
|
|
|
226
411
|
/** Override `fetch` for tests. Defaults to global `fetch`. */
|
|
227
412
|
fetch?: typeof fetch;
|
|
228
413
|
}
|
|
229
|
-
|
|
414
|
+
/** What the capability factories receive: the plugin options, a client, the repo and its root. */
|
|
415
|
+
export interface PluginContext {
|
|
416
|
+
/** The plugin options. */
|
|
230
417
|
options: GitHubPluginOptions;
|
|
418
|
+
/** The GitHub client the capability uses. */
|
|
231
419
|
client: GitHubClient;
|
|
420
|
+
/** The repo as `owner/name`. */
|
|
232
421
|
repo: string;
|
|
422
|
+
/** Absolute path to the working repo root. */
|
|
233
423
|
repoRoot: string;
|
|
234
424
|
}
|
|
235
|
-
|
|
236
|
-
declare function
|
|
237
|
-
|
|
238
|
-
declare function
|
|
239
|
-
|
|
240
|
-
declare function
|
|
425
|
+
/** Builds the `source` capability; the optional clients cover org-level and user-sync access. */
|
|
426
|
+
export declare function source(ctx: PluginContext, orgClient?: GitHubClient, userSyncClient?: GitHubClient): Source;
|
|
427
|
+
/** Builds the `secrets` capability; the optional client handles organization secrets. */
|
|
428
|
+
export declare function secrets(ctx: PluginContext, orgClient?: GitHubClient): Secrets;
|
|
429
|
+
/** Builds the `environments` capability. */
|
|
430
|
+
export declare function environments(ctx: PluginContext): Environments;
|
|
431
|
+
/** Builds the `ci` capability. */
|
|
432
|
+
export declare function ci(ctx: PluginContext): Ci;
|
|
433
|
+
/** Builds the `issues` capability, passing the lifecycle labels when configured. */
|
|
434
|
+
export declare function issues(ctx: PluginContext): Issues;
|
|
435
|
+
/** Builds the `projects` capability: GitHub Projects v2 over GraphQL, with items keyed relative to the configured repo. */
|
|
436
|
+
export declare function projects(ctx: PluginContext): Projects;
|
|
437
|
+
/** Creates the plugin, resolving a token per capability when it is first used. */
|
|
438
|
+
export declare function createPlugin(options: GitHubPluginOptions): {
|
|
241
439
|
name: string;
|
|
440
|
+
probes: {
|
|
441
|
+
token: import("@theholocron/cli").Probe;
|
|
442
|
+
connection: import("@theholocron/cli").Probe;
|
|
443
|
+
};
|
|
242
444
|
capabilities: {
|
|
243
445
|
source: () => Source;
|
|
244
446
|
ci: () => Ci;
|
|
245
447
|
secrets: () => Secrets;
|
|
246
448
|
environments: () => Environments;
|
|
247
449
|
issues: () => Issues;
|
|
450
|
+
projects: () => Projects;
|
|
248
451
|
};
|
|
249
452
|
};
|
|
250
453
|
/**
|
|
251
|
-
* One-line hint printed by `holocron
|
|
454
|
+
* One-line hint printed by `holocron new token github` when no token
|
|
252
455
|
* is supplied or the supplied token is rejected.
|
|
253
456
|
*/
|
|
254
|
-
declare const AUTH_HINT: string;
|
|
255
|
-
|
|
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 };
|
|
457
|
+
export declare const AUTH_HINT: string;
|
|
458
|
+
export { type Auth, AuthError, type CanonicalLabel, type GitHubClientOptions, type NormalizedTeamEntry, type ProjectsOptions, type ResolveTokenInput, type TeamEntry, type TeamPermission, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, createFeatureResolver, createGitHubClient };
|