@effected/github 0.22.0 → 0.23.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/ActionsOidc.js CHANGED
@@ -1,4 +1,4 @@
1
- import { JwksResolver, Jwt, JwtError } from "@effected/jwt";
1
+ import { Oidc } from "@effected/oidc";
2
2
  import { Effect, Schema, SchemaTransformation } from "effect";
3
3
 
4
4
  // src/ActionsOidc.ts
@@ -23,6 +23,10 @@ const IdFromString = Schema.String.check(Schema.isPattern(/^\d+$/)).pipe(Schema.
23
23
  *
24
24
  * Claims GitHub adds that are not modelled here are dropped on decode.
25
25
  *
26
+ * To decode a payload as it arrives in the token (snake_case keys, string
27
+ * ids), use {@link ActionsOidcClaimsFromWire}; this class itself decodes the
28
+ * camelCase form.
29
+ *
26
30
  * @public
27
31
  */
28
32
  var ActionsOidcClaims = class extends Schema.Class("ActionsOidcClaims")({
@@ -71,8 +75,28 @@ var ActionsOidcClaims = class extends Schema.Class("ActionsOidcClaims")({
71
75
  /** `github-hosted` or `self-hosted` (wire key `runner_environment`). */
72
76
  runnerEnvironment: Schema.String
73
77
  }) {};
74
- /** The claims as they arrive in the token: snake_case keys, decoding to {@link ActionsOidcClaims}. */
75
- const ClaimsFromWire = ActionsOidcClaims.pipe(Schema.encodeKeys({
78
+ /**
79
+ * {@link ActionsOidcClaims} as the claims arrive in the token: snake_case
80
+ * keys and string ids, decoding to the class and encoding back to the wire.
81
+ *
82
+ * @remarks
83
+ * The codec {@link ActionsOidc.verify} decodes a verified payload with.
84
+ * Exported for reading a token this process already trusts, such as one the
85
+ * runner's own token service just issued, and for building one: encoding an
86
+ * instance yields the exact payload GitHub would sign.
87
+ *
88
+ * @example
89
+ * ```ts
90
+ * import { ActionsOidcClaimsFromWire } from "@effected/github";
91
+ * import { Oidc } from "@effected/oidc";
92
+ *
93
+ * // Unverified: only for a token handed over by a trusted runtime.
94
+ * const read = (token: string) => Oidc.decodeUnverified(token, ActionsOidcClaimsFromWire);
95
+ * ```
96
+ *
97
+ * @public
98
+ */
99
+ const ActionsOidcClaimsFromWire = ActionsOidcClaims.pipe(Schema.encodeKeys({
76
100
  repositoryId: "repository_id",
77
101
  repositoryOwner: "repository_owner",
78
102
  repositoryOwnerId: "repository_owner_id",
@@ -85,16 +109,11 @@ const ClaimsFromWire = ActionsOidcClaims.pipe(Schema.encodeKeys({
85
109
  runnerEnvironment: "runner_environment"
86
110
  }));
87
111
  const verify = Effect.fn("ActionsOidc.verify")(function* (token, options) {
88
- if (options.audience.length === 0) return yield* new JwtError({
89
- reason: "wrongAudience",
90
- detail: "no audience was given; an Actions OIDC token is never verified without one"
91
- });
92
- return yield* Jwt.verify(token, {
93
- key: JwksResolver.forIssuer(ISSUER),
94
- claims: ClaimsFromWire,
112
+ return yield* Oidc.verify(token, {
95
113
  issuer: ISSUER,
96
114
  audience: options.audience,
97
- ...options.clockTolerance !== void 0 ? { clockTolerance: options.clockTolerance } : {}
115
+ claims: ActionsOidcClaimsFromWire,
116
+ clockTolerance: options.clockTolerance
98
117
  });
99
118
  });
100
119
  const testClaims = (overrides = {}) => ({
@@ -122,8 +141,9 @@ const testClaims = (overrides = {}) => ({
122
141
  * repository, workflow and run it is.
123
142
  *
124
143
  * @remarks
125
- * {@link ActionsOidc.verify} checks the signature against GitHub's published
126
- * JWKS (through `@effected/jwt`'s `JwksResolver`, which caches it), then `iss`,
144
+ * {@link ActionsOidc.verify} is `@effected/oidc`'s `Oidc.verify` pinned to the
145
+ * Actions issuer: it checks the signature against GitHub's published JWKS
146
+ * (through `@effected/jwt`'s `JwksResolver`, which caches it), then `iss`,
127
147
  * `aud`, `exp`, `nbf` and `iat`, then decodes the payload into
128
148
  * {@link ActionsOidcClaims}. Every failure is a `JwtError`; route on its
129
149
  * `reason` (`wrongAudience`, `expired`, `claims`, ...), never on its message.
@@ -141,7 +161,8 @@ const testClaims = (overrides = {}) => ({
141
161
  * are refused as `wrongIssuer`.
142
162
  *
143
163
  * This module does not reach octokit: a service that only verifies tokens
144
- * links `@effected/jwt` and nothing else from this package.
164
+ * links `@effected/oidc` and `@effected/jwt` and nothing else from this
165
+ * package.
145
166
  *
146
167
  * @example
147
168
  * ```ts
@@ -176,4 +197,4 @@ const ActionsOidc = {
176
197
  testClaims
177
198
  };
178
199
 
179
- export { ActionsOidc, ActionsOidcClaims };
200
+ export { ActionsOidc, ActionsOidcClaims, ActionsOidcClaimsFromWire };
package/GitHubApp.js CHANGED
@@ -3,8 +3,8 @@ import { GitHubGraphQLError } from "./GraphQL.js";
3
3
  import { GitHubClient, makeClientShape } from "./GitHubClient.js";
4
4
  import { numericId } from "./internal/ids.js";
5
5
  import { InstallationTokenStore } from "./InstallationTokenStore.js";
6
- import { Jwt, JwtKey } from "@effected/jwt";
7
6
  import { Cause, Clock, Context, DateTime, Deferred, Duration, Effect, Layer, Option, Redacted, Ref, Schema, Semaphore, Stream } from "effect";
7
+ import { Jwt, JwtKey } from "@effected/jwt";
8
8
 
9
9
  // src/GitHubApp.ts
10
10
  /**
@@ -3,7 +3,7 @@ import { GitHubClient } from "./GitHubClient.js";
3
3
  import { Repo } from "./Repo.js";
4
4
  import { numericId } from "./internal/ids.js";
5
5
  import { PageOptions } from "./Rest.js";
6
- import { Clock, Context, Duration, Effect, Layer, Option, Schedule, Schema } from "effect";
6
+ import { Context, DateTime, Duration, Effect, Layer, Option, Schedule, Schema } from "effect";
7
7
 
8
8
  // src/WorkflowDispatch.ts
9
9
  /**
@@ -205,7 +205,7 @@ const make = (client) => {
205
205
  ref,
206
206
  attempts
207
207
  });
208
- const dispatchedAt = new Date(yield* Clock.currentTimeMillis).toISOString();
208
+ const dispatchedAt = yield* Effect.map(DateTime.now, DateTime.formatIso);
209
209
  const dispatched = yield* dispatchWithRun(workflow, ref, options?.inputs);
210
210
  const findRun = Option.isSome(dispatched) ? Effect.map(runStatus(dispatched.value.runId), Option.some) : Effect.gen(function* () {
211
211
  const match = (yield* client.paginate("GET /repos/{owner}/{repo}/actions/runs", {
package/index.d.ts CHANGED
@@ -63,9 +63,46 @@ declare const ActionsOidcClaims_base: Schema.Class<ActionsOidcClaims, Schema.Str
63
63
  *
64
64
  * Claims GitHub adds that are not modelled here are dropped on decode.
65
65
  *
66
+ * To decode a payload as it arrives in the token (snake_case keys, string
67
+ * ids), use {@link ActionsOidcClaimsFromWire}; this class itself decodes the
68
+ * camelCase form.
69
+ *
66
70
  * @public
67
71
  */
68
72
  export declare class ActionsOidcClaims extends ActionsOidcClaims_base {}
73
+ /**
74
+ * {@link ActionsOidcClaims} as the claims arrive in the token: snake_case
75
+ * keys and string ids, decoding to the class and encoding back to the wire.
76
+ *
77
+ * @remarks
78
+ * The codec {@link ActionsOidc.verify} decodes a verified payload with.
79
+ * Exported for reading a token this process already trusts, such as one the
80
+ * runner's own token service just issued, and for building one: encoding an
81
+ * instance yields the exact payload GitHub would sign.
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * import { ActionsOidcClaimsFromWire } from "@effected/github";
86
+ * import { Oidc } from "@effected/oidc";
87
+ *
88
+ * // Unverified: only for a token handed over by a trusted runtime.
89
+ * const read = (token: string) => Oidc.decodeUnverified(token, ActionsOidcClaimsFromWire);
90
+ * ```
91
+ *
92
+ * @public
93
+ */
94
+ export declare const ActionsOidcClaimsFromWire: Schema.encodeKeys<typeof ActionsOidcClaims, {
95
+ readonly repositoryId: "repository_id";
96
+ readonly repositoryOwner: "repository_owner";
97
+ readonly repositoryOwnerId: "repository_owner_id";
98
+ readonly runId: "run_id";
99
+ readonly runAttempt: "run_attempt";
100
+ readonly workflowRef: "workflow_ref";
101
+ readonly jobWorkflowRef: "job_workflow_ref";
102
+ readonly eventName: "event_name";
103
+ readonly actorId: "actor_id";
104
+ readonly runnerEnvironment: "runner_environment";
105
+ }>;
69
106
  /**
70
107
  * Options for {@link ActionsOidc.verify}.
71
108
  *
@@ -87,8 +124,9 @@ interface ActionsOidcVerifyOptions {
87
124
  * repository, workflow and run it is.
88
125
  *
89
126
  * @remarks
90
- * {@link ActionsOidc.verify} checks the signature against GitHub's published
91
- * JWKS (through `@effected/jwt`'s `JwksResolver`, which caches it), then `iss`,
127
+ * {@link ActionsOidc.verify} is `@effected/oidc`'s `Oidc.verify` pinned to the
128
+ * Actions issuer: it checks the signature against GitHub's published JWKS
129
+ * (through `@effected/jwt`'s `JwksResolver`, which caches it), then `iss`,
92
130
  * `aud`, `exp`, `nbf` and `iat`, then decodes the payload into
93
131
  * {@link ActionsOidcClaims}. Every failure is a `JwtError`; route on its
94
132
  * `reason` (`wrongAudience`, `expired`, `claims`, ...), never on its message.
@@ -106,7 +144,8 @@ interface ActionsOidcVerifyOptions {
106
144
  * are refused as `wrongIssuer`.
107
145
  *
108
146
  * This module does not reach octokit: a service that only verifies tokens
109
- * links `@effected/jwt` and nothing else from this package.
147
+ * links `@effected/oidc` and `@effected/jwt` and nothing else from this
148
+ * package.
110
149
  *
111
150
  * @example
112
151
  * ```ts
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ActionsOidc, ActionsOidcClaims } from "./ActionsOidc.js";
1
+ import { ActionsOidc, ActionsOidcClaims, ActionsOidcClaimsFromWire } from "./ActionsOidc.js";
2
2
  import { GitHubError, GitHubErrorKind, GitHubValidationCode, GitHubValidationEntry } from "./GitHubError.js";
3
3
  import { GitHubGraphQLError, GraphQLDocument, GraphQLErrorEntry } from "./GraphQL.js";
4
4
  import { RateLimitSnapshot, RetryPolicy } from "./Resilience.js";
@@ -31,4 +31,4 @@ import { ExtraPermission, PermissionGap, PermissionLevel, PermissionResult, Toke
31
31
  import { DispatchedRun, WorkflowDispatch, WorkflowRunStatus } from "./WorkflowDispatch.js";
32
32
  import { CLOSING_KEYWORDS, harvestIssueReferences, parseBareLineReference } from "@effected/github-references";
33
33
 
34
- export { ActionsOidc, ActionsOidcClaims, Annotation, AnnotationLevel, AppIdentity, AppInfo, ArtifactMetadata, Attestation, AttestationListEntry, AttestationRecord, AuthenticatedApp, BotIdentity, BotUser, CLOSING_KEYWORDS, CheckConclusion, CheckRun, CheckRunOutput, CheckRunRef, CheckRunStatus, CodeScanning, CommentMarker, CommentOnceResult, CommentRecord, CommitComparison, CommitFile, CommitRef, CommitSummary, DeliveryAttempt, DeploymentEnvironment, DispatchedRun, ExtraPermission, FileChange, FileContent, FileDeletion, FileMode, FileStatus, GRAPHQL_ONLY_SETTINGS, GitBranch, GitCommit, GitHubApp, GitHubAppError, GitHubClient, GitHubCommit, GitHubContent, GitHubError, GitHubErrorKind, GitHubFixtures, GitHubGraphQLError, GitHubIssue, GitHubRelease, GitHubRepository, GitHubValidationCode, GitHubValidationEntry, GitTag, GraphQLDocument, GraphQLErrorEntry, Installation, InstallationToken, InstallationTokenStore, InvalidRepoRefError, IssueInfo, LinkedIssue, MergeMethod, PageOptions, PermissionGap, PermissionLevel, PermissionResult, PullRequest, PullRequestComment, PullRequestInfo, RateLimitSnapshot, RawFailure, ReleaseAsset, ReleaseInfo, Repo, RepoRef, ReportedCheckConclusion, ReportedCheckRunOutput, RepositorySecret, RepositorySecurity, RepositoryVariable, RetryPolicy, Ruleset, SECURITY_ANALYSIS_STATUS_FIELDS, SemverTag, StorageRecordInput, TagRef, TokenPermissionError, TokenPermissions, WorkflowDispatch, WorkflowRunStatus, harvestIssueReferences, parseBareLineReference, repositoryPatch, transformSecurityAndAnalysis, versionFromTag };
34
+ export { ActionsOidc, ActionsOidcClaims, ActionsOidcClaimsFromWire, Annotation, AnnotationLevel, AppIdentity, AppInfo, ArtifactMetadata, Attestation, AttestationListEntry, AttestationRecord, AuthenticatedApp, BotIdentity, BotUser, CLOSING_KEYWORDS, CheckConclusion, CheckRun, CheckRunOutput, CheckRunRef, CheckRunStatus, CodeScanning, CommentMarker, CommentOnceResult, CommentRecord, CommitComparison, CommitFile, CommitRef, CommitSummary, DeliveryAttempt, DeploymentEnvironment, DispatchedRun, ExtraPermission, FileChange, FileContent, FileDeletion, FileMode, FileStatus, GRAPHQL_ONLY_SETTINGS, GitBranch, GitCommit, GitHubApp, GitHubAppError, GitHubClient, GitHubCommit, GitHubContent, GitHubError, GitHubErrorKind, GitHubFixtures, GitHubGraphQLError, GitHubIssue, GitHubRelease, GitHubRepository, GitHubValidationCode, GitHubValidationEntry, GitTag, GraphQLDocument, GraphQLErrorEntry, Installation, InstallationToken, InstallationTokenStore, InvalidRepoRefError, IssueInfo, LinkedIssue, MergeMethod, PageOptions, PermissionGap, PermissionLevel, PermissionResult, PullRequest, PullRequestComment, PullRequestInfo, RateLimitSnapshot, RawFailure, ReleaseAsset, ReleaseInfo, Repo, RepoRef, ReportedCheckConclusion, ReportedCheckRunOutput, RepositorySecret, RepositorySecurity, RepositoryVariable, RetryPolicy, Ruleset, SECURITY_ANALYSIS_STATUS_FIELDS, SemverTag, StorageRecordInput, TagRef, TokenPermissionError, TokenPermissions, WorkflowDispatch, WorkflowRunStatus, harvestIssueReferences, parseBareLineReference, repositoryPatch, transformSecurityAndAnalysis, versionFromTag };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effected/github",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "private": false,
5
5
  "description": "Typed GitHub REST and GraphQL services over the octokit core request surface, with app auth and resource helpers.",
6
6
  "keywords": [
@@ -40,6 +40,7 @@
40
40
  "dependencies": {
41
41
  "@effected/github-references": "^0.11.0",
42
42
  "@effected/jwt": "^0.5.0",
43
+ "@effected/oidc": "^0.1.0",
43
44
  "@effected/semver": "^0.15.0",
44
45
  "@octokit/core": "^7.0.6",
45
46
  "@octokit/plugin-paginate-rest": "^16.0.0",