@effected/github 0.14.0 → 0.15.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/ArtifactMetadata.js +7 -5
- package/Attestation.js +7 -1
- package/CheckRun.js +10 -5
- package/CodeScanning.js +8 -1
- package/DeploymentEnvironment.js +19 -1
- package/GitBranch.js +22 -3
- package/GitCommit.js +25 -5
- package/GitHubApp.js +33 -14
- package/GitHubClient.js +24 -18
- package/GitHubCommit.js +20 -1
- package/GitHubContent.js +19 -1
- package/GitHubError.js +11 -22
- package/GitHubIssue.js +24 -8
- package/GitHubRelease.js +20 -2
- package/GitHubRepository.js +25 -11
- package/GitTag.js +19 -1
- package/GraphQL.js +21 -18
- package/PullRequest.js +27 -8
- package/PullRequestComment.js +25 -7
- package/README.md +5 -5
- package/Repo.js +8 -15
- package/RepositorySecret.js +19 -1
- package/RepositorySecurity.js +20 -1
- package/RepositoryVariable.js +19 -1
- package/Resilience.js +18 -16
- package/Rest.js +2 -4
- package/Ruleset.js +25 -4
- package/TokenPermissions.js +8 -11
- package/WorkflowDispatch.js +25 -1
- package/index.d.ts +684 -323
- package/internal/headers.js +0 -10
- package/internal/octokit.js +5 -11
- package/internal/paginate.js +1 -4
- package/package.json +4 -4
package/index.d.ts
CHANGED
|
@@ -9,12 +9,9 @@ import { SemVer } from "@effected/semver";
|
|
|
9
9
|
* Why a GitHub call failed, as a value you can branch on.
|
|
10
10
|
*
|
|
11
11
|
* @remarks
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* tested `includes("already") || includes("exists")`, and another re-issued an
|
|
16
|
-
* existence check after every failed branch creation because it could not tell
|
|
17
|
-
* "someone else created it" from "that failed".
|
|
12
|
+
* Branch on this discriminant instead of string-matching an error message:
|
|
13
|
+
* `alreadyExists` tells "someone else created it" apart from "that failed", so
|
|
14
|
+
* an upsert needs no follow-up existence check.
|
|
18
15
|
*
|
|
19
16
|
* @public
|
|
20
17
|
*/
|
|
@@ -75,8 +72,8 @@ declare const GitHubError_base: Schema.Class<GitHubError, Schema.TaggedStruct<"G
|
|
|
75
72
|
* @remarks
|
|
76
73
|
* Written by the client from `retry-after` or the rate-limit reset, and read
|
|
77
74
|
* by exactly one thing: the retry `Schedule`. It is a policy input, not
|
|
78
|
-
* information for a caller
|
|
79
|
-
* `retryable`
|
|
75
|
+
* information for a caller. Whether a failure is worth retrying at all is the
|
|
76
|
+
* derived `retryable` getter.
|
|
80
77
|
*/
|
|
81
78
|
readonly retryAfterMillis: Schema.optionalKey<Schema.Int>;
|
|
82
79
|
/**
|
|
@@ -95,16 +92,9 @@ declare const GitHubError_base: Schema.Class<GitHubError, Schema.TaggedStruct<"G
|
|
|
95
92
|
* Every REST failure this package produces, from every resource.
|
|
96
93
|
*
|
|
97
94
|
* @remarks
|
|
98
|
-
* One error class, not one per resource
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* site that disappears entirely now that `GitBranch.upsert` exists. Eighteen
|
|
102
|
-
* near-identical error classes and thirteen near-identical mapper closures
|
|
103
|
-
* bought that one match.
|
|
104
|
-
*
|
|
105
|
-
* What replaces them is {@link GitHubErrorKind} for routing and `operation` for
|
|
106
|
-
* identification. This mirrors `@effected/git`, where the rule is that no
|
|
107
|
-
* consumer ever string-matches stderr because classification happens once.
|
|
95
|
+
* One error class, not one per resource: {@link GitHubErrorKind} routes and
|
|
96
|
+
* `operation` identifies what was attempted. This mirrors `@effected/git`,
|
|
97
|
+
* where classification happens once so no consumer string-matches stderr.
|
|
108
98
|
*
|
|
109
99
|
* @public
|
|
110
100
|
*/
|
|
@@ -134,7 +124,7 @@ export declare class GitHubError extends GitHubError_base {
|
|
|
134
124
|
* @remarks
|
|
135
125
|
* The single classification step for the whole package — every resource
|
|
136
126
|
* method's failures come through here, so the taxonomy cannot drift between
|
|
137
|
-
* resources
|
|
127
|
+
* resources.
|
|
138
128
|
*
|
|
139
129
|
* `nowMillis` is passed in rather than read from the wall clock so the
|
|
140
130
|
* function stays pure and total: the rate-limit reset header is an absolute
|
|
@@ -201,9 +191,8 @@ declare const GitHubGraphQLError_base: Schema.Class<GitHubGraphQLError, Schema.T
|
|
|
201
191
|
*
|
|
202
192
|
* @remarks
|
|
203
193
|
* `"alreadyExists"` exists here for the same reason it exists on the REST
|
|
204
|
-
* error:
|
|
205
|
-
*
|
|
206
|
-
* make project creation idempotent.
|
|
194
|
+
* error: it lets a caller make a create idempotent without lowercasing the
|
|
195
|
+
* message and grepping it.
|
|
207
196
|
*/
|
|
208
197
|
readonly kind: Schema.Literals<readonly ["alreadyExists", "notFound", "rejected", "unauthorized", "rateLimited", "transport", "decode"]>;
|
|
209
198
|
/** The document's name, e.g. `"linkedIssues"` — never the literal `"graphql"`. */
|
|
@@ -223,7 +212,7 @@ declare const GitHubGraphQLError_base: Schema.Class<GitHubGraphQLError, Schema.T
|
|
|
223
212
|
* @remarks
|
|
224
213
|
* Separate from `GitHubError` because GraphQL genuinely answers differently:
|
|
225
214
|
* a 200 response can still carry failures, and it carries a **list** of them.
|
|
226
|
-
* `errors`
|
|
215
|
+
* `errors` carries every entry GitHub reported, in order.
|
|
227
216
|
*
|
|
228
217
|
* @public
|
|
229
218
|
*/
|
|
@@ -250,25 +239,29 @@ export declare class GitHubGraphQLError extends GitHubGraphQLError_base {
|
|
|
250
239
|
*
|
|
251
240
|
* @remarks
|
|
252
241
|
* This is the mechanism that makes `client.graphql` return a **domain value**
|
|
253
|
-
* rather than an `unknown` the caller casts
|
|
254
|
-
* query
|
|
255
|
-
* so every consumer wrote its own response interface and hoped.
|
|
242
|
+
* rather than an `unknown` the caller casts: the response schema ties the
|
|
243
|
+
* query to its decoded type.
|
|
256
244
|
*
|
|
257
|
-
*
|
|
258
|
-
* its own
|
|
259
|
-
*
|
|
260
|
-
* without this package having to know about its schema.
|
|
245
|
+
* This package owns the documents its resource services need; a consumer with a
|
|
246
|
+
* domain of its own (GitHub Projects, say) builds its own `GraphQLDocument` and
|
|
247
|
+
* gets the same typing and the same error taxonomy.
|
|
261
248
|
*
|
|
262
249
|
* @example
|
|
263
250
|
* ```ts
|
|
264
|
-
* import { GraphQLDocument } from "@effected/github";
|
|
265
|
-
* import { Schema } from "effect";
|
|
266
|
-
*
|
|
267
|
-
* const
|
|
268
|
-
* name: "
|
|
269
|
-
* document: `query {
|
|
270
|
-
* response: Schema.Struct({
|
|
271
|
-
* })<{ readonly
|
|
251
|
+
* import { GitHubClient, GraphQLDocument } from "@effected/github";
|
|
252
|
+
* import { Effect, Schema } from "effect";
|
|
253
|
+
*
|
|
254
|
+
* const OwnerLogin = GraphQLDocument.make({
|
|
255
|
+
* name: "ownerLogin",
|
|
256
|
+
* document: `query ($owner: String!) { repositoryOwner(login: $owner) { login } }`,
|
|
257
|
+
* response: Schema.Struct({ repositoryOwner: Schema.NullOr(Schema.Struct({ login: Schema.String })) }),
|
|
258
|
+
* })<{ readonly owner: string }>();
|
|
259
|
+
*
|
|
260
|
+
* const login = Effect.gen(function* () {
|
|
261
|
+
* const client = yield* GitHubClient;
|
|
262
|
+
* const data = yield* client.graphql(OwnerLogin, { owner: "effect-ts" });
|
|
263
|
+
* return data.repositoryOwner?.login;
|
|
264
|
+
* });
|
|
272
265
|
* ```
|
|
273
266
|
*
|
|
274
267
|
* @public
|
|
@@ -324,11 +317,8 @@ declare const RateLimitSnapshot_base: Schema.Class<RateLimitSnapshot, Schema.Str
|
|
|
324
317
|
* one. Read it through the client's `rateLimit` member when you want to pace
|
|
325
318
|
* yourself — **nothing in this package throttles on your behalf.**
|
|
326
319
|
*
|
|
327
|
-
* The
|
|
328
|
-
*
|
|
329
|
-
* so an application that forgot to provide it got two private cells and a
|
|
330
|
-
* silently dead feature. Here the cell lives inside the client layer that writes
|
|
331
|
-
* it, and this is the only way to read it.
|
|
320
|
+
* The cell lives inside the client layer that writes it, so there is nothing
|
|
321
|
+
* extra to provide: reading it through the client is the only way.
|
|
332
322
|
*
|
|
333
323
|
* @public
|
|
334
324
|
*/
|
|
@@ -379,15 +369,22 @@ declare const RetryPolicy_base: Schema.Class<RetryPolicy, Schema.Struct<{
|
|
|
379
369
|
*
|
|
380
370
|
* @remarks
|
|
381
371
|
* There is exactly **one** retry policy in this package, and it is wired into
|
|
382
|
-
* the client so every resource inherits it and no resource carries its own.
|
|
383
|
-
* package this replaces shipped four mutually inconsistent policies — a
|
|
384
|
-
* hand-rolled recursive loop, a second exported `Schedule` that ignored
|
|
385
|
-
* server-advised delays, a per-operation branch retry layered on top of the
|
|
386
|
-
* client's, and a rate-limiter retry with no predicate at all, which cheerfully
|
|
387
|
-
* retried permission denials — and consumers added two more on top.
|
|
372
|
+
* the client so every resource inherits it and no resource carries its own.
|
|
388
373
|
*
|
|
389
|
-
* Only failures that report `retryable` are retried, which for `GitHubError`
|
|
390
|
-
*
|
|
374
|
+
* Only failures that report `retryable` are retried, which for `GitHubError`
|
|
375
|
+
* means a transport failure or a rate limit. A 404, a validation rejection and
|
|
376
|
+
* an authorization failure fail on the first attempt.
|
|
377
|
+
*
|
|
378
|
+
* @example
|
|
379
|
+
* ```ts
|
|
380
|
+
* import { GitHubClient, RetryPolicy } from "@effected/github";
|
|
381
|
+
* import { Duration, Redacted } from "effect";
|
|
382
|
+
*
|
|
383
|
+
* const layer = GitHubClient.layerFromToken({
|
|
384
|
+
* token: Redacted.make("ghp_example"),
|
|
385
|
+
* retry: RetryPolicy.make({ ...RetryPolicy.default, maxRetries: 2, maxDelay: Duration.seconds(10) }),
|
|
386
|
+
* });
|
|
387
|
+
* ```
|
|
391
388
|
*
|
|
392
389
|
* @public
|
|
393
390
|
*/
|
|
@@ -427,9 +424,7 @@ export declare class RetryPolicy extends RetryPolicy_base {
|
|
|
427
424
|
* Built on `Schedule.modifyDelay`, whose callback receives the schedule's
|
|
428
425
|
* `Metadata` — including the **input that failed**. That is what makes a
|
|
429
426
|
* header-driven policy expressible as a `Schedule` at all: the delay is a
|
|
430
|
-
* function of the error, not only of the attempt number.
|
|
431
|
-
* available is why the package this replaces hand-rolled a recursive retry
|
|
432
|
-
* loop instead of using `Effect.retry`.
|
|
427
|
+
* function of the error, not only of the attempt number.
|
|
433
428
|
*/
|
|
434
429
|
schedule<E extends RetryableFailure>(): Schedule.Schedule<number, E>;
|
|
435
430
|
}
|
|
@@ -459,7 +454,7 @@ type Route = keyof Endpoints;
|
|
|
459
454
|
* @remarks
|
|
460
455
|
* octokit's own `RequestParameters` carries an `[parameter: string]: unknown`
|
|
461
456
|
* index signature, so intersecting it would silently accept every misspelled
|
|
462
|
-
* parameter. These three are the ones
|
|
457
|
+
* parameter. These three are the ones callers need:
|
|
463
458
|
* `headers` for a release asset's `content-type` and the attestations API
|
|
464
459
|
* version pin, `mediaType.format` for raw content reads, and `baseUrl` for the
|
|
465
460
|
* `uploads.github.com` host that release-asset uploads go to. Everything else a
|
|
@@ -500,8 +495,7 @@ type Data<R extends Route> = Endpoints[R]["response"]["data"];
|
|
|
500
495
|
* The subset of routes that paginate.
|
|
501
496
|
*
|
|
502
497
|
* @remarks
|
|
503
|
-
* Handing a non-paginating route to a paginating call is a **compile** error
|
|
504
|
-
* which the string-keyed surface this package replaces could not express.
|
|
498
|
+
* Handing a non-paginating route to a paginating call is a **compile** error.
|
|
505
499
|
*
|
|
506
500
|
* Intersected with `Rest.Route` because `plugin-paginate-rest` generates its
|
|
507
501
|
* map from its own `@octokit/types` pin, which can trail the one this package
|
|
@@ -536,10 +530,8 @@ declare const PageOptions_base: Schema.Class<PageOptions, Schema.Struct<{
|
|
|
536
530
|
* How far a paginated read should go.
|
|
537
531
|
*
|
|
538
532
|
* @remarks
|
|
539
|
-
* Both fields are honored by every paginating method in this package.
|
|
540
|
-
*
|
|
541
|
-
* of its eight call sites, so callers silently got 100-item pages and an
|
|
542
|
-
* unbounded walk with no way to say otherwise.
|
|
533
|
+
* Both fields are honored by every paginating method in this package. Unset,
|
|
534
|
+
* a read requests 100-item pages and walks until GitHub stops.
|
|
543
535
|
*
|
|
544
536
|
* `perPage` is **validated, not clamped**: GitHub caps a page at 100 and
|
|
545
537
|
* silently ignores anything larger, so a caller asking for 250 has a bug whose
|
|
@@ -702,19 +694,17 @@ interface GitHubFixtures {
|
|
|
702
694
|
* A missing fixture is a **test wiring** mistake, not a condition the code
|
|
703
695
|
* under test should handle, so the default kills the fiber rather than
|
|
704
696
|
* entering the error channel — the same treatment an absent `graphql`
|
|
705
|
-
* fixture
|
|
697
|
+
* fixture gets.
|
|
706
698
|
*
|
|
707
|
-
*
|
|
708
|
-
*
|
|
709
|
-
*
|
|
710
|
-
*
|
|
711
|
-
*
|
|
712
|
-
* fail for a new reason with nothing in any message naming a fixture. That
|
|
713
|
-
* cost `@spencerbeggs/reposets` 28 tests reading as ordinary logic bugs.
|
|
699
|
+
* Prefer `"die"` to `"fail"`: **a typed failure is only loud in code that
|
|
700
|
+
* does not catch.** Code whose methods each catch `GitHubError` and report
|
|
701
|
+
* it — a per-resource sync, say — turns a missing stub into a *different
|
|
702
|
+
* execution path* rather than a failure, and the assertions then fail for a
|
|
703
|
+
* new reason with nothing in any message naming a fixture.
|
|
714
704
|
*
|
|
715
705
|
* - `"die"` — defect naming the route. Loud in every consumer.
|
|
716
|
-
* - `"fail"` —
|
|
717
|
-
*
|
|
706
|
+
* - `"fail"` — fail with `GitHubError.notFound`. Rarely what you want, since
|
|
707
|
+
* a recorded `GitHubError` value stubs a failure explicitly:
|
|
718
708
|
* `{ "GET /repos/{owner}/{repo}": GitHubError.notFound("read", "repo") }`
|
|
719
709
|
* says which route fails and why, where absence says only "unwired".
|
|
720
710
|
* - `"empty"` — serve `{}` for a request and no items for a paginated read.
|
|
@@ -735,11 +725,6 @@ interface GitHubFixtures {
|
|
|
735
725
|
* **params** they were called with, which is what lets a suite assert that a
|
|
736
726
|
* method sent the right `owner`/`repo`/body rather than only the right
|
|
737
727
|
* route. `graphql` records the document name as `route`.
|
|
738
|
-
*
|
|
739
|
-
* Recording params was added for the resource modules ported in from
|
|
740
|
-
* `@spencerbeggs/reposets`, whose ~80-line hand-rolled harness existed
|
|
741
|
-
* because every one of their methods goes through `request` and a fixture
|
|
742
|
-
* could assert nothing about them.
|
|
743
728
|
*/
|
|
744
729
|
readonly requested?: Array<RecordedCall> | undefined;
|
|
745
730
|
}
|
|
@@ -754,12 +739,27 @@ declare const GitHubClient_base: Context.ServiceClass<GitHubClient, "@effected/g
|
|
|
754
739
|
* literal and gets both sides typed, with no callback, no type parameter to
|
|
755
740
|
* invent, and no cast.
|
|
756
741
|
*
|
|
757
|
-
*
|
|
758
|
-
*
|
|
759
|
-
*
|
|
760
|
-
*
|
|
761
|
-
*
|
|
762
|
-
*
|
|
742
|
+
* Nothing here asks the caller to invent a response type: the route literal is
|
|
743
|
+
* the only thing written, and a mismatch between a route and its parameters is
|
|
744
|
+
* a compile error.
|
|
745
|
+
*
|
|
746
|
+
* @example
|
|
747
|
+
* ```ts
|
|
748
|
+
* import { GitHubClient } from "@effected/github";
|
|
749
|
+
* import { Effect, Redacted } from "effect";
|
|
750
|
+
*
|
|
751
|
+
* const program = Effect.gen(function* () {
|
|
752
|
+
* const client = yield* GitHubClient;
|
|
753
|
+
* const release = yield* client.request("GET /repos/{owner}/{repo}/releases/latest", {
|
|
754
|
+
* owner: "effect-ts",
|
|
755
|
+
* repo: "effect",
|
|
756
|
+
* });
|
|
757
|
+
* return release.tag_name;
|
|
758
|
+
* });
|
|
759
|
+
*
|
|
760
|
+
* const layer = GitHubClient.layerFromToken({ token: Redacted.make("ghp_example") });
|
|
761
|
+
* Effect.runPromise(program.pipe(Effect.provide(layer)));
|
|
762
|
+
* ```
|
|
763
763
|
*
|
|
764
764
|
* @public
|
|
765
765
|
*/
|
|
@@ -782,10 +782,7 @@ export declare class GitHubClient extends GitHubClient_base {
|
|
|
782
782
|
* provides a provider instead of mutating the environment and a non-Actions
|
|
783
783
|
* consumer can source the token however it likes.
|
|
784
784
|
*
|
|
785
|
-
* Construction fails with core's `ConfigError`
|
|
786
|
-
* configured". The layer this replaces failed with a **wire-failure** error
|
|
787
|
-
* type instead, which is why one consumer wrapped it in `Layer.orDie` under a
|
|
788
|
-
* five-line comment explaining that the error did not mean what it said.
|
|
785
|
+
* Construction fails with core's `ConfigError` when no token is configured.
|
|
789
786
|
*/
|
|
790
787
|
static readonly layerFromConfig: (options?: Omit<GitHubClientOptions, "token"> & {
|
|
791
788
|
readonly name?: string | undefined;
|
|
@@ -810,17 +807,11 @@ export declare class GitHubClient extends GitHubClient_base {
|
|
|
810
807
|
* A double over recorded responses that **pages them for real**.
|
|
811
808
|
*
|
|
812
809
|
* @remarks
|
|
813
|
-
* The
|
|
814
|
-
*
|
|
815
|
-
* because it reimplements nothing: it builds a `PageSource` over the recorded
|
|
810
|
+
* The recorded-response double in this package. It reimplements no behavior:
|
|
811
|
+
* it builds a `PageSource` over the recorded
|
|
816
812
|
* array and hands it to the same `paginate` engine the live client uses, so
|
|
817
813
|
* `perPage` and `maxPages` cannot behave differently here than in production.
|
|
818
814
|
*
|
|
819
|
-
* The double it replaces named its pagination parameters `_options` and
|
|
820
|
-
* ignored them, returning every recorded page regardless of what the caller
|
|
821
|
-
* asked for — which made every truncation path in every consumer
|
|
822
|
-
* structurally untestable.
|
|
823
|
-
*
|
|
824
815
|
* `fixtures.requested` is appended to as the test runs, so a suite can assert
|
|
825
816
|
* which routes were walked and at what page size.
|
|
826
817
|
*/
|
|
@@ -875,33 +866,26 @@ declare const Repo_base: Context.ServiceClass<Repo, "@effected/github/Repo", Rep
|
|
|
875
866
|
* `{ owner, repo }` argument**, which is what makes a read like
|
|
876
867
|
* `GitHubRepository.defaultBranch` a single expression instead of a preamble.
|
|
877
868
|
*
|
|
878
|
-
* The
|
|
879
|
-
*
|
|
880
|
-
*
|
|
881
|
-
*
|
|
882
|
-
*
|
|
883
|
-
*
|
|
869
|
+
* The coordinate is a plain value. The only env-driven way to get one is
|
|
870
|
+
* {@link Repo.layerFromConfig}, which is named for being env-driven, and a
|
|
871
|
+
* program that acts on several repositories uses {@link Repo.provide}.
|
|
872
|
+
*
|
|
873
|
+
* The service shape is entirely one immutable value (a `RepoRef`), with no
|
|
874
|
+
* methods, so `Layer.succeed` is the correct test double.
|
|
884
875
|
*
|
|
885
876
|
* @example
|
|
886
877
|
* ```ts
|
|
887
|
-
* import { Repo } from "@effected/github";
|
|
878
|
+
* import { Repo, RepoRef } from "@effected/github";
|
|
888
879
|
* import { Effect } from "effect";
|
|
889
880
|
*
|
|
890
881
|
* declare const syncOne: Effect.Effect<void, never, Repo>;
|
|
891
|
-
* declare const targets: ReadonlyArray<
|
|
882
|
+
* declare const targets: ReadonlyArray<RepoRef>;
|
|
892
883
|
*
|
|
893
884
|
* const syncAll = Effect.forEach(targets, (target) => syncOne.pipe(Repo.provide(target)), {
|
|
894
885
|
* concurrency: 4,
|
|
895
886
|
* });
|
|
896
887
|
* ```
|
|
897
888
|
*
|
|
898
|
-
* **A deliberate exception to "no non-effectful members on a service shape."**
|
|
899
|
-
* This shape is entirely one immutable value: there is nothing to leave
|
|
900
|
-
* unimplemented, so `Layer.mock` has nothing to degrade and `Layer.succeed` is
|
|
901
|
-
* the correct double. The rule exists to stop a sync member from quietly
|
|
902
|
-
* degrading a *mixed* shape's partial mock. The boundary to hold: the moment a
|
|
903
|
-
* method appears here, this is a service again and the rule applies.
|
|
904
|
-
*
|
|
905
889
|
* @public
|
|
906
890
|
*/
|
|
907
891
|
export declare class Repo extends Repo_base {
|
|
@@ -943,10 +927,7 @@ declare const StorageRecordInput_base: Schema.Class<StorageRecordInput, Schema.S
|
|
|
943
927
|
* What to record about a published artifact.
|
|
944
928
|
*
|
|
945
929
|
* @remarks
|
|
946
|
-
* These are the fields the endpoint
|
|
947
|
-
* declared a `version` field the endpoint has no notion of — a fabricated key
|
|
948
|
-
* that a `Record<string, unknown>` body accepted silently and the generated
|
|
949
|
-
* types reject outright.
|
|
930
|
+
* These are the fields the storage-record endpoint accepts.
|
|
950
931
|
*
|
|
951
932
|
* @public
|
|
952
933
|
*/
|
|
@@ -957,9 +938,8 @@ export declare class StorageRecordInput extends StorageRecordInput_base {}
|
|
|
957
938
|
* @remarks
|
|
958
939
|
* The endpoint is org-scoped rather than repository-scoped, but the
|
|
959
940
|
* organization is resolved from {@link Repo}'s `owner` per call like every
|
|
960
|
-
* other resource
|
|
961
|
-
*
|
|
962
|
-
* case, exactly as it covers the cross-repository one.
|
|
941
|
+
* other resource. `Repo.provide` covers the cross-org case, exactly as it
|
|
942
|
+
* covers the cross-repository one.
|
|
963
943
|
*
|
|
964
944
|
* @public
|
|
965
945
|
*/
|
|
@@ -969,11 +949,16 @@ interface ArtifactMetadataShape {
|
|
|
969
949
|
}
|
|
970
950
|
declare const ArtifactMetadata_base: Context.ServiceClass<ArtifactMetadata, "@effected/github/ArtifactMetadata", ArtifactMetadataShape>;
|
|
971
951
|
/**
|
|
972
|
-
*
|
|
952
|
+
* Records where published artifacts are stored, at the organization level.
|
|
953
|
+
*
|
|
954
|
+
* @remarks
|
|
955
|
+
* Provide it with {@link ArtifactMetadata.layer}, which needs a `GitHubClient`;
|
|
956
|
+
* `createStorageRecord` also needs a `Repo` in `R`.
|
|
973
957
|
*
|
|
974
958
|
* @public
|
|
975
959
|
*/
|
|
976
960
|
export declare class ArtifactMetadata extends ArtifactMetadata_base {
|
|
961
|
+
/** The live service, built over a `GitHubClient`. */
|
|
977
962
|
static readonly layer: Layer.Layer<ArtifactMetadata, never, GitHubClient>;
|
|
978
963
|
/** An in-memory double; unstubbed members die naming themselves. */
|
|
979
964
|
static readonly makeTest: (overrides?: Partial<ArtifactMetadataShape>) => ArtifactMetadataShape;
|
|
@@ -1012,8 +997,7 @@ export declare class AttestationListEntry extends AttestationListEntry_base {}
|
|
|
1012
997
|
* @remarks
|
|
1013
998
|
* Upload and listing only. Building a statement, signing it and producing the
|
|
1014
999
|
* bundle belong to `@effected/sbom`; assembling those into a pipeline belongs to
|
|
1015
|
-
* the consumer.
|
|
1016
|
-
* package needed a mega-layer to test.
|
|
1000
|
+
* the consumer.
|
|
1017
1001
|
*
|
|
1018
1002
|
* @public
|
|
1019
1003
|
*/
|
|
@@ -1034,11 +1018,17 @@ interface AttestationShape {
|
|
|
1034
1018
|
}
|
|
1035
1019
|
declare const Attestation_base: Context.ServiceClass<Attestation, "@effected/github/Attestation", AttestationShape>;
|
|
1036
1020
|
/**
|
|
1037
|
-
*
|
|
1021
|
+
* Uploads signed attestation bundles to a repository and lists what is attested
|
|
1022
|
+
* about a subject digest.
|
|
1023
|
+
*
|
|
1024
|
+
* @remarks
|
|
1025
|
+
* Provide it with {@link Attestation.layer}, which needs a `GitHubClient`; each
|
|
1026
|
+
* method also needs a `Repo` in `R`.
|
|
1038
1027
|
*
|
|
1039
1028
|
* @public
|
|
1040
1029
|
*/
|
|
1041
1030
|
export declare class Attestation extends Attestation_base {
|
|
1031
|
+
/** The live service, built over a `GitHubClient`. */
|
|
1042
1032
|
static readonly layer: Layer.Layer<Attestation, never, GitHubClient>;
|
|
1043
1033
|
/** An in-memory double; unstubbed members die naming themselves. */
|
|
1044
1034
|
static readonly makeTest: (overrides?: Partial<AttestationShape>) => AttestationShape;
|
|
@@ -1084,8 +1074,8 @@ declare const CheckRunOutput_base: Schema.Class<CheckRunOutput, Schema.Struct<{
|
|
|
1084
1074
|
* GitHub's limits are **byte** limits, and that distinction is the whole reason
|
|
1085
1075
|
* this class exists rather than a struct: `✅`, `❌`, `🦋` and `│` cost several
|
|
1086
1076
|
* bytes each, so a character-count check passes while the request comes back
|
|
1087
|
-
* 422 saying *"summary exceeds a maximum bytesize of 65535"*.
|
|
1088
|
-
*
|
|
1077
|
+
* 422 saying *"summary exceeds a maximum bytesize of 65535"*. Use
|
|
1078
|
+
* {@link CheckRunOutput.truncated} to cut an output to fit.
|
|
1089
1079
|
*
|
|
1090
1080
|
* @public
|
|
1091
1081
|
*/
|
|
@@ -1140,7 +1130,11 @@ export declare class CheckRunRef extends CheckRunRef_base {}
|
|
|
1140
1130
|
*/
|
|
1141
1131
|
type ConcludeCheckRun = (conclusion: (typeof CheckConclusion.literals)[number], output?: CheckRunOutput) => Effect.Effect<void>;
|
|
1142
1132
|
/**
|
|
1143
|
-
*
|
|
1133
|
+
* Create, update and conclude GitHub check runs on a commit, including a
|
|
1134
|
+
* bracket that always concludes the run.
|
|
1135
|
+
*
|
|
1136
|
+
* @remarks
|
|
1137
|
+
* Every member resolves the target repository from the `Repo` service in `R`.
|
|
1144
1138
|
*
|
|
1145
1139
|
* @public
|
|
1146
1140
|
*/
|
|
@@ -1174,30 +1168,46 @@ interface CheckRunShape {
|
|
|
1174
1168
|
* Neither an interrupt nor an existing failure is replaced by whatever went
|
|
1175
1169
|
* wrong while reporting it.
|
|
1176
1170
|
*
|
|
1177
|
-
* `use` keeps its own `R` and its own `A`,
|
|
1178
|
-
*
|
|
1179
|
-
* self-contained layers just to use the bracket.
|
|
1171
|
+
* `use` keeps its own `R` and its own `A`, so the bracket composes with
|
|
1172
|
+
* whatever services the wrapped work needs.
|
|
1180
1173
|
*
|
|
1181
1174
|
* @example
|
|
1182
1175
|
* ```ts
|
|
1183
|
-
*
|
|
1176
|
+
* import { CheckRun, CheckRunOutput } from "@effected/github";
|
|
1177
|
+
* import { Effect } from "effect";
|
|
1178
|
+
*
|
|
1179
|
+
* const lintWithCheck = (sha: string) =>
|
|
1184
1180
|
* Effect.gen(function* () {
|
|
1185
|
-
* const
|
|
1186
|
-
* yield*
|
|
1187
|
-
*
|
|
1188
|
-
*
|
|
1189
|
-
*
|
|
1181
|
+
* const check = yield* CheckRun;
|
|
1182
|
+
* return yield* check.withCheckRun("lint", sha, (_id, conclude) =>
|
|
1183
|
+
* Effect.gen(function* () {
|
|
1184
|
+
* const findings = 3; // run the linter here
|
|
1185
|
+
* // An advisory result: record "neutral" instead of the default "success".
|
|
1186
|
+
* yield* conclude(
|
|
1187
|
+
* "neutral",
|
|
1188
|
+
* CheckRunOutput.make({ title: "lint", summary: `${findings} findings` }),
|
|
1189
|
+
* );
|
|
1190
|
+
* return findings;
|
|
1191
|
+
* }),
|
|
1192
|
+
* );
|
|
1193
|
+
* });
|
|
1190
1194
|
* ```
|
|
1191
1195
|
*/
|
|
1192
1196
|
readonly withCheckRun: <A, E, R>(name: string, headSha: string, use: (id: number, conclude: ConcludeCheckRun) => Effect.Effect<A, E, R>) => Effect.Effect<A, E | GitHubError, R | Repo>;
|
|
1193
1197
|
}
|
|
1194
1198
|
declare const CheckRun_base: Context.ServiceClass<CheckRun, "@effected/github/CheckRun", CheckRunShape>;
|
|
1195
1199
|
/**
|
|
1196
|
-
*
|
|
1200
|
+
* Create, update and conclude GitHub check runs, including the
|
|
1201
|
+
* {@link CheckRunShape.withCheckRun} bracket that always reaches a terminal state.
|
|
1202
|
+
*
|
|
1203
|
+
* @remarks
|
|
1204
|
+
* Provide it with {@link CheckRun.layer}, which needs a `GitHubClient`; each
|
|
1205
|
+
* method also needs a `Repo` in `R`.
|
|
1197
1206
|
*
|
|
1198
1207
|
* @public
|
|
1199
1208
|
*/
|
|
1200
1209
|
export declare class CheckRun extends CheckRun_base {
|
|
1210
|
+
/** The live service, built over a `GitHubClient`. */
|
|
1201
1211
|
static readonly layer: Layer.Layer<CheckRun, never, GitHubClient>;
|
|
1202
1212
|
/** An in-memory double; unstubbed members die naming themselves. */
|
|
1203
1213
|
static readonly makeTest: (overrides?: Partial<CheckRunShape>) => CheckRunShape;
|
|
@@ -1251,8 +1261,8 @@ interface CodeScanningShape {
|
|
|
1251
1261
|
* the repository's workflows afterwards. A caller that treats "default setup
|
|
1252
1262
|
* is off" as "no CodeQL workflow exists" will be wrong, and one that counts
|
|
1253
1263
|
* workflows to decide whether a repository has any CI will count that one.
|
|
1254
|
-
*
|
|
1255
|
-
*
|
|
1264
|
+
* Observed against a real organization, not inferred from the API
|
|
1265
|
+
* description.
|
|
1256
1266
|
*/
|
|
1257
1267
|
readonly configure: (setup: CodeScanningSetup) => Effect.Effect<void, GitHubError, Repo>;
|
|
1258
1268
|
/**
|
|
@@ -1268,12 +1278,19 @@ interface CodeScanningShape {
|
|
|
1268
1278
|
}
|
|
1269
1279
|
declare const CodeScanning_base: Context.ServiceClass<CodeScanning, "@effected/github/CodeScanning", CodeScanningShape>;
|
|
1270
1280
|
/**
|
|
1271
|
-
* CodeQL default setup
|
|
1281
|
+
* Configure CodeQL default setup and read the languages GitHub detects in a
|
|
1282
|
+
* repository.
|
|
1283
|
+
*
|
|
1284
|
+
* @remarks
|
|
1285
|
+
* Provide it with {@link CodeScanning.layer}, which needs a `GitHubClient`; each
|
|
1286
|
+
* method also needs a `Repo` in `R`.
|
|
1272
1287
|
*
|
|
1273
1288
|
* @public
|
|
1274
1289
|
*/
|
|
1275
1290
|
export declare class CodeScanning extends CodeScanning_base {
|
|
1276
1291
|
/**
|
|
1292
|
+
* The live service, built over a `GitHubClient`.
|
|
1293
|
+
*
|
|
1277
1294
|
* @remarks
|
|
1278
1295
|
* The callback is written `(client) => make(client)` rather than passed as
|
|
1279
1296
|
* `make` directly, and that is load-bearing: a static initializer runs while
|
|
@@ -1295,10 +1312,11 @@ export declare class CodeScanning extends CodeScanning_base {
|
|
|
1295
1312
|
* @public
|
|
1296
1313
|
*/
|
|
1297
1314
|
interface DeploymentEnvironmentInfo {
|
|
1315
|
+
/** The environment's name. */
|
|
1298
1316
|
readonly name: string;
|
|
1299
1317
|
}
|
|
1300
1318
|
/**
|
|
1301
|
-
*
|
|
1319
|
+
* Create or update, list and delete a repository's deployment environments.
|
|
1302
1320
|
*
|
|
1303
1321
|
* @public
|
|
1304
1322
|
*/
|
|
@@ -1330,12 +1348,30 @@ interface DeploymentEnvironmentShape {
|
|
|
1330
1348
|
}
|
|
1331
1349
|
declare const DeploymentEnvironment_base: Context.ServiceClass<DeploymentEnvironment, "@effected/github/DeploymentEnvironment", DeploymentEnvironmentShape>;
|
|
1332
1350
|
/**
|
|
1333
|
-
*
|
|
1351
|
+
* Create or update, list and delete a repository's deployment environments.
|
|
1352
|
+
*
|
|
1353
|
+
* @remarks
|
|
1354
|
+
* Provide it with {@link DeploymentEnvironment.layer}, which needs a
|
|
1355
|
+
* `GitHubClient`; each method also needs a `Repo` in `R`.
|
|
1356
|
+
*
|
|
1357
|
+
* @example
|
|
1358
|
+
* ```ts
|
|
1359
|
+
* import { DeploymentEnvironment } from "@effected/github";
|
|
1360
|
+
* import { Effect } from "effect";
|
|
1361
|
+
*
|
|
1362
|
+
* const program = Effect.gen(function* () {
|
|
1363
|
+
* const environments = yield* DeploymentEnvironment;
|
|
1364
|
+
* yield* environments.upsert("production", { wait_timer: 10 });
|
|
1365
|
+
* return yield* environments.list();
|
|
1366
|
+
* });
|
|
1367
|
+
* ```
|
|
1334
1368
|
*
|
|
1335
1369
|
* @public
|
|
1336
1370
|
*/
|
|
1337
1371
|
export declare class DeploymentEnvironment extends DeploymentEnvironment_base {
|
|
1338
1372
|
/**
|
|
1373
|
+
* The live service, built over a `GitHubClient`.
|
|
1374
|
+
*
|
|
1339
1375
|
* @remarks
|
|
1340
1376
|
* `(client) => make(client)` rather than `make`: a static initializer runs
|
|
1341
1377
|
* while the module body is still evaluating, so naming a `const` declared
|
|
@@ -1372,25 +1408,19 @@ interface GitBranchShape {
|
|
|
1372
1408
|
* Point `name` at `sha`, creating it if needed.
|
|
1373
1409
|
*
|
|
1374
1410
|
* @remarks
|
|
1375
|
-
* **One call, one intent.** Creating a branch that may already exist
|
|
1376
|
-
*
|
|
1377
|
-
*
|
|
1378
|
-
*
|
|
1379
|
-
*
|
|
1380
|
-
*
|
|
1381
|
-
* dance a few files away.
|
|
1382
|
-
*
|
|
1383
|
-
* This is one round trip in the common case and two in the raced one, and the
|
|
1384
|
-
* recovery **resets** rather than inheriting a branch a concurrent creator
|
|
1385
|
-
* rooted somewhere else — which is the semantics that comment was defending.
|
|
1411
|
+
* **One call, one intent.** Creating a branch that may already exist needs no
|
|
1412
|
+
* `exists` check, no catch and no second attempt: this creates the ref, and
|
|
1413
|
+
* when GitHub answers `alreadyExists` it resets the ref to `sha`. It is one
|
|
1414
|
+
* round trip in the common case and two in the raced one, and the recovery
|
|
1415
|
+
* **resets** rather than inheriting a branch a concurrent creator rooted
|
|
1416
|
+
* somewhere else. The result says which happened: `"created"` or `"reset"`.
|
|
1386
1417
|
*
|
|
1387
1418
|
* **A reset is observable, and open pull requests react to it.** Resetting a
|
|
1388
1419
|
* branch to its PR's base — `upsert(branch, targetHead)` — makes that PR's
|
|
1389
1420
|
* head equal its base, and GitHub **auto-closes a PR whose diff is empty**.
|
|
1390
|
-
* The window is invisible at this call site:
|
|
1391
|
-
*
|
|
1392
|
-
*
|
|
1393
|
-
* while the run reported success. When the end state is "the target head plus
|
|
1421
|
+
* The window is invisible at this call site: `upsert(releaseBranch, mainHead)`
|
|
1422
|
+
* followed a few seconds later by a commit that re-adds content can lose an
|
|
1423
|
+
* open release PR in between while the run reports success. When the end state is "the target head plus
|
|
1394
1424
|
* a commit", build the commit first — `GitCommit.get` the target for its
|
|
1395
1425
|
* `treeSha`, `createTree` on it, `createCommit` with the target as parent —
|
|
1396
1426
|
* and upsert **once**, straight to the finished sha, so the ref never rests
|
|
@@ -1427,12 +1457,32 @@ interface GitBranchShape {
|
|
|
1427
1457
|
}
|
|
1428
1458
|
declare const GitBranch_base: Context.ServiceClass<GitBranch, "@effected/github/GitBranch", GitBranchShape>;
|
|
1429
1459
|
/**
|
|
1430
|
-
*
|
|
1460
|
+
* Create, move, read and delete branch refs through GitHub's Git Database API,
|
|
1461
|
+
* with an `upsert` that needs no existence check.
|
|
1462
|
+
*
|
|
1463
|
+
* @remarks
|
|
1464
|
+
* Provide it with {@link GitBranch.layer}, which needs a `GitHubClient`; each
|
|
1465
|
+
* method also needs a `Repo` in `R`. Branch names are accepted as `main`,
|
|
1466
|
+
* `heads/main` or `refs/heads/main`.
|
|
1467
|
+
*
|
|
1468
|
+
* @example
|
|
1469
|
+
* ```ts
|
|
1470
|
+
* import { GitBranch } from "@effected/github";
|
|
1471
|
+
* import { Effect } from "effect";
|
|
1472
|
+
*
|
|
1473
|
+
* const ensureBranch = (name: string, sha: string) =>
|
|
1474
|
+
* Effect.gen(function* () {
|
|
1475
|
+
* const branches = yield* GitBranch;
|
|
1476
|
+
* return yield* branches.upsert(name, sha); // "created" | "reset"
|
|
1477
|
+
* });
|
|
1478
|
+
* ```
|
|
1431
1479
|
*
|
|
1432
1480
|
* @public
|
|
1433
1481
|
*/
|
|
1434
1482
|
export declare class GitBranch extends GitBranch_base {
|
|
1435
1483
|
/**
|
|
1484
|
+
* The live service, built over a `GitHubClient`.
|
|
1485
|
+
*
|
|
1436
1486
|
* @remarks
|
|
1437
1487
|
* The callback is written `(client) => make(client)` rather than passed as
|
|
1438
1488
|
* `make` directly, and that is load-bearing: a static initializer runs while
|
|
@@ -1499,10 +1549,8 @@ declare const CommitRef_base: Schema.Class<CommitRef, Schema.Struct<{
|
|
|
1499
1549
|
* A commit, projected to the three fields callers actually use.
|
|
1500
1550
|
*
|
|
1501
1551
|
* @remarks
|
|
1502
|
-
* `treeSha` is here because
|
|
1503
|
-
*
|
|
1504
|
-
* wants a tree SHA, not a commit SHA"* — the same eight lines written twice, in
|
|
1505
|
-
* two files, for one string.
|
|
1552
|
+
* `treeSha` is here because the Git Data API's `base_tree` wants a tree SHA,
|
|
1553
|
+
* not a commit SHA.
|
|
1506
1554
|
*
|
|
1507
1555
|
* @public
|
|
1508
1556
|
*/
|
|
@@ -1544,9 +1592,7 @@ interface GitCommitShape {
|
|
|
1544
1592
|
* `GitBranch.upsert` straight to the finished commit. Do **not** spell a
|
|
1545
1593
|
* rebase as `upsert(branch, targetHead)` followed by `commitFiles`: between
|
|
1546
1594
|
* those calls the branch *is* the target head, an open pull request from it
|
|
1547
|
-
* has an empty diff, and GitHub auto-closes PRs in that state
|
|
1548
|
-
* consumer lost its open release PR to that ~3-second window while the run
|
|
1549
|
-
* went green.
|
|
1595
|
+
* has an empty diff, and GitHub auto-closes PRs in that state.
|
|
1550
1596
|
*/
|
|
1551
1597
|
readonly commitFiles: (options: {
|
|
1552
1598
|
readonly branch: string;
|
|
@@ -1556,11 +1602,33 @@ interface GitCommitShape {
|
|
|
1556
1602
|
}
|
|
1557
1603
|
declare const GitCommit_base: Context.ServiceClass<GitCommit, "@effected/github/GitCommit", GitCommitShape>;
|
|
1558
1604
|
/**
|
|
1559
|
-
*
|
|
1605
|
+
* Read commits and build trees and commits through GitHub's Git Database API,
|
|
1606
|
+
* including a one-call "commit these files onto a branch".
|
|
1607
|
+
*
|
|
1608
|
+
* @remarks
|
|
1609
|
+
* Provide it with {@link GitCommit.layer}, which needs a `GitHubClient`; each
|
|
1610
|
+
* method also needs a `Repo` in `R`. No local git runs: this is the REST API,
|
|
1611
|
+
* not `@effected/git`.
|
|
1612
|
+
*
|
|
1613
|
+
* @example
|
|
1614
|
+
* ```ts
|
|
1615
|
+
* import { FileContent, GitCommit } from "@effected/github";
|
|
1616
|
+
* import { Effect } from "effect";
|
|
1617
|
+
*
|
|
1618
|
+
* const writeNotes = Effect.gen(function* () {
|
|
1619
|
+
* const commits = yield* GitCommit;
|
|
1620
|
+
* return yield* commits.commitFiles({
|
|
1621
|
+
* branch: "docs/notes",
|
|
1622
|
+
* message: "docs: add notes",
|
|
1623
|
+
* changes: [FileContent.make({ path: "NOTES.md", content: "# Notes\n" })],
|
|
1624
|
+
* }); // the new commit's sha
|
|
1625
|
+
* });
|
|
1626
|
+
* ```
|
|
1560
1627
|
*
|
|
1561
1628
|
* @public
|
|
1562
1629
|
*/
|
|
1563
1630
|
export declare class GitCommit extends GitCommit_base {
|
|
1631
|
+
/** The live service, built over a `GitHubClient`. */
|
|
1564
1632
|
static readonly layer: Layer.Layer<GitCommit, never, GitHubClient>;
|
|
1565
1633
|
/** An in-memory double; unstubbed members die naming themselves. */
|
|
1566
1634
|
static readonly makeTest: (overrides?: Partial<GitCommitShape>) => GitCommitShape;
|
|
@@ -1671,9 +1739,8 @@ export declare class InstallationToken extends InstallationToken_base {
|
|
|
1671
1739
|
* Whether this token is spent, `skew` before its stated expiry.
|
|
1672
1740
|
*
|
|
1673
1741
|
* @remarks
|
|
1674
|
-
*
|
|
1675
|
-
*
|
|
1676
|
-
* started answering 401 with no explanation.
|
|
1742
|
+
* `skew` defaults to one minute, so a token is treated as spent slightly early
|
|
1743
|
+
* rather than answering 401 mid-request.
|
|
1677
1744
|
*/
|
|
1678
1745
|
isExpired(nowMillis: number, skew?: Duration.Duration): boolean;
|
|
1679
1746
|
/** The committer identity a commit made with this token should carry. */
|
|
@@ -1689,10 +1756,10 @@ declare const BotIdentity_base: Schema.Class<BotIdentity, Schema.Struct<{
|
|
|
1689
1756
|
* Who a bot commits as.
|
|
1690
1757
|
*
|
|
1691
1758
|
* @remarks
|
|
1692
|
-
* A **pure class**, not a service member
|
|
1693
|
-
*
|
|
1694
|
-
*
|
|
1695
|
-
*
|
|
1759
|
+
* A **pure class**, not a `GitHubApp` service member: a synchronous method on
|
|
1760
|
+
* the service shape would be required in every `Layer.mock` and would silently
|
|
1761
|
+
* degrade every partial double to a full implementation. Get one from
|
|
1762
|
+
* `InstallationToken.botIdentity` or `AppIdentity.botIdentity`.
|
|
1696
1763
|
*
|
|
1697
1764
|
* @public
|
|
1698
1765
|
*/
|
|
@@ -1781,9 +1848,28 @@ declare const GitHubApp_base: Context.ServiceClass<GitHubApp, "@effected/github/
|
|
|
1781
1848
|
* `@effected/commands`' service, for the same reason.
|
|
1782
1849
|
*
|
|
1783
1850
|
* The JWT signer is `universal-github-app-jwt` — zero dependencies, and
|
|
1784
|
-
* `@octokit/auth-app`'s own JWT dependency.
|
|
1785
|
-
*
|
|
1786
|
-
*
|
|
1851
|
+
* `@octokit/auth-app`'s own JWT dependency.
|
|
1852
|
+
*
|
|
1853
|
+
* @example
|
|
1854
|
+
* ```ts
|
|
1855
|
+
* import { GitHubApp, GitHubClient } from "@effected/github";
|
|
1856
|
+
* import { Effect, Redacted } from "effect";
|
|
1857
|
+
*
|
|
1858
|
+
* const program = Effect.gen(function* () {
|
|
1859
|
+
* const client = yield* GitHubClient;
|
|
1860
|
+
* const accessible = yield* client.request("GET /installation/repositories", { per_page: 1 });
|
|
1861
|
+
* return accessible.total_count;
|
|
1862
|
+
* });
|
|
1863
|
+
*
|
|
1864
|
+
* // Mints an installation token on build, re-mints before expiry, revokes on release.
|
|
1865
|
+
* const layer = GitHubApp.clientLayer({
|
|
1866
|
+
* appId: "12345",
|
|
1867
|
+
* privateKey: Redacted.make("-----BEGIN PRIVATE KEY-----\n..."),
|
|
1868
|
+
* owner: "my-org",
|
|
1869
|
+
* });
|
|
1870
|
+
*
|
|
1871
|
+
* Effect.runPromise(Effect.provide(program, layer));
|
|
1872
|
+
* ```
|
|
1787
1873
|
*
|
|
1788
1874
|
* @public
|
|
1789
1875
|
*/
|
|
@@ -1806,11 +1892,12 @@ export declare class GitHubApp extends GitHubApp_base {
|
|
|
1806
1892
|
* The token's lifetime is the layer's scope: it is minted on build and
|
|
1807
1893
|
* **revoked on release**, best-effort, so a workflow does not leave live
|
|
1808
1894
|
* credentials behind. It is also **re-minted automatically** a minute before
|
|
1809
|
-
* it expires,
|
|
1810
|
-
*
|
|
1811
|
-
* started answering 401 with nothing explaining why.
|
|
1895
|
+
* it expires, so a long-running program does not start answering 401 when
|
|
1896
|
+
* the hour ends.
|
|
1812
1897
|
*
|
|
1813
|
-
*
|
|
1898
|
+
* Building the layer mints the first token, so a misconfigured app fails
|
|
1899
|
+
* construction with `GitHubAppError`. After that, a failure to obtain
|
|
1900
|
+
* credentials surfaces to the caller as a
|
|
1814
1901
|
* `GitHubError { kind: "unauthorized" }` carrying the `GitHubAppError` as its
|
|
1815
1902
|
* cause: from a request's point of view, "could not authenticate" is an
|
|
1816
1903
|
* authorization failure, and widening every method's error channel to say so
|
|
@@ -1837,22 +1924,19 @@ interface GitHubAppShape {
|
|
|
1837
1924
|
* Mint an installation token.
|
|
1838
1925
|
*
|
|
1839
1926
|
* @remarks
|
|
1840
|
-
*
|
|
1841
|
-
*
|
|
1927
|
+
* `installationId` is used when given; otherwise the installation is
|
|
1928
|
+
* discovered from `owner`, or from the app's only installation.
|
|
1842
1929
|
*/
|
|
1843
1930
|
readonly token: (request: TokenRequest) => Effect.Effect<InstallationToken, GitHubAppError>;
|
|
1844
1931
|
/**
|
|
1845
|
-
* Mint a token that is revoked when the scope closes.
|
|
1932
|
+
* Mint a token that is revoked, best-effort, when the scope closes.
|
|
1846
1933
|
*
|
|
1847
1934
|
* @remarks
|
|
1848
|
-
*
|
|
1935
|
+
* Mints through `token` and releases through `revoke`.
|
|
1849
1936
|
*/
|
|
1850
1937
|
readonly scopedToken: (request: TokenRequest) => Effect.Effect<InstallationToken, GitHubAppError, Scope.Scope>;
|
|
1851
1938
|
/**
|
|
1852
1939
|
* Revoke a token now.
|
|
1853
|
-
*
|
|
1854
|
-
* @remarks
|
|
1855
|
-
* Used by the token bridge's `post` phase. Touches: nothing else.
|
|
1856
1940
|
*/
|
|
1857
1941
|
readonly revoke: (token: Redacted.Redacted<string>) => Effect.Effect<void, GitHubAppError>;
|
|
1858
1942
|
/**
|
|
@@ -1861,17 +1945,12 @@ interface GitHubAppShape {
|
|
|
1861
1945
|
* @remarks
|
|
1862
1946
|
* Supply `installationToken` when you have one: `GET /users/{slug}[bot]`
|
|
1863
1947
|
* rejects an app JWT, so without it the lookup runs unauthenticated at
|
|
1864
|
-
* GitHub's 60-requests-per-hour-per-IP limit.
|
|
1948
|
+
* GitHub's 60-requests-per-hour-per-IP limit.
|
|
1865
1949
|
*/
|
|
1866
1950
|
readonly identity: (request: AppCredentials & {
|
|
1867
1951
|
readonly installationToken?: Redacted.Redacted<string> | undefined;
|
|
1868
1952
|
}) => Effect.Effect<AppIdentity, GitHubAppError>;
|
|
1869
|
-
/**
|
|
1870
|
-
* Every installation of the app.
|
|
1871
|
-
*
|
|
1872
|
-
* @remarks
|
|
1873
|
-
* Touches: nothing else.
|
|
1874
|
-
*/
|
|
1953
|
+
/** Every installation of the app. */
|
|
1875
1954
|
readonly installations: (credentials: AppCredentials) => Effect.Effect<ReadonlyArray<Installation>, GitHubAppError>;
|
|
1876
1955
|
}
|
|
1877
1956
|
//#endregion
|
|
@@ -1949,14 +2028,14 @@ declare const CommitComparison_base: Schema.Class<CommitComparison, Schema.Struc
|
|
|
1949
2028
|
*/
|
|
1950
2029
|
export declare class CommitComparison extends CommitComparison_base {}
|
|
1951
2030
|
/**
|
|
1952
|
-
*
|
|
2031
|
+
* Read commits, list them, compare two refs and list the files a commit touched.
|
|
1953
2032
|
*
|
|
1954
2033
|
* @public
|
|
1955
2034
|
*/
|
|
1956
2035
|
interface GitHubCommitShape {
|
|
1957
|
-
/**
|
|
2036
|
+
/** Read one commit by sha or ref. */
|
|
1958
2037
|
readonly get: (ref: string) => Effect.Effect<CommitSummary, GitHubError, Repo>;
|
|
1959
|
-
/**
|
|
2038
|
+
/** List commits reachable from `ref` (the default branch when omitted), newest first, optionally limited to those touching `path`. */
|
|
1960
2039
|
readonly list: (options?: {
|
|
1961
2040
|
readonly ref?: string | undefined;
|
|
1962
2041
|
readonly path?: string | undefined;
|
|
@@ -1968,8 +2047,9 @@ interface GitHubCommitShape {
|
|
|
1968
2047
|
* @remarks
|
|
1969
2048
|
* GitHub paginates this **by commit**, while the single-commit read paginates
|
|
1970
2049
|
* **by file** at 300 per page — so a one-commit comparison is permanently
|
|
1971
|
-
* truncated at 300 files no matter what you pass. That is GitHub's
|
|
1972
|
-
*
|
|
2050
|
+
* truncated at 300 files no matter what you pass. That is GitHub's
|
|
2051
|
+
* constraint; use {@link GitHubCommitShape.changedFiles} to page every file
|
|
2052
|
+
* of one commit.
|
|
1973
2053
|
*/
|
|
1974
2054
|
readonly compare: (base: string, head: string) => Effect.Effect<CommitComparison, GitHubError, Repo>;
|
|
1975
2055
|
/** The files one commit touched, paginated by file. */
|
|
@@ -1979,11 +2059,30 @@ interface GitHubCommitShape {
|
|
|
1979
2059
|
}
|
|
1980
2060
|
declare const GitHubCommit_base: Context.ServiceClass<GitHubCommit, "@effected/github/GitHubCommit", GitHubCommitShape>;
|
|
1981
2061
|
/**
|
|
1982
|
-
*
|
|
2062
|
+
* Read commits, compare refs and list changed files through GitHub's commits
|
|
2063
|
+
* API.
|
|
2064
|
+
*
|
|
2065
|
+
* @remarks
|
|
2066
|
+
* Provide it with {@link GitHubCommit.layer}, which needs a `GitHubClient`; each
|
|
2067
|
+
* method also needs a `Repo` in `R`. For commits as Git Database objects (trees,
|
|
2068
|
+
* parents), use `GitCommit` instead.
|
|
2069
|
+
*
|
|
2070
|
+
* @example
|
|
2071
|
+
* ```ts
|
|
2072
|
+
* import { GitHubCommit } from "@effected/github";
|
|
2073
|
+
* import { Effect } from "effect";
|
|
2074
|
+
*
|
|
2075
|
+
* const changedSinceMain = Effect.gen(function* () {
|
|
2076
|
+
* const commits = yield* GitHubCommit;
|
|
2077
|
+
* const comparison = yield* commits.compare("main", "feature");
|
|
2078
|
+
* return comparison.files.map((file) => file.path);
|
|
2079
|
+
* });
|
|
2080
|
+
* ```
|
|
1983
2081
|
*
|
|
1984
2082
|
* @public
|
|
1985
2083
|
*/
|
|
1986
2084
|
export declare class GitHubCommit extends GitHubCommit_base {
|
|
2085
|
+
/** The live service, built over a `GitHubClient`. */
|
|
1987
2086
|
static readonly layer: Layer.Layer<GitHubCommit, never, GitHubClient>;
|
|
1988
2087
|
/** An in-memory double; unstubbed members die naming themselves. */
|
|
1989
2088
|
static readonly makeTest: (overrides?: Partial<GitHubCommitShape>) => GitHubCommitShape;
|
|
@@ -1993,7 +2092,7 @@ export declare class GitHubCommit extends GitHubCommit_base {
|
|
|
1993
2092
|
//#endregion
|
|
1994
2093
|
//#region src/GitHubContent.d.ts
|
|
1995
2094
|
/**
|
|
1996
|
-
*
|
|
2095
|
+
* Read a text file out of a repository at a ref.
|
|
1997
2096
|
*
|
|
1998
2097
|
* @public
|
|
1999
2098
|
*/
|
|
@@ -2001,6 +2100,11 @@ interface GitHubContentShape {
|
|
|
2001
2100
|
/**
|
|
2002
2101
|
* A text file's contents at `ref`, or the default branch when `ref` is
|
|
2003
2102
|
* omitted.
|
|
2103
|
+
*
|
|
2104
|
+
* @remarks
|
|
2105
|
+
* Fails `notFound` when the path does not exist, and `rejected` when it is a
|
|
2106
|
+
* directory, is not a regular file, or is too large for the contents API
|
|
2107
|
+
* (which answers an empty body above roughly a megabyte).
|
|
2004
2108
|
*/
|
|
2005
2109
|
readonly getFile: (path: string, options?: {
|
|
2006
2110
|
readonly ref?: string | undefined;
|
|
@@ -2012,11 +2116,29 @@ interface GitHubContentShape {
|
|
|
2012
2116
|
}
|
|
2013
2117
|
declare const GitHubContent_base: Context.ServiceClass<GitHubContent, "@effected/github/GitHubContent", GitHubContentShape>;
|
|
2014
2118
|
/**
|
|
2015
|
-
*
|
|
2119
|
+
* Read a text file out of a repository at a ref, with absence as an `Option`
|
|
2120
|
+
* when you want it.
|
|
2121
|
+
*
|
|
2122
|
+
* @remarks
|
|
2123
|
+
* Provide it with {@link GitHubContent.layer}, which needs a `GitHubClient`;
|
|
2124
|
+
* each method also needs a `Repo` in `R`.
|
|
2125
|
+
*
|
|
2126
|
+
* @example
|
|
2127
|
+
* ```ts
|
|
2128
|
+
* import { GitHubContent } from "@effected/github";
|
|
2129
|
+
* import { Effect, Option } from "effect";
|
|
2130
|
+
*
|
|
2131
|
+
* const readme = Effect.gen(function* () {
|
|
2132
|
+
* const content = yield* GitHubContent;
|
|
2133
|
+
* const file = yield* content.getFileOption("README.md", { ref: "main" });
|
|
2134
|
+
* return Option.getOrElse(file, () => "");
|
|
2135
|
+
* });
|
|
2136
|
+
* ```
|
|
2016
2137
|
*
|
|
2017
2138
|
* @public
|
|
2018
2139
|
*/
|
|
2019
2140
|
export declare class GitHubContent extends GitHubContent_base {
|
|
2141
|
+
/** The live service, built over a `GitHubClient`. */
|
|
2020
2142
|
static readonly layer: Layer.Layer<GitHubContent, never, GitHubClient>;
|
|
2021
2143
|
/** An in-memory double; unstubbed members die naming themselves. */
|
|
2022
2144
|
static readonly makeTest: (overrides?: Partial<GitHubContentShape>) => GitHubContentShape;
|
|
@@ -2035,11 +2157,9 @@ declare const CommentMarker_base: Schema.Class<CommentMarker, Schema.Struct<{
|
|
|
2035
2157
|
* The hidden marker that makes a comment findable again.
|
|
2036
2158
|
*
|
|
2037
2159
|
* @remarks
|
|
2038
|
-
*
|
|
2039
|
-
*
|
|
2040
|
-
*
|
|
2041
|
-
* testable without a client, and the library has no opinion about whose comments
|
|
2042
|
-
* these are.
|
|
2160
|
+
* The marker is `<!-- namespace:key -->`, an HTML comment appended to the body.
|
|
2161
|
+
* The namespace is the caller's, so the library has no opinion about whose
|
|
2162
|
+
* comments these are, and a marker is testable without a client.
|
|
2043
2163
|
*
|
|
2044
2164
|
* @public
|
|
2045
2165
|
*/
|
|
@@ -2055,13 +2175,14 @@ declare const CommentRecord_base: Schema.Class<CommentRecord, Schema.Struct<{
|
|
|
2055
2175
|
readonly url: Schema.String;
|
|
2056
2176
|
}>, {}>;
|
|
2057
2177
|
/**
|
|
2058
|
-
* A comment this package wrote or found.
|
|
2178
|
+
* A comment this package wrote or found: its id, body and web URL.
|
|
2059
2179
|
*
|
|
2060
2180
|
* @public
|
|
2061
2181
|
*/
|
|
2062
2182
|
export declare class CommentRecord extends CommentRecord_base {}
|
|
2063
2183
|
/**
|
|
2064
|
-
*
|
|
2184
|
+
* Post, update, find and delete comments on a pull request or issue, including
|
|
2185
|
+
* a "sticky" comment kept current through a marker.
|
|
2065
2186
|
*
|
|
2066
2187
|
* @public
|
|
2067
2188
|
*/
|
|
@@ -2080,22 +2201,42 @@ interface PullRequestCommentShape {
|
|
|
2080
2201
|
* Find the marked comment.
|
|
2081
2202
|
*
|
|
2082
2203
|
* @remarks
|
|
2083
|
-
* **Paginates
|
|
2084
|
-
*
|
|
2085
|
-
* update posted a new comment instead.
|
|
2204
|
+
* **Paginates**, so the marker is found on a busy pull request too; pass
|
|
2205
|
+
* `page` to bound the walk.
|
|
2086
2206
|
*/
|
|
2087
2207
|
readonly find: (issueNumber: number, marker: CommentMarker, options?: {
|
|
2088
2208
|
readonly page?: PageOptions | undefined;
|
|
2089
2209
|
}) => Effect.Effect<Option.Option<CommentRecord>, GitHubError, Repo>;
|
|
2210
|
+
/** Delete a comment by id. */
|
|
2090
2211
|
readonly delete: (commentId: number) => Effect.Effect<void, GitHubError, Repo>;
|
|
2091
2212
|
}
|
|
2092
2213
|
declare const PullRequestComment_base: Context.ServiceClass<PullRequestComment, "@effected/github/PullRequestComment", PullRequestCommentShape>;
|
|
2093
2214
|
/**
|
|
2094
|
-
*
|
|
2215
|
+
* Post, update, find and delete comments on a pull request or issue, including
|
|
2216
|
+
* a "sticky" comment kept current through a `CommentMarker`.
|
|
2217
|
+
*
|
|
2218
|
+
* @remarks
|
|
2219
|
+
* Provide it with {@link PullRequestComment.layer}, which needs a `GitHubClient`;
|
|
2220
|
+
* each method also needs a `Repo` in `R`.
|
|
2221
|
+
*
|
|
2222
|
+
* @example
|
|
2223
|
+
* ```ts
|
|
2224
|
+
* import { CommentMarker, PullRequestComment } from "@effected/github";
|
|
2225
|
+
* import { Effect } from "effect";
|
|
2226
|
+
*
|
|
2227
|
+
* const marker = CommentMarker.make({ namespace: "my-action", key: "report" });
|
|
2228
|
+
*
|
|
2229
|
+
* const report = (pullNumber: number, body: string) =>
|
|
2230
|
+
* Effect.gen(function* () {
|
|
2231
|
+
* const comments = yield* PullRequestComment;
|
|
2232
|
+
* return yield* comments.upsert(pullNumber, marker, body); // edits the marked comment in place
|
|
2233
|
+
* });
|
|
2234
|
+
* ```
|
|
2095
2235
|
*
|
|
2096
2236
|
* @public
|
|
2097
2237
|
*/
|
|
2098
2238
|
export declare class PullRequestComment extends PullRequestComment_base {
|
|
2239
|
+
/** The live service, built over a `GitHubClient`. */
|
|
2099
2240
|
static readonly layer: Layer.Layer<PullRequestComment, never, GitHubClient>;
|
|
2100
2241
|
/** An in-memory double; unstubbed members die naming themselves. */
|
|
2101
2242
|
static readonly makeTest: (overrides?: Partial<PullRequestCommentShape>) => PullRequestCommentShape;
|
|
@@ -2131,10 +2272,8 @@ declare const LinkedIssue_base: Schema.Class<LinkedIssue, Schema.Struct<{
|
|
|
2131
2272
|
* branch or commit messages.
|
|
2132
2273
|
*
|
|
2133
2274
|
* @remarks
|
|
2134
|
-
*
|
|
2135
|
-
*
|
|
2136
|
-
* with the field aliased twice to get it — the single largest duplicated
|
|
2137
|
-
* document in the survey.
|
|
2275
|
+
* Resolved by querying the pull request's closing references twice, once with
|
|
2276
|
+
* `userLinkedOnly`, and marking the issues present in the second result.
|
|
2138
2277
|
*/
|
|
2139
2278
|
readonly userLinked: Schema.Boolean;
|
|
2140
2279
|
}>, {}>;
|
|
@@ -2162,19 +2301,28 @@ declare const CommentOnceResult_base: Schema.Class<CommentOnceResult, Schema.Str
|
|
|
2162
2301
|
*/
|
|
2163
2302
|
export declare class CommentOnceResult extends CommentOnceResult_base {}
|
|
2164
2303
|
/**
|
|
2165
|
-
*
|
|
2304
|
+
* Read, list, close and comment on issues, and resolve the issues a pull
|
|
2305
|
+
* request closes.
|
|
2166
2306
|
*
|
|
2167
2307
|
* @public
|
|
2168
2308
|
*/
|
|
2169
2309
|
interface GitHubIssueShape {
|
|
2310
|
+
/** Read one issue. Fails `notFound` when it does not exist. */
|
|
2170
2311
|
readonly get: (number: number) => Effect.Effect<IssueInfo, GitHubError, Repo>;
|
|
2312
|
+
/**
|
|
2313
|
+
* List issues, paginated. `state` is omitted from the request when unset, so GitHub's default applies.
|
|
2314
|
+
*
|
|
2315
|
+
* @remarks
|
|
2316
|
+
* GitHub's issues endpoint also returns pull requests; this does not filter them out.
|
|
2317
|
+
*/
|
|
2171
2318
|
readonly list: (options?: {
|
|
2172
2319
|
readonly state?: "open" | "closed" | "all" | undefined;
|
|
2173
2320
|
readonly labels?: ReadonlyArray<string> | undefined;
|
|
2174
2321
|
readonly page?: PageOptions | undefined;
|
|
2175
2322
|
}) => Effect.Effect<ReadonlyArray<IssueInfo>, GitHubError, Repo>;
|
|
2323
|
+
/** Close an issue. `reason` is sent as `state_reason` when given; unset, GitHub chooses. */
|
|
2176
2324
|
readonly close: (number: number, reason?: "completed" | "not_planned") => Effect.Effect<void, GitHubError, Repo>;
|
|
2177
|
-
/** Post a comment. */
|
|
2325
|
+
/** Post a comment and return its id. */
|
|
2178
2326
|
readonly comment: (number: number, body: string) => Effect.Effect<number, GitHubError, Repo>;
|
|
2179
2327
|
/**
|
|
2180
2328
|
* Post a marked comment once: create it, or skip if it already exists.
|
|
@@ -2204,10 +2352,10 @@ interface GitHubIssueShape {
|
|
|
2204
2352
|
* Has `prNumber` already been cross-referenced on this issue?
|
|
2205
2353
|
*
|
|
2206
2354
|
* @remarks
|
|
2207
|
-
*
|
|
2208
|
-
*
|
|
2355
|
+
* An idempotence guard over the issue's timeline, so that re-running a
|
|
2356
|
+
* workflow does not comment twice.
|
|
2209
2357
|
*
|
|
2210
|
-
* Two hazards before building on it
|
|
2358
|
+
* Two hazards before building on it:
|
|
2211
2359
|
*
|
|
2212
2360
|
* - **An issue obtained from `linkedIssues(pr)` answers `true` from the
|
|
2213
2361
|
* outset** — the closing link itself puts a cross-reference on the
|
|
@@ -2224,11 +2372,30 @@ interface GitHubIssueShape {
|
|
|
2224
2372
|
}
|
|
2225
2373
|
declare const GitHubIssue_base: Context.ServiceClass<GitHubIssue, "@effected/github/GitHubIssue", GitHubIssueShape>;
|
|
2226
2374
|
/**
|
|
2227
|
-
*
|
|
2375
|
+
* Read, list, close and comment on issues, and resolve the issues a pull
|
|
2376
|
+
* request closes.
|
|
2377
|
+
*
|
|
2378
|
+
* @remarks
|
|
2379
|
+
* Provide it with {@link GitHubIssue.layer}, which needs a `GitHubClient`; each
|
|
2380
|
+
* method also needs a `Repo` in `R`.
|
|
2381
|
+
*
|
|
2382
|
+
* @example
|
|
2383
|
+
* ```ts
|
|
2384
|
+
* import { GitHubIssue } from "@effected/github";
|
|
2385
|
+
* import { Effect } from "effect";
|
|
2386
|
+
*
|
|
2387
|
+
* const closeWontFix = (number: number) =>
|
|
2388
|
+
* Effect.gen(function* () {
|
|
2389
|
+
* const issues = yield* GitHubIssue;
|
|
2390
|
+
* yield* issues.comment(number, "Closing as not planned.");
|
|
2391
|
+
* yield* issues.close(number, "not_planned");
|
|
2392
|
+
* });
|
|
2393
|
+
* ```
|
|
2228
2394
|
*
|
|
2229
2395
|
* @public
|
|
2230
2396
|
*/
|
|
2231
2397
|
export declare class GitHubIssue extends GitHubIssue_base {
|
|
2398
|
+
/** The live service, built over a `GitHubClient`. */
|
|
2232
2399
|
static readonly layer: Layer.Layer<GitHubIssue, never, GitHubClient>;
|
|
2233
2400
|
/** An in-memory double; unstubbed members die naming themselves. */
|
|
2234
2401
|
static readonly makeTest: (overrides?: Partial<GitHubIssueShape>) => GitHubIssueShape;
|
|
@@ -2250,7 +2417,7 @@ declare const ReleaseInfo_base: Schema.Class<ReleaseInfo, Schema.Struct<{
|
|
|
2250
2417
|
readonly uploadUrl: Schema.String;
|
|
2251
2418
|
}>, {}>;
|
|
2252
2419
|
/**
|
|
2253
|
-
* A release.
|
|
2420
|
+
* A release, projected to the fields callers read.
|
|
2254
2421
|
*
|
|
2255
2422
|
* @public
|
|
2256
2423
|
*/
|
|
@@ -2270,11 +2437,12 @@ declare const ReleaseAsset_base: Schema.Class<ReleaseAsset, Schema.Struct<{
|
|
|
2270
2437
|
*/
|
|
2271
2438
|
export declare class ReleaseAsset extends ReleaseAsset_base {}
|
|
2272
2439
|
/**
|
|
2273
|
-
*
|
|
2440
|
+
* Create, read, list and update releases, and upload and list their assets.
|
|
2274
2441
|
*
|
|
2275
2442
|
* @public
|
|
2276
2443
|
*/
|
|
2277
2444
|
interface GitHubReleaseShape {
|
|
2445
|
+
/** Create a release for `tag`. Unset fields are left to GitHub's defaults. */
|
|
2278
2446
|
readonly create: (input: {
|
|
2279
2447
|
readonly tag: string;
|
|
2280
2448
|
readonly name?: string | undefined;
|
|
@@ -2283,12 +2451,15 @@ interface GitHubReleaseShape {
|
|
|
2283
2451
|
readonly prerelease?: boolean | undefined;
|
|
2284
2452
|
readonly generateReleaseNotes?: boolean | undefined;
|
|
2285
2453
|
}) => Effect.Effect<ReleaseInfo, GitHubError, Repo>;
|
|
2454
|
+
/** Read the release for `tag`. Fails `notFound` when there is none. */
|
|
2286
2455
|
readonly getByTag: (tag: string) => Effect.Effect<ReleaseInfo, GitHubError, Repo>;
|
|
2287
2456
|
/** As {@link GitHubReleaseShape.getByTag}, with absence as `Option.none`. */
|
|
2288
2457
|
readonly getByTagOption: (tag: string) => Effect.Effect<Option.Option<ReleaseInfo>, GitHubError, Repo>;
|
|
2458
|
+
/** List releases, paginated. */
|
|
2289
2459
|
readonly list: (options?: {
|
|
2290
2460
|
readonly page?: PageOptions | undefined;
|
|
2291
2461
|
}) => Effect.Effect<ReadonlyArray<ReleaseInfo>, GitHubError, Repo>;
|
|
2462
|
+
/** Patch a release by id; only the fields given are sent. */
|
|
2292
2463
|
readonly update: (id: number, patch: {
|
|
2293
2464
|
readonly name?: string | undefined;
|
|
2294
2465
|
readonly body?: string | undefined;
|
|
@@ -2317,17 +2488,36 @@ interface GitHubReleaseShape {
|
|
|
2317
2488
|
readonly contentType: string;
|
|
2318
2489
|
readonly label?: string | undefined;
|
|
2319
2490
|
}) => Effect.Effect<ReleaseAsset, GitHubError, Repo>;
|
|
2491
|
+
/** List a release's assets, paginated. */
|
|
2320
2492
|
readonly listAssets: (id: number, options?: {
|
|
2321
2493
|
readonly page?: PageOptions | undefined;
|
|
2322
2494
|
}) => Effect.Effect<ReadonlyArray<ReleaseAsset>, GitHubError, Repo>;
|
|
2323
2495
|
}
|
|
2324
2496
|
declare const GitHubRelease_base: Context.ServiceClass<GitHubRelease, "@effected/github/GitHubRelease", GitHubReleaseShape>;
|
|
2325
2497
|
/**
|
|
2326
|
-
*
|
|
2498
|
+
* Create, read, list and update GitHub releases, and upload and list their
|
|
2499
|
+
* assets.
|
|
2500
|
+
*
|
|
2501
|
+
* @remarks
|
|
2502
|
+
* Provide it with {@link GitHubRelease.layer}, which needs a `GitHubClient`;
|
|
2503
|
+
* each method also needs a `Repo` in `R`.
|
|
2504
|
+
*
|
|
2505
|
+
* @example
|
|
2506
|
+
* ```ts
|
|
2507
|
+
* import { GitHubRelease } from "@effected/github";
|
|
2508
|
+
* import { Effect } from "effect";
|
|
2509
|
+
*
|
|
2510
|
+
* const publish = Effect.gen(function* () {
|
|
2511
|
+
* const releases = yield* GitHubRelease;
|
|
2512
|
+
* const release = yield* releases.create({ tag: "v1.2.3", generateReleaseNotes: true });
|
|
2513
|
+
* return release.url;
|
|
2514
|
+
* });
|
|
2515
|
+
* ```
|
|
2327
2516
|
*
|
|
2328
2517
|
* @public
|
|
2329
2518
|
*/
|
|
2330
2519
|
export declare class GitHubRelease extends GitHubRelease_base {
|
|
2520
|
+
/** The live service, built over a `GitHubClient`. */
|
|
2331
2521
|
static readonly layer: Layer.Layer<GitHubRelease, never, GitHubClient>;
|
|
2332
2522
|
/** An in-memory double; unstubbed members die naming themselves. */
|
|
2333
2523
|
static readonly makeTest: (overrides?: Partial<GitHubReleaseShape>) => GitHubReleaseShape;
|
|
@@ -2340,11 +2530,9 @@ export declare class GitHubRelease extends GitHubRelease_base {
|
|
|
2340
2530
|
* Everything GitHub reports about a repository.
|
|
2341
2531
|
*
|
|
2342
2532
|
* @remarks
|
|
2343
|
-
* The **generated** response type
|
|
2344
|
-
*
|
|
2345
|
-
*
|
|
2346
|
-
* existed, verbatim, in the OpenAPI types the package now leans on. Re-declaring
|
|
2347
|
-
* them would have been the same mistake with our name on it.
|
|
2533
|
+
* The **generated** response type for `GET /repos/{owner}/{repo}`, not a
|
|
2534
|
+
* hand-written projection, so every field GitHub documents is available with
|
|
2535
|
+
* its documented type.
|
|
2348
2536
|
*
|
|
2349
2537
|
* @public
|
|
2350
2538
|
*/
|
|
@@ -2363,10 +2551,9 @@ type RepositoryPatch = Omit<Params<"PATCH /repos/{owner}/{repo}">, "owner" | "re
|
|
|
2363
2551
|
* The shape you actually have when you are applying only what a user
|
|
2364
2552
|
* configured. Octokit's generated params spell an optional field as
|
|
2365
2553
|
* `has_issues?: boolean`, **not** `has_issues?: boolean | undefined`, so under
|
|
2366
|
-
* `exactOptionalPropertyTypes`
|
|
2367
|
-
*
|
|
2368
|
-
*
|
|
2369
|
-
* it into one.
|
|
2554
|
+
* `exactOptionalPropertyTypes` a `Partial<T>` built from your own settings
|
|
2555
|
+
* schema does not assign to `RepositoryPatch` at all. This type does, and
|
|
2556
|
+
* {@link repositoryPatch} turns it into one.
|
|
2370
2557
|
*
|
|
2371
2558
|
* @public
|
|
2372
2559
|
*/
|
|
@@ -2377,10 +2564,7 @@ type RepositoryPatchDraft = { readonly [K in keyof RepositoryPatch]?: Repository
|
|
|
2377
2564
|
*
|
|
2378
2565
|
* @remarks
|
|
2379
2566
|
* The supported spelling for "apply only what was configured" — the natural
|
|
2380
|
-
* shape for a sync action,
|
|
2381
|
-
* Without it a consumer under the recommended tsconfig is quietly pushed toward
|
|
2382
|
-
* `as`, which is a real cost in a package whose stated design property is that
|
|
2383
|
-
* the route is the key and there are no casts.
|
|
2567
|
+
* shape for a sync action, without a cast at the call site.
|
|
2384
2568
|
*
|
|
2385
2569
|
* Dropping the key rather than sending `undefined` is what the wire needs:
|
|
2386
2570
|
* `PATCH` treats an absent field as "leave it alone", while an explicit `null`
|
|
@@ -2433,12 +2617,9 @@ export declare const SECURITY_ANALYSIS_STATUS_FIELDS: ReadonlySet<string>;
|
|
|
2433
2617
|
* `PATCH /repos/{owner}/{repo}` route accepts none of them, and
|
|
2434
2618
|
* `has_discussions` is the treacherous one: the REST **read** returns it, so
|
|
2435
2619
|
* routing its write to the PATCH looks symmetric, but the PATCH silently
|
|
2436
|
-
* ignores unknown body fields and answers 200
|
|
2437
|
-
*
|
|
2438
|
-
*
|
|
2439
|
-
*
|
|
2440
|
-
* Field names verified against `UpdateRepositoryInput` by live introspection,
|
|
2441
|
-
* 2026-08-15.
|
|
2620
|
+
* ignores unknown body fields and answers 200, so the write would look applied
|
|
2621
|
+
* while the repository never changed. Setting any of these forces a second
|
|
2622
|
+
* round trip to learn the repository's node id.
|
|
2442
2623
|
*
|
|
2443
2624
|
* @public
|
|
2444
2625
|
*/
|
|
@@ -2490,7 +2671,8 @@ interface AppliedSettings {
|
|
|
2490
2671
|
readonly graphql: ReadonlyArray<string>;
|
|
2491
2672
|
}
|
|
2492
2673
|
/**
|
|
2493
|
-
*
|
|
2674
|
+
* Read and update a repository's settings, and look up its default branch, node
|
|
2675
|
+
* id and owner type.
|
|
2494
2676
|
*
|
|
2495
2677
|
* @public
|
|
2496
2678
|
*/
|
|
@@ -2503,8 +2685,7 @@ interface GitHubRepositoryShape {
|
|
|
2503
2685
|
* The default branch's name.
|
|
2504
2686
|
*
|
|
2505
2687
|
* @remarks
|
|
2506
|
-
*
|
|
2507
|
-
* plus eleven lines of code to read this one string.
|
|
2688
|
+
* Reads the repository payload and returns `default_branch`.
|
|
2508
2689
|
*/
|
|
2509
2690
|
readonly defaultBranch: Effect.Effect<string, GitHubError, Repo>;
|
|
2510
2691
|
/**
|
|
@@ -2512,7 +2693,7 @@ interface GitHubRepositoryShape {
|
|
|
2512
2693
|
*
|
|
2513
2694
|
* @remarks
|
|
2514
2695
|
* Needed as `repositoryId` by the `createLinkedBranch` and `createPullRequest`
|
|
2515
|
-
* mutations
|
|
2696
|
+
* mutations.
|
|
2516
2697
|
*/
|
|
2517
2698
|
readonly nodeId: Effect.Effect<string, GitHubError, Repo>;
|
|
2518
2699
|
/**
|
|
@@ -2536,13 +2717,14 @@ interface GitHubRepositoryShape {
|
|
|
2536
2717
|
* @remarks
|
|
2537
2718
|
* `updateSettings` is the thin, faithfully-typed PATCH and returns what
|
|
2538
2719
|
* GitHub then reports. This is the **applicator**: it takes an open map,
|
|
2539
|
-
* routes each key to whichever API can actually set it, and returns
|
|
2720
|
+
* routes each key to whichever API can actually set it, and returns an
|
|
2721
|
+
* {@link AppliedSettings} naming the keys that were sent through each.
|
|
2540
2722
|
*
|
|
2541
|
-
*
|
|
2542
|
-
*
|
|
2543
|
-
* `updateRepository`, which addresses a repository by **node
|
|
2544
|
-
* touching
|
|
2545
|
-
* is the common case.
|
|
2723
|
+
* Three settings — `has_sponsorships`, `has_pull_requests` and
|
|
2724
|
+
* `has_discussions` ({@link GRAPHQL_ONLY_SETTINGS}) — are only reachable
|
|
2725
|
+
* through GraphQL's `updateRepository`, which addresses a repository by **node
|
|
2726
|
+
* id**. So a map touching any of them costs an extra read; a map touching none
|
|
2727
|
+
* does not, which is the common case.
|
|
2546
2728
|
*
|
|
2547
2729
|
* The map is open by design. GitHub's settings surface is large and moving,
|
|
2548
2730
|
* and a closed type here would date the package — but it also means a typo is
|
|
@@ -2553,11 +2735,31 @@ interface GitHubRepositoryShape {
|
|
|
2553
2735
|
}
|
|
2554
2736
|
declare const GitHubRepository_base: Context.ServiceClass<GitHubRepository, "@effected/github/GitHubRepository", GitHubRepositoryShape>;
|
|
2555
2737
|
/**
|
|
2556
|
-
*
|
|
2738
|
+
* Read and update a repository's settings, including settings only GraphQL can
|
|
2739
|
+
* write, and look up its default branch, node id and owner type.
|
|
2740
|
+
*
|
|
2741
|
+
* @remarks
|
|
2742
|
+
* Provide it with {@link GitHubRepository.layer}, which needs a `GitHubClient`;
|
|
2743
|
+
* every member also needs a `Repo` in `R`. `settings`, `defaultBranch`, `nodeId`
|
|
2744
|
+
* and `ownerType` are `Effect` values, not functions.
|
|
2745
|
+
*
|
|
2746
|
+
* @example
|
|
2747
|
+
* ```ts
|
|
2748
|
+
* import { GitHubRepository } from "@effected/github";
|
|
2749
|
+
* import { Effect } from "effect";
|
|
2750
|
+
*
|
|
2751
|
+
* const program = Effect.gen(function* () {
|
|
2752
|
+
* const repository = yield* GitHubRepository;
|
|
2753
|
+
* const branch = yield* repository.defaultBranch;
|
|
2754
|
+
* const applied = yield* repository.applySettings({ has_wiki: false, has_discussions: true });
|
|
2755
|
+
* return { branch, applied }; // applied.rest, applied.graphql
|
|
2756
|
+
* });
|
|
2757
|
+
* ```
|
|
2557
2758
|
*
|
|
2558
2759
|
* @public
|
|
2559
2760
|
*/
|
|
2560
2761
|
export declare class GitHubRepository extends GitHubRepository_base {
|
|
2762
|
+
/** The live service, built over a `GitHubClient`. */
|
|
2561
2763
|
static readonly layer: Layer.Layer<GitHubRepository, never, GitHubClient>;
|
|
2562
2764
|
/** An in-memory double; unstubbed members die naming themselves. */
|
|
2563
2765
|
static readonly makeTest: (overrides?: Partial<GitHubRepositoryShape>) => GitHubRepositoryShape;
|
|
@@ -2597,7 +2799,7 @@ export declare class SemverTag extends SemverTag_base {}
|
|
|
2597
2799
|
*
|
|
2598
2800
|
* @remarks
|
|
2599
2801
|
* The default covers the three shapes `@effected/workspaces`' `ReleaseTag`
|
|
2600
|
-
* produces
|
|
2802
|
+
* produces: `v1.2.3`, `pkg@v1.2.3` and
|
|
2601
2803
|
* `@scope/pkg@1.2.3`. Taking the substring after the **last** `@` is what makes
|
|
2602
2804
|
* the scoped form work, since the scope itself contains one.
|
|
2603
2805
|
*
|
|
@@ -2633,7 +2835,7 @@ interface GitTagShape {
|
|
|
2633
2835
|
readonly upsert: (tag: string, sha: string) => Effect.Effect<void, GitHubError, Repo>;
|
|
2634
2836
|
/** Delete the tag ref. */
|
|
2635
2837
|
readonly delete: (tag: string) => Effect.Effect<void, GitHubError, Repo>;
|
|
2636
|
-
/** Every tag,
|
|
2838
|
+
/** Every tag, in GitHub's order. `prefix` filters client-side. */
|
|
2637
2839
|
readonly list: (options?: {
|
|
2638
2840
|
readonly prefix?: string | undefined;
|
|
2639
2841
|
readonly page?: PageOptions | undefined;
|
|
@@ -2649,10 +2851,9 @@ interface GitTagShape {
|
|
|
2649
2851
|
* The newest version-shaped tag.
|
|
2650
2852
|
*
|
|
2651
2853
|
* @remarks
|
|
2652
|
-
*
|
|
2653
|
-
* `
|
|
2654
|
-
*
|
|
2655
|
-
* a single pass over the page stream with no round trips at all.
|
|
2854
|
+
* Parsing and comparison are both synchronous in `@effected/semver`
|
|
2855
|
+
* (`parseResult`, `compare`), so this is a single pass over the page stream
|
|
2856
|
+
* with no extra round trips.
|
|
2656
2857
|
*
|
|
2657
2858
|
* **"Newest" means highest version, not most recent.** That is the right
|
|
2658
2859
|
* answer for a single-versioned repository and the wrong instrument for a
|
|
@@ -2660,8 +2861,7 @@ interface GitTagShape {
|
|
|
2660
2861
|
* ordering and recency are unrelated: a `pkg-a@2.0.0` tag outranks a
|
|
2661
2862
|
* `pkg-b@1.4.0` cut yesterday, so the result can sit several releases behind
|
|
2662
2863
|
* the actual head and never move. Nothing about the failure is visible —
|
|
2663
|
-
* a stale-but-plausible tag comes back
|
|
2664
|
-
* boundary two releases back, permanently. In a monorepo, filter by the
|
|
2864
|
+
* a stale-but-plausible tag comes back. In a monorepo, filter by the
|
|
2665
2865
|
* package's tag prefix (see {@link LatestSemverOptions}) so the comparison
|
|
2666
2866
|
* runs within one version line, or order by tagged-commit date instead.
|
|
2667
2867
|
*/
|
|
@@ -2669,11 +2869,29 @@ interface GitTagShape {
|
|
|
2669
2869
|
}
|
|
2670
2870
|
declare const GitTag_base: Context.ServiceClass<GitTag, "@effected/github/GitTag", GitTagShape>;
|
|
2671
2871
|
/**
|
|
2672
|
-
*
|
|
2872
|
+
* Create, move, resolve, list and delete tag refs through GitHub's Git Database
|
|
2873
|
+
* API, and find the newest version-shaped tag.
|
|
2874
|
+
*
|
|
2875
|
+
* @remarks
|
|
2876
|
+
* Provide it with {@link GitTag.layer}, which needs a `GitHubClient`; each
|
|
2877
|
+
* method also needs a `Repo` in `R`.
|
|
2878
|
+
*
|
|
2879
|
+
* @example
|
|
2880
|
+
* ```ts
|
|
2881
|
+
* import { GitTag } from "@effected/github";
|
|
2882
|
+
* import { Effect, Option } from "effect";
|
|
2883
|
+
*
|
|
2884
|
+
* const latest = Effect.gen(function* () {
|
|
2885
|
+
* const tags = yield* GitTag;
|
|
2886
|
+
* const newest = yield* tags.latestSemver({ prefix: "v" });
|
|
2887
|
+
* return Option.map(newest, (tag) => tag.version.toString());
|
|
2888
|
+
* });
|
|
2889
|
+
* ```
|
|
2673
2890
|
*
|
|
2674
2891
|
* @public
|
|
2675
2892
|
*/
|
|
2676
2893
|
export declare class GitTag extends GitTag_base {
|
|
2894
|
+
/** The live service, built over a `GitHubClient`. */
|
|
2677
2895
|
static readonly layer: Layer.Layer<GitTag, never, GitHubClient>;
|
|
2678
2896
|
/** An in-memory double; unstubbed members die naming themselves. */
|
|
2679
2897
|
static readonly makeTest: (overrides?: Partial<GitTagShape>) => GitTagShape;
|
|
@@ -2722,28 +2940,32 @@ declare const PullRequestInfo_base: Schema.Class<PullRequestInfo, Schema.Struct<
|
|
|
2722
2940
|
*
|
|
2723
2941
|
* @remarks
|
|
2724
2942
|
* This is the **domain** shape, and the only pull-request type this package
|
|
2725
|
-
* exports.
|
|
2726
|
-
* `
|
|
2727
|
-
*
|
|
2728
|
-
* link `html_url`, where this class flattens them to `head`/`headSha` and
|
|
2729
|
-
* spells it `url`. Reading the wrong one produces code that typechecks against
|
|
2730
|
-
* a member set the boundary will never hand it. If you are writing a test
|
|
2731
|
-
* double or a fixture, this is the type you build.
|
|
2943
|
+
* exports. It flattens GitHub's nested `head`/`base` objects to
|
|
2944
|
+
* `head`/`headSha` and `base`/`baseSha`, and spells the link `url`. If you are
|
|
2945
|
+
* writing a test double or a fixture, this is the type you build.
|
|
2732
2946
|
*
|
|
2733
2947
|
* @public
|
|
2734
2948
|
*/
|
|
2735
2949
|
export declare class PullRequestInfo extends PullRequestInfo_base {}
|
|
2736
|
-
/**
|
|
2950
|
+
/**
|
|
2951
|
+
* What {@link PullRequestShape.upsert} did.
|
|
2952
|
+
*
|
|
2953
|
+
* @public
|
|
2954
|
+
*/
|
|
2737
2955
|
interface UpsertedPullRequest {
|
|
2956
|
+
/** The pull request, as created or as updated. */
|
|
2738
2957
|
readonly pullRequest: PullRequestInfo;
|
|
2958
|
+
/** `true` when a new pull request was opened, `false` when an open one was updated. */
|
|
2739
2959
|
readonly created: boolean;
|
|
2740
2960
|
}
|
|
2741
2961
|
/**
|
|
2742
|
-
*
|
|
2962
|
+
* Read, list, create, update, merge and label pull requests, and control
|
|
2963
|
+
* auto-merge.
|
|
2743
2964
|
*
|
|
2744
2965
|
* @public
|
|
2745
2966
|
*/
|
|
2746
2967
|
interface PullRequestShape {
|
|
2968
|
+
/** Read one pull request. Fails `notFound` when it does not exist. */
|
|
2747
2969
|
readonly get: (number: number) => Effect.Effect<PullRequestInfo, GitHubError, Repo>;
|
|
2748
2970
|
/**
|
|
2749
2971
|
* Open, closed or all pull requests, optionally filtered.
|
|
@@ -2752,10 +2974,8 @@ interface PullRequestShape {
|
|
|
2752
2974
|
* `head` accepts **either** the qualified `owner:ref` GitHub's filter wants
|
|
2753
2975
|
* or a bare `ref`, which is qualified with the current repo's owner on the
|
|
2754
2976
|
* way out. So for a pull request opened **from the current repository**,
|
|
2755
|
-
* feeding this method `PullRequestInfo.head`
|
|
2756
|
-
*
|
|
2757
|
-
* list client-side because the raw REST route ignores an unqualified ref no
|
|
2758
|
-
* longer needs to.
|
|
2977
|
+
* feeding this method `PullRequestInfo.head` (the bare branch name)
|
|
2978
|
+
* round-trips correctly; GitHub's own route ignores an unqualified ref.
|
|
2759
2979
|
*
|
|
2760
2980
|
* **The round trip does not hold for a fork-originated pull request.**
|
|
2761
2981
|
* `PullRequestInfo` projects only the ref and drops the source owner, so
|
|
@@ -2777,9 +2997,7 @@ interface PullRequestShape {
|
|
|
2777
2997
|
* Each entry is a full {@link CommitFile} — path **and** status, plus the
|
|
2778
2998
|
* line counts and any pre-rename path — the same projection
|
|
2779
2999
|
* `GitHubCommit.changedFiles` returns, because GitHub answers both
|
|
2780
|
-
* endpoints with the same `diff-entry` shape.
|
|
2781
|
-
* to the path alone, and consumers who needed the status fell back to a raw
|
|
2782
|
-
* route.
|
|
3000
|
+
* endpoints with the same `diff-entry` shape.
|
|
2783
3001
|
*/
|
|
2784
3002
|
readonly listFiles: (number: number, options?: {
|
|
2785
3003
|
readonly page?: PageOptions | undefined;
|
|
@@ -2788,14 +3006,12 @@ interface PullRequestShape {
|
|
|
2788
3006
|
* The pull requests associated with a commit.
|
|
2789
3007
|
*
|
|
2790
3008
|
* @remarks
|
|
2791
|
-
*
|
|
2792
|
-
* method and one consumer never found it — dropping to a raw octokit callback
|
|
2793
|
-
* with the only `noExplicitAny` suppression in the entire survey. It also
|
|
2794
|
-
* paginates now, which the previous one did not.
|
|
3009
|
+
* Paginated: pass `page` to bound the walk.
|
|
2795
3010
|
*/
|
|
2796
3011
|
readonly listAssociatedWithCommit: (sha: string, options?: {
|
|
2797
3012
|
readonly page?: PageOptions | undefined;
|
|
2798
3013
|
}) => Effect.Effect<ReadonlyArray<PullRequestInfo>, GitHubError, Repo>;
|
|
3014
|
+
/** Open a pull request from `head` into `base`. */
|
|
2799
3015
|
readonly create: (input: {
|
|
2800
3016
|
readonly title: string;
|
|
2801
3017
|
readonly head: string;
|
|
@@ -2803,13 +3019,20 @@ interface PullRequestShape {
|
|
|
2803
3019
|
readonly body?: string | undefined;
|
|
2804
3020
|
readonly draft?: boolean | undefined;
|
|
2805
3021
|
}) => Effect.Effect<PullRequestInfo, GitHubError, Repo>;
|
|
3022
|
+
/** Patch a pull request; only the fields given are sent. */
|
|
2806
3023
|
readonly update: (number: number, patch: {
|
|
2807
3024
|
readonly title?: string | undefined;
|
|
2808
3025
|
readonly body?: string | undefined;
|
|
2809
3026
|
readonly state?: "open" | "closed" | undefined;
|
|
2810
3027
|
readonly base?: string | undefined;
|
|
2811
3028
|
}) => Effect.Effect<PullRequestInfo, GitHubError, Repo>;
|
|
2812
|
-
/**
|
|
3029
|
+
/**
|
|
3030
|
+
* Update the open pull request for `head`→`base`, or open one.
|
|
3031
|
+
*
|
|
3032
|
+
* @remarks
|
|
3033
|
+
* When a pull request is already open, only `title` and `body` are updated;
|
|
3034
|
+
* `draft` applies only when a new pull request is opened.
|
|
3035
|
+
*/
|
|
2813
3036
|
readonly upsert: (input: {
|
|
2814
3037
|
readonly title: string;
|
|
2815
3038
|
readonly head: string;
|
|
@@ -2817,12 +3040,15 @@ interface PullRequestShape {
|
|
|
2817
3040
|
readonly body?: string | undefined;
|
|
2818
3041
|
readonly draft?: boolean | undefined;
|
|
2819
3042
|
}) => Effect.Effect<UpsertedPullRequest, GitHubError, Repo>;
|
|
3043
|
+
/** Merge a pull request and return the merge commit sha. `method` defaults to GitHub's choice. */
|
|
2820
3044
|
readonly merge: (number: number, options?: {
|
|
2821
3045
|
readonly method?: "merge" | "squash" | "rebase" | undefined;
|
|
2822
3046
|
readonly commitTitle?: string | undefined;
|
|
2823
3047
|
readonly commitMessage?: string | undefined;
|
|
2824
3048
|
}) => Effect.Effect<string, GitHubError, Repo>;
|
|
3049
|
+
/** Add labels to a pull request (as an issue), keeping the ones already there. */
|
|
2825
3050
|
readonly addLabels: (number: number, labels: ReadonlyArray<string>) => Effect.Effect<void, GitHubError, Repo>;
|
|
3051
|
+
/** Request reviews from users and/or teams (team slugs). */
|
|
2826
3052
|
readonly requestReviewers: (number: number, reviewers: {
|
|
2827
3053
|
readonly users?: ReadonlyArray<string> | undefined;
|
|
2828
3054
|
readonly teams?: ReadonlyArray<string> | undefined;
|
|
@@ -2831,20 +3057,42 @@ interface PullRequestShape {
|
|
|
2831
3057
|
* Turn auto-merge on or off.
|
|
2832
3058
|
*
|
|
2833
3059
|
* @remarks
|
|
2834
|
-
* An explicit call, not an option on `create`/`update
|
|
2835
|
-
*
|
|
2836
|
-
*
|
|
2837
|
-
* create had failed.
|
|
3060
|
+
* An explicit call, not an option on `create`/`update`, so a create that
|
|
3061
|
+
* worked is never reported as failed because auto-merge was refused. Pass
|
|
3062
|
+
* `"off"` to disable it.
|
|
2838
3063
|
*/
|
|
2839
3064
|
readonly setAutoMerge: (pullRequest: PullRequestInfo, method: "merge" | "squash" | "rebase" | "off") => Effect.Effect<void, GitHubGraphQLError, Repo>;
|
|
2840
3065
|
}
|
|
2841
3066
|
declare const PullRequest_base: Context.ServiceClass<PullRequest, "@effected/github/PullRequest", PullRequestShape>;
|
|
2842
3067
|
/**
|
|
2843
|
-
*
|
|
3068
|
+
* Read, list, create, update, merge and label pull requests, and control
|
|
3069
|
+
* auto-merge.
|
|
3070
|
+
*
|
|
3071
|
+
* @remarks
|
|
3072
|
+
* Provide it with {@link PullRequest.layer}, which needs a `GitHubClient`; each
|
|
3073
|
+
* method also needs a `Repo` in `R`.
|
|
3074
|
+
*
|
|
3075
|
+
* @example
|
|
3076
|
+
* ```ts
|
|
3077
|
+
* import { PullRequest } from "@effected/github";
|
|
3078
|
+
* import { Effect } from "effect";
|
|
3079
|
+
*
|
|
3080
|
+
* const openOrUpdate = Effect.gen(function* () {
|
|
3081
|
+
* const pulls = yield* PullRequest;
|
|
3082
|
+
* const { pullRequest, created } = yield* pulls.upsert({
|
|
3083
|
+
* title: "chore: release",
|
|
3084
|
+
* head: "changeset-release/main",
|
|
3085
|
+
* base: "main",
|
|
3086
|
+
* });
|
|
3087
|
+
* yield* pulls.setAutoMerge(pullRequest, "squash");
|
|
3088
|
+
* return created;
|
|
3089
|
+
* });
|
|
3090
|
+
* ```
|
|
2844
3091
|
*
|
|
2845
3092
|
* @public
|
|
2846
3093
|
*/
|
|
2847
3094
|
export declare class PullRequest extends PullRequest_base {
|
|
3095
|
+
/** The live service, built over a `GitHubClient`. */
|
|
2848
3096
|
static readonly layer: Layer.Layer<PullRequest, never, GitHubClient>;
|
|
2849
3097
|
/** An in-memory double; unstubbed members die naming themselves. */
|
|
2850
3098
|
static readonly makeTest: (overrides?: Partial<PullRequestShape>) => PullRequestShape;
|
|
@@ -2875,10 +3123,12 @@ type SecretScope = "actions" | "dependabot" | "codespaces";
|
|
|
2875
3123
|
* @public
|
|
2876
3124
|
*/
|
|
2877
3125
|
interface SecretInfo {
|
|
3126
|
+
/** The secret's name. */
|
|
2878
3127
|
readonly name: string;
|
|
2879
3128
|
}
|
|
2880
3129
|
/**
|
|
2881
|
-
*
|
|
3130
|
+
* Write, list and delete Actions, Dependabot and Codespaces secrets on a
|
|
3131
|
+
* repository, and Actions secrets on its environments.
|
|
2882
3132
|
*
|
|
2883
3133
|
* @public
|
|
2884
3134
|
*/
|
|
@@ -2898,7 +3148,8 @@ interface RepositorySecretShape {
|
|
|
2898
3148
|
}
|
|
2899
3149
|
declare const RepositorySecret_base: Context.ServiceClass<RepositorySecret, "@effected/github/RepositorySecret", RepositorySecretShape>;
|
|
2900
3150
|
/**
|
|
2901
|
-
*
|
|
3151
|
+
* Write, list and delete repository and environment secrets, encrypted
|
|
3152
|
+
* client-side before they leave the process.
|
|
2902
3153
|
*
|
|
2903
3154
|
* @remarks
|
|
2904
3155
|
* Every write is a **two-step**: fetch the store's public key, then `PUT` a
|
|
@@ -2914,10 +3165,27 @@ declare const RepositorySecret_base: Context.ServiceClass<RepositorySecret, "@ef
|
|
|
2914
3165
|
* the type; this module performs the single `Redacted.value` unwrap, at the
|
|
2915
3166
|
* moment of encryption, and the sealed box is what continues.
|
|
2916
3167
|
*
|
|
3168
|
+
* Provide it with {@link RepositorySecret.layer}, which needs a `GitHubClient`;
|
|
3169
|
+
* each method also needs a `Repo` in `R`.
|
|
3170
|
+
*
|
|
3171
|
+
* @example
|
|
3172
|
+
* ```ts
|
|
3173
|
+
* import { RepositorySecret } from "@effected/github";
|
|
3174
|
+
* import { Effect, Redacted } from "effect";
|
|
3175
|
+
*
|
|
3176
|
+
* const program = Effect.gen(function* () {
|
|
3177
|
+
* const secrets = yield* RepositorySecret;
|
|
3178
|
+
* yield* secrets.set("NPM_TOKEN", Redacted.make("npm_example"), "actions");
|
|
3179
|
+
* return yield* secrets.list("actions"); // names only; values are never returned
|
|
3180
|
+
* });
|
|
3181
|
+
* ```
|
|
3182
|
+
*
|
|
2917
3183
|
* @public
|
|
2918
3184
|
*/
|
|
2919
3185
|
export declare class RepositorySecret extends RepositorySecret_base {
|
|
2920
3186
|
/**
|
|
3187
|
+
* The live service, built over a `GitHubClient`.
|
|
3188
|
+
*
|
|
2921
3189
|
* @remarks
|
|
2922
3190
|
* `(client) => make(client)` rather than `make`: a static initializer runs
|
|
2923
3191
|
* while the module body is still evaluating, so naming a `const` declared
|
|
@@ -2932,7 +3200,9 @@ export declare class RepositorySecret extends RepositorySecret_base {
|
|
|
2932
3200
|
//#endregion
|
|
2933
3201
|
//#region src/RepositorySecurity.d.ts
|
|
2934
3202
|
/**
|
|
2935
|
-
*
|
|
3203
|
+
* Read and toggle the three repository security features that have their own
|
|
3204
|
+
* endpoints: Dependabot alerts, Dependabot security fixes and private
|
|
3205
|
+
* vulnerability reporting.
|
|
2936
3206
|
*
|
|
2937
3207
|
* @public
|
|
2938
3208
|
*/
|
|
@@ -2952,7 +3222,8 @@ interface RepositorySecurityShape {
|
|
|
2952
3222
|
}
|
|
2953
3223
|
declare const RepositorySecurity_base: Context.ServiceClass<RepositorySecurity, "@effected/github/RepositorySecurity", RepositorySecurityShape>;
|
|
2954
3224
|
/**
|
|
2955
|
-
*
|
|
3225
|
+
* Read and toggle Dependabot alerts, Dependabot security fixes and private
|
|
3226
|
+
* vulnerability reporting.
|
|
2956
3227
|
*
|
|
2957
3228
|
* @remarks
|
|
2958
3229
|
* These are **not** `security_and_analysis` fields and cannot ride along on the
|
|
@@ -2975,10 +3246,28 @@ declare const RepositorySecurity_base: Context.ServiceClass<RepositorySecurity,
|
|
|
2975
3246
|
* every other failure still fails. A 404 from the other two is a real failure
|
|
2976
3247
|
* and stays one, which is why the mapping is not applied uniformly.
|
|
2977
3248
|
*
|
|
3249
|
+
* Provide it with {@link RepositorySecurity.layer}, which needs a
|
|
3250
|
+
* `GitHubClient`; each method also needs a `Repo` in `R`.
|
|
3251
|
+
*
|
|
3252
|
+
* @example
|
|
3253
|
+
* ```ts
|
|
3254
|
+
* import { RepositorySecurity } from "@effected/github";
|
|
3255
|
+
* import { Effect } from "effect";
|
|
3256
|
+
*
|
|
3257
|
+
* const harden = Effect.gen(function* () {
|
|
3258
|
+
* const security = yield* RepositorySecurity;
|
|
3259
|
+
* yield* security.setVulnerabilityAlerts(true);
|
|
3260
|
+
* yield* security.setPrivateVulnerabilityReporting(true);
|
|
3261
|
+
* return yield* security.vulnerabilityAlerts(); // true
|
|
3262
|
+
* });
|
|
3263
|
+
* ```
|
|
3264
|
+
*
|
|
2978
3265
|
* @public
|
|
2979
3266
|
*/
|
|
2980
3267
|
export declare class RepositorySecurity extends RepositorySecurity_base {
|
|
2981
3268
|
/**
|
|
3269
|
+
* The live service, built over a `GitHubClient`.
|
|
3270
|
+
*
|
|
2982
3271
|
* @remarks
|
|
2983
3272
|
* `(client) => make(client)` rather than `make`: a static initializer runs
|
|
2984
3273
|
* while the module body is still evaluating, so naming a `const` declared
|
|
@@ -2993,7 +3282,7 @@ export declare class RepositorySecurity extends RepositorySecurity_base {
|
|
|
2993
3282
|
//#endregion
|
|
2994
3283
|
//#region src/RepositoryVariable.d.ts
|
|
2995
3284
|
/**
|
|
2996
|
-
* A variable, as listing returns it.
|
|
3285
|
+
* A variable's name and value, as listing returns it.
|
|
2997
3286
|
*
|
|
2998
3287
|
* @remarks
|
|
2999
3288
|
* Unlike a secret this carries its **value**: variables are readable, so a
|
|
@@ -3004,11 +3293,14 @@ export declare class RepositorySecurity extends RepositorySecurity_base {
|
|
|
3004
3293
|
* @public
|
|
3005
3294
|
*/
|
|
3006
3295
|
interface VariableInfo {
|
|
3296
|
+
/** The variable's name. */
|
|
3007
3297
|
readonly name: string;
|
|
3298
|
+
/** The variable's current value. */
|
|
3008
3299
|
readonly value: string;
|
|
3009
3300
|
}
|
|
3010
3301
|
/**
|
|
3011
|
-
*
|
|
3302
|
+
* Create or update, list and delete Actions variables on a repository and on
|
|
3303
|
+
* its environments.
|
|
3012
3304
|
*
|
|
3013
3305
|
* @public
|
|
3014
3306
|
*/
|
|
@@ -3029,9 +3321,7 @@ interface RepositoryVariableShape {
|
|
|
3029
3321
|
* treating any error as absence would turn a permissions problem into a
|
|
3030
3322
|
* spurious create.
|
|
3031
3323
|
*
|
|
3032
|
-
*
|
|
3033
|
-
* suite nor the first consumer's has issued this read against real GitHub —
|
|
3034
|
-
* both run against doubles.
|
|
3324
|
+
* The 404-for-absent behaviour is GitHub's documented contract.
|
|
3035
3325
|
*
|
|
3036
3326
|
* Only `notFound` selects the create branch: a successful read selects the
|
|
3037
3327
|
* update branch, and any other failure propagates rather than being guessed
|
|
@@ -3055,7 +3345,8 @@ interface RepositoryVariableShape {
|
|
|
3055
3345
|
}
|
|
3056
3346
|
declare const RepositoryVariable_base: Context.ServiceClass<RepositoryVariable, "@effected/github/RepositoryVariable", RepositoryVariableShape>;
|
|
3057
3347
|
/**
|
|
3058
|
-
*
|
|
3348
|
+
* Create or update, list and delete Actions variables on a repository and on
|
|
3349
|
+
* its environments.
|
|
3059
3350
|
*
|
|
3060
3351
|
* @remarks
|
|
3061
3352
|
* No encryption and no public key, unlike secrets — but also **no upsert**,
|
|
@@ -3063,10 +3354,27 @@ declare const RepositoryVariable_base: Context.ServiceClass<RepositoryVariable,
|
|
|
3063
3354
|
* the create and update routes are different endpoints with different verbs and
|
|
3064
3355
|
* neither tolerates the other's case.
|
|
3065
3356
|
*
|
|
3357
|
+
* Provide it with {@link RepositoryVariable.layer}, which needs a
|
|
3358
|
+
* `GitHubClient`; each method also needs a `Repo` in `R`.
|
|
3359
|
+
*
|
|
3360
|
+
* @example
|
|
3361
|
+
* ```ts
|
|
3362
|
+
* import { RepositoryVariable } from "@effected/github";
|
|
3363
|
+
* import { Effect } from "effect";
|
|
3364
|
+
*
|
|
3365
|
+
* const program = Effect.gen(function* () {
|
|
3366
|
+
* const variables = yield* RepositoryVariable;
|
|
3367
|
+
* yield* variables.set("DEPLOY_REGION", "eu-west-1"); // creates or updates
|
|
3368
|
+
* return yield* variables.list();
|
|
3369
|
+
* });
|
|
3370
|
+
* ```
|
|
3371
|
+
*
|
|
3066
3372
|
* @public
|
|
3067
3373
|
*/
|
|
3068
3374
|
export declare class RepositoryVariable extends RepositoryVariable_base {
|
|
3069
3375
|
/**
|
|
3376
|
+
* The live service, built over a `GitHubClient`.
|
|
3377
|
+
*
|
|
3070
3378
|
* @remarks
|
|
3071
3379
|
* `(client) => make(client)` rather than `make`: a static initializer runs
|
|
3072
3380
|
* while the module body is still evaluating, so naming a `const` declared
|
|
@@ -3092,7 +3400,9 @@ export declare class RepositoryVariable extends RepositoryVariable_base {
|
|
|
3092
3400
|
* @public
|
|
3093
3401
|
*/
|
|
3094
3402
|
interface RulesetInfo {
|
|
3403
|
+
/** The ruleset's numeric id. */
|
|
3095
3404
|
readonly id: number;
|
|
3405
|
+
/** The ruleset's name. */
|
|
3096
3406
|
readonly name: string;
|
|
3097
3407
|
/** `"Repository"` for the repository's own, `"Organization"` for an inherited one. */
|
|
3098
3408
|
readonly source_type?: string | undefined;
|
|
@@ -3108,15 +3418,22 @@ interface RulesetInfo {
|
|
|
3108
3418
|
* @public
|
|
3109
3419
|
*/
|
|
3110
3420
|
interface RulesetPayload {
|
|
3421
|
+
/** The ruleset's name, which `upsert` matches on. */
|
|
3111
3422
|
readonly name: string;
|
|
3423
|
+
/** What it applies to: `"branch"`, `"tag"` or `"push"`. */
|
|
3112
3424
|
readonly target: string;
|
|
3425
|
+
/** `"active"`, `"evaluate"` or `"disabled"`. */
|
|
3113
3426
|
readonly enforcement: string;
|
|
3427
|
+
/** Which refs it applies to. Passed to GitHub as given. */
|
|
3114
3428
|
readonly conditions?: unknown;
|
|
3429
|
+
/** The rules it enforces. Passed to GitHub as given. */
|
|
3115
3430
|
readonly rules?: unknown;
|
|
3431
|
+
/** Actors allowed to bypass it. Passed to GitHub as given. */
|
|
3116
3432
|
readonly bypass_actors?: unknown;
|
|
3117
3433
|
}
|
|
3118
3434
|
/**
|
|
3119
|
-
*
|
|
3435
|
+
* Create or update, list and delete repository rulesets, and look up the team
|
|
3436
|
+
* and role ids their bypass actors need.
|
|
3120
3437
|
*
|
|
3121
3438
|
* @public
|
|
3122
3439
|
*/
|
|
@@ -3149,7 +3466,8 @@ interface RulesetShape {
|
|
|
3149
3466
|
}
|
|
3150
3467
|
declare const Ruleset_base: Context.ServiceClass<Ruleset, "@effected/github/Ruleset", RulesetShape>;
|
|
3151
3468
|
/**
|
|
3152
|
-
*
|
|
3469
|
+
* Create or update, list and delete repository rulesets, and look up the team
|
|
3470
|
+
* and role ids their bypass actors need.
|
|
3153
3471
|
*
|
|
3154
3472
|
* @remarks
|
|
3155
3473
|
* ## An inherited ruleset is never written to
|
|
@@ -3161,14 +3479,34 @@ declare const Ruleset_base: Context.ServiceClass<Ruleset, "@effected/github/Rule
|
|
|
3161
3479
|
* that never mentioned the organization.
|
|
3162
3480
|
*
|
|
3163
3481
|
* {@link RulesetShape.upsert} filters on `source_type` before matching, so an
|
|
3164
|
-
* inherited ruleset can never be the target of a write.
|
|
3165
|
-
*
|
|
3166
|
-
*
|
|
3482
|
+
* inherited ruleset can never be the target of a write.
|
|
3483
|
+
*
|
|
3484
|
+
* Provide it with {@link Ruleset.layer}, which needs a `GitHubClient`; each
|
|
3485
|
+
* method also needs a `Repo` in `R`.
|
|
3486
|
+
*
|
|
3487
|
+
* @example
|
|
3488
|
+
* ```ts
|
|
3489
|
+
* import { Ruleset } from "@effected/github";
|
|
3490
|
+
* import { Effect } from "effect";
|
|
3491
|
+
*
|
|
3492
|
+
* const protectMain = Effect.gen(function* () {
|
|
3493
|
+
* const rulesets = yield* Ruleset;
|
|
3494
|
+
* yield* rulesets.upsert({
|
|
3495
|
+
* name: "protect-main",
|
|
3496
|
+
* target: "branch",
|
|
3497
|
+
* enforcement: "active",
|
|
3498
|
+
* conditions: { ref_name: { include: ["~DEFAULT_BRANCH"], exclude: [] } },
|
|
3499
|
+
* rules: [{ type: "deletion" }],
|
|
3500
|
+
* });
|
|
3501
|
+
* });
|
|
3502
|
+
* ```
|
|
3167
3503
|
*
|
|
3168
3504
|
* @public
|
|
3169
3505
|
*/
|
|
3170
3506
|
export declare class Ruleset extends Ruleset_base {
|
|
3171
3507
|
/**
|
|
3508
|
+
* The live service, built over a `GitHubClient`.
|
|
3509
|
+
*
|
|
3172
3510
|
* @remarks
|
|
3173
3511
|
* `(client) => make(client)` rather than `make`: a static initializer runs
|
|
3174
3512
|
* while the module body is still evaluating, so naming a `const` declared
|
|
@@ -3205,7 +3543,9 @@ declare const PermissionGap_base: Schema.Class<PermissionGap, Schema.Struct<{
|
|
|
3205
3543
|
*/
|
|
3206
3544
|
export declare class PermissionGap extends PermissionGap_base {}
|
|
3207
3545
|
declare const ExtraPermission_base: Schema.Class<ExtraPermission, Schema.Struct<{
|
|
3546
|
+
/** The permission's name, e.g. `"contents"`. */
|
|
3208
3547
|
readonly permission: Schema.String;
|
|
3548
|
+
/** What the token has. */
|
|
3209
3549
|
readonly granted: Schema.Literals<readonly ["read", "write", "admin"]>;
|
|
3210
3550
|
/** What was asked for, when anything was. */
|
|
3211
3551
|
readonly required: Schema.optionalKey<Schema.Literals<readonly ["read", "write", "admin"]>>;
|
|
@@ -3255,17 +3595,12 @@ declare const TokenPermissions_base: Schema.Class<TokenPermissions, Schema.Struc
|
|
|
3255
3595
|
* The permissions a token was granted, and what they satisfy.
|
|
3256
3596
|
*
|
|
3257
3597
|
* @remarks
|
|
3258
|
-
* **A pure class, not a service.**
|
|
3259
|
-
* `
|
|
3260
|
-
*
|
|
3261
|
-
*
|
|
3262
|
-
*
|
|
3263
|
-
*
|
|
3264
|
-
*
|
|
3265
|
-
* Here there is no service, no layer and no double: a caller holds the
|
|
3266
|
-
* permissions GitHub already gave it (`InstallationToken.permissions`) and
|
|
3267
|
-
* compares them. The only `Effect`s are the two assertions, and they exist only
|
|
3268
|
-
* because failing typed is more useful than returning a boolean.
|
|
3598
|
+
* **A pure class, not a service.** It compares permission levels
|
|
3599
|
+
* (`read < write < admin`), so there is no layer and no test double: a caller
|
|
3600
|
+
* holds the permissions GitHub already gave it (`InstallationToken.permissions`)
|
|
3601
|
+
* and compares them. The only `Effect`s are the two assertions, which fail with
|
|
3602
|
+
* `TokenPermissionError` because failing typed is more useful than returning a
|
|
3603
|
+
* boolean.
|
|
3269
3604
|
*
|
|
3270
3605
|
* @example
|
|
3271
3606
|
* ```ts
|
|
@@ -3308,11 +3643,13 @@ export declare class TokenPermissions extends TokenPermissions_base {
|
|
|
3308
3643
|
//#endregion
|
|
3309
3644
|
//#region src/WorkflowDispatch.d.ts
|
|
3310
3645
|
declare const WorkflowRunStatus_base: Schema.Class<WorkflowRunStatus, Schema.Struct<{
|
|
3646
|
+
/** The run's numeric id. */
|
|
3311
3647
|
readonly id: Schema.Int;
|
|
3312
3648
|
/** `queued`, `in_progress`, `completed`, … */
|
|
3313
3649
|
readonly status: Schema.String;
|
|
3314
3650
|
/** Set once `status` is `completed`. */
|
|
3315
3651
|
readonly conclusion: Schema.optionalKey<Schema.String>;
|
|
3652
|
+
/** The run's web URL. */
|
|
3316
3653
|
readonly url: Schema.String;
|
|
3317
3654
|
}>, {}>;
|
|
3318
3655
|
/**
|
|
@@ -3331,9 +3668,8 @@ export declare class WorkflowRunStatus extends WorkflowRunStatus_base {
|
|
|
3331
3668
|
* `state` is GitHub's own value — `active`, `disabled_manually`,
|
|
3332
3669
|
* `disabled_inactivity`, and so on. It is reported rather than interpreted:
|
|
3333
3670
|
* whether a *disabled* workflow counts for a given GitHub feature is that
|
|
3334
|
-
* feature's rule, not this package's
|
|
3335
|
-
*
|
|
3336
|
-
* that care filter on it themselves.
|
|
3671
|
+
* feature's rule, not this package's. Callers that care filter on it
|
|
3672
|
+
* themselves.
|
|
3337
3673
|
*
|
|
3338
3674
|
* @public
|
|
3339
3675
|
*/
|
|
@@ -3348,7 +3684,7 @@ interface WorkflowInfo {
|
|
|
3348
3684
|
readonly state: string;
|
|
3349
3685
|
}
|
|
3350
3686
|
/**
|
|
3351
|
-
* How
|
|
3687
|
+
* How often to poll for a dispatched run, and how long to keep polling.
|
|
3352
3688
|
*
|
|
3353
3689
|
* @public
|
|
3354
3690
|
*/
|
|
@@ -3359,13 +3695,15 @@ interface PollOptions {
|
|
|
3359
3695
|
readonly timeout?: Duration.Duration | undefined;
|
|
3360
3696
|
}
|
|
3361
3697
|
/**
|
|
3362
|
-
*
|
|
3698
|
+
* Dispatch workflows, wait for the run they start, and list the repository's
|
|
3699
|
+
* workflows.
|
|
3363
3700
|
*
|
|
3364
3701
|
* @public
|
|
3365
3702
|
*/
|
|
3366
3703
|
interface WorkflowDispatchShape {
|
|
3367
3704
|
/** Fire a `workflow_dispatch` event. GitHub answers 204 with no run id. */
|
|
3368
3705
|
readonly dispatch: (workflow: string, ref: string, inputs?: Record<string, string>) => Effect.Effect<void, GitHubError, Repo>;
|
|
3706
|
+
/** Read one workflow run's status. */
|
|
3369
3707
|
readonly runStatus: (runId: number) => Effect.Effect<WorkflowRunStatus, GitHubError, Repo>;
|
|
3370
3708
|
/**
|
|
3371
3709
|
* Every workflow defined in the repository.
|
|
@@ -3386,10 +3724,11 @@ interface WorkflowDispatchShape {
|
|
|
3386
3724
|
* Dispatch, find the run it created, and wait for it to finish.
|
|
3387
3725
|
*
|
|
3388
3726
|
* @remarks
|
|
3389
|
-
* The wait is `Effect.repeat` with a predicate over the **success** value
|
|
3390
|
-
*
|
|
3391
|
-
*
|
|
3392
|
-
*
|
|
3727
|
+
* The wait is `Effect.repeat` with a predicate over the **success** value, so
|
|
3728
|
+
* "not finished yet" is never an error. If the run is not found finished
|
|
3729
|
+
* within `poll.timeout`, it fails with a `rejected` `GitHubError` (status
|
|
3730
|
+
* 408). The run is matched by branch, creation time and workflow path, so
|
|
3731
|
+
* concurrent dispatches of the same workflow on the same ref can be confused.
|
|
3393
3732
|
*/
|
|
3394
3733
|
readonly dispatchAndWait: (workflow: string, ref: string, options?: {
|
|
3395
3734
|
readonly inputs?: Record<string, string> | undefined;
|
|
@@ -3398,11 +3737,33 @@ interface WorkflowDispatchShape {
|
|
|
3398
3737
|
}
|
|
3399
3738
|
declare const WorkflowDispatch_base: Context.ServiceClass<WorkflowDispatch, "@effected/github/WorkflowDispatch", WorkflowDispatchShape>;
|
|
3400
3739
|
/**
|
|
3401
|
-
*
|
|
3740
|
+
* Dispatch workflows, wait for the run they start, and list the repository's
|
|
3741
|
+
* workflows.
|
|
3742
|
+
*
|
|
3743
|
+
* @remarks
|
|
3744
|
+
* Provide it with {@link WorkflowDispatch.layer}, which needs a `GitHubClient`;
|
|
3745
|
+
* each method also needs a `Repo` in `R`. `list` is an `Effect` value, not a
|
|
3746
|
+
* function.
|
|
3747
|
+
*
|
|
3748
|
+
* @example
|
|
3749
|
+
* ```ts
|
|
3750
|
+
* import { WorkflowDispatch } from "@effected/github";
|
|
3751
|
+
* import { Duration, Effect } from "effect";
|
|
3752
|
+
*
|
|
3753
|
+
* const release = Effect.gen(function* () {
|
|
3754
|
+
* const workflows = yield* WorkflowDispatch;
|
|
3755
|
+
* const run = yield* workflows.dispatchAndWait("release.yml", "main", {
|
|
3756
|
+
* inputs: { dryRun: "false" },
|
|
3757
|
+
* poll: { interval: Duration.seconds(15), timeout: Duration.minutes(20) },
|
|
3758
|
+
* });
|
|
3759
|
+
* return run.conclusion;
|
|
3760
|
+
* });
|
|
3761
|
+
* ```
|
|
3402
3762
|
*
|
|
3403
3763
|
* @public
|
|
3404
3764
|
*/
|
|
3405
3765
|
export declare class WorkflowDispatch extends WorkflowDispatch_base {
|
|
3766
|
+
/** The live service, built over a `GitHubClient`. */
|
|
3406
3767
|
static readonly layer: Layer.Layer<WorkflowDispatch, never, GitHubClient>;
|
|
3407
3768
|
/** An in-memory double; unstubbed members die naming themselves. */
|
|
3408
3769
|
static readonly makeTest: (overrides?: Partial<WorkflowDispatchShape>) => WorkflowDispatchShape;
|