@effected/github 0.6.1 → 0.7.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/README.md +4 -2
- package/index.d.ts +1 -102
- package/index.js +1 -1
- package/package.json +2 -1
- package/IssueReferences.js +0 -126
package/README.md
CHANGED
|
@@ -122,7 +122,7 @@ const program = Effect.gen(function* () {
|
|
|
122
122
|
|
|
123
123
|
The existence check pages the issue's comments to the end and matches the marker in `upsert`'s exact spelling, so a comment either member writes stays findable by the other. It is a look-before-write: two runs racing on the same issue can both see no marker and both post, so treat the marker as the record rather than the check as a lock.
|
|
124
124
|
|
|
125
|
-
Whether a run should comment at all usually turns on which issues a pull request closes, and that is a grammar rather than an API call.
|
|
125
|
+
Whether a run should comment at all usually turns on which issues a pull request closes, and that is a grammar rather than an API call. That grammar now lives in [`@effected/github-references`](https://www.npmjs.com/package/@effected/github-references), a pure package with no octokit behind it; this package re-exports the two dialects it used to own so existing code keeps compiling:
|
|
126
126
|
|
|
127
127
|
```ts
|
|
128
128
|
import { harvestIssueReferences, parseBareLineReference } from "@effected/github";
|
|
@@ -140,6 +140,8 @@ console.log(parseBareLineReference("closes #12 for real"));
|
|
|
140
140
|
|
|
141
141
|
`harvestIssueReferences` reads the **inline-in-prose** dialect: one of the nine closing keywords (`CLOSING_KEYWORDS`) followed by whitespace and `#<number>`, anywhere in the text, no colon — the spelling GitHub itself scans a pull request body for. Duplicates come back as written, because whether `fixes #1, fixes #1` means one intent or two is the caller's question. `parseBareLineReference` reads the **bare-line** dialect, where the whole trimmed line is the reference and the colon is optional — the shape a generated references block writes, one per line. Cross-repo (`owner/repo#12`) and full-URL references are out of scope.
|
|
142
142
|
|
|
143
|
+
The re-export covers exactly six names — `CLOSING_KEYWORDS`, `ClosingKeyword`, `IssueReference`, `harvestIssueReferences`, `BareLineReference`, `parseBareLineReference` — and may be dropped at a later release. Import from `@effected/github-references` directly for new code; it also carries a third dialect this package does not re-export, the closing list (`Closes #247, #248 and #251`).
|
|
144
|
+
|
|
143
145
|
## Repository configuration
|
|
144
146
|
|
|
145
147
|
Six services cover the half of a repository that is policy rather than content: `RepositorySecret`, `RepositoryVariable`, `Ruleset`, `DeploymentEnvironment`, `RepositorySecurity` and `CodeScanning`. They are shaped for a program applying the same configuration across a fleet, so every list read paginates to the end and a truncated page never becomes a wrong decision.
|
|
@@ -273,7 +275,7 @@ const TestClient = GitHubClient.layerFixture(fixtures);
|
|
|
273
275
|
- `CheckRun` — `withCheckRun` concludes on every exit path; `CheckRunOutput.truncated()` cuts rendered output to GitHub's byte limits.
|
|
274
276
|
- `PullRequest` / `PullRequestComment` — upserts for both, `listFiles` answering with the same full `CommitFile` records a commit read returns, `headSha`/`baseSha` on `PullRequestInfo`, plus `CommentMarker` for finding a sticky comment again.
|
|
275
277
|
- `GitHubIssue` — issues and their comments, including `commentOnce` for a marked comment that is posted exactly once and never edited, and `linkedIssues` for what a pull request closes.
|
|
276
|
-
- `
|
|
278
|
+
- `harvestIssueReferences` / `parseBareLineReference` — a compatibility re-export of the two closing-reference dialects that moved to `@effected/github-references`, with `CLOSING_KEYWORDS` and their result types.
|
|
277
279
|
- `GitHubRelease` — releases and asset uploads, including the one route (`uploadAsset`, with the endpoint's optional display label) outside GitHub's generated endpoint map.
|
|
278
280
|
- `RepositorySecret` / `RepositoryVariable` — repository and environment secrets and variables, with the sealed-box encryption GitHub's secrets API demands kept in one module nothing else imports.
|
|
279
281
|
- `Ruleset` / `DeploymentEnvironment` / `RepositorySecurity` / `CodeScanning` — the rest of the configuration tier: rulesets matched by name and scope, idempotent environment writes, the three security toggles GitHub keeps off the repository endpoint, and CodeQL default setup with the language detection that gates it.
|
package/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BareLineReference, CLOSING_KEYWORDS, ClosingKeyword, IssueReference, harvestIssueReferences, parseBareLineReference } from "@effected/github-references";
|
|
1
2
|
import { Config, Context, Duration, Effect, Layer, Option, Redacted, Result, Schedule, Schema, Scope, Stream } from "effect";
|
|
2
3
|
import { PaginatingEndpoints } from "@octokit/plugin-paginate-rest";
|
|
3
4
|
import { Endpoints, RequestHeaders } from "@octokit/types";
|
|
@@ -2549,108 +2550,6 @@ declare class GitTag extends GitTag_base {
|
|
|
2549
2550
|
static readonly layerTest: (overrides?: Partial<GitTagShape>) => Layer.Layer<GitTag>;
|
|
2550
2551
|
}
|
|
2551
2552
|
//#endregion
|
|
2552
|
-
//#region src/IssueReferences.d.ts
|
|
2553
|
-
/**
|
|
2554
|
-
* GitHub's closing-keyword issue-reference grammar, as pure functions.
|
|
2555
|
-
*
|
|
2556
|
-
* @remarks
|
|
2557
|
-
* GitHub links an issue to a pull request when the PR's description carries
|
|
2558
|
-
* `<keyword> #<number>` for one of nine documented keywords. Consumers speak
|
|
2559
|
-
* that grammar in two distinct dialects, and this module models exactly those
|
|
2560
|
-
* two — no service, no layer, nothing but strings in and values out:
|
|
2561
|
-
*
|
|
2562
|
-
* - **Inline-in-prose** ({@link harvestIssueReferences}): a reference may appear anywhere in
|
|
2563
|
-
* running text — `"fixes #12 and closes #13"` — with mandatory whitespace
|
|
2564
|
-
* and **no colon**, because that is the spelling GitHub itself scans PR
|
|
2565
|
-
* bodies for. This is the dialect a release pipeline harvests from commit
|
|
2566
|
-
* subjects and PR descriptions.
|
|
2567
|
-
* - **Bare-line** ({@link parseBareLineReference}): the whole line, after trimming, *is*
|
|
2568
|
-
* the reference — `"Closes: #12"` — with an **optional colon**, because a
|
|
2569
|
-
* generated references region writes one reference per line and a colon
|
|
2570
|
-
* reads better there. GitHub does not require the colon; the region format
|
|
2571
|
-
* allows it, so the parser must too. The dialects differ because their
|
|
2572
|
-
* producers do: prose is written by humans for GitHub's scanner, the region
|
|
2573
|
-
* is written by tooling for humans.
|
|
2574
|
-
*
|
|
2575
|
-
* Deliberately out of scope this round: cross-repo references
|
|
2576
|
-
* (`owner/repo#N`) and full-URL references
|
|
2577
|
-
* (`https://github.com/owner/repo/issues/N`). Both are real GitHub spellings;
|
|
2578
|
-
* neither dialect's consumers emit them yet, and guessing at their shape here
|
|
2579
|
-
* would freeze an API nobody has driven.
|
|
2580
|
-
*/
|
|
2581
|
-
/**
|
|
2582
|
-
* The nine closing keywords GitHub documents, lowercased.
|
|
2583
|
-
*
|
|
2584
|
-
* @public
|
|
2585
|
-
*/
|
|
2586
|
-
declare const CLOSING_KEYWORDS: readonly ["close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"];
|
|
2587
|
-
/**
|
|
2588
|
-
* One of the nine documented closing keywords, in canonical lowercase form.
|
|
2589
|
-
*
|
|
2590
|
-
* @public
|
|
2591
|
-
*/
|
|
2592
|
-
type ClosingKeyword = (typeof CLOSING_KEYWORDS)[number];
|
|
2593
|
-
/**
|
|
2594
|
-
* One closing reference found in prose by {@link harvestIssueReferences}.
|
|
2595
|
-
*
|
|
2596
|
-
* @public
|
|
2597
|
-
*/
|
|
2598
|
-
interface IssueReference {
|
|
2599
|
-
/** The referenced issue number. */
|
|
2600
|
-
readonly issueNumber: number;
|
|
2601
|
-
/** The matched keyword, lowercased to its canonical form. */
|
|
2602
|
-
readonly keyword: ClosingKeyword;
|
|
2603
|
-
/** Offset of the first character of the whole match (`keyword` through digits). */
|
|
2604
|
-
readonly start: number;
|
|
2605
|
-
/** Offset one past the last character of the whole match. */
|
|
2606
|
-
readonly end: number;
|
|
2607
|
-
}
|
|
2608
|
-
/**
|
|
2609
|
-
* The closing reference a bare line carries, per {@link parseBareLineReference}.
|
|
2610
|
-
*
|
|
2611
|
-
* @remarks
|
|
2612
|
-
* No offsets: in the bare-line dialect the whole line is the reference, so
|
|
2613
|
-
* positions within it locate nothing a caller acts on.
|
|
2614
|
-
*
|
|
2615
|
-
* @public
|
|
2616
|
-
*/
|
|
2617
|
-
interface BareLineReference {
|
|
2618
|
-
/** The referenced issue number. */
|
|
2619
|
-
readonly issueNumber: number;
|
|
2620
|
-
/** The matched keyword, lowercased to its canonical form. */
|
|
2621
|
-
readonly keyword: ClosingKeyword;
|
|
2622
|
-
}
|
|
2623
|
-
/**
|
|
2624
|
-
* Every inline closing reference in `text`, in document order.
|
|
2625
|
-
*
|
|
2626
|
-
* @remarks
|
|
2627
|
-
* The **inline-in-prose** dialect: case-insensitive `<keyword> #<number>`
|
|
2628
|
-
* anywhere in the text, whitespace mandatory, colon not accepted — a colon
|
|
2629
|
-
* spelling belongs to the bare-line dialect and {@link parseBareLineReference}.
|
|
2630
|
-
* Duplicates are preserved: whether `fixes #1, fixes #1` means one reference
|
|
2631
|
-
* or two is the caller's business, not a parser's.
|
|
2632
|
-
*
|
|
2633
|
-
* A match whose digits exceed `Number.MAX_SAFE_INTEGER` is skipped, not
|
|
2634
|
-
* misparsed — see the module remarks for the scope boundary.
|
|
2635
|
-
*
|
|
2636
|
-
* @public
|
|
2637
|
-
*/
|
|
2638
|
-
declare const harvestIssueReferences: (text: string) => ReadonlyArray<IssueReference>;
|
|
2639
|
-
/**
|
|
2640
|
-
* The reference a whole line carries, or `Option.none()`.
|
|
2641
|
-
*
|
|
2642
|
-
* @remarks
|
|
2643
|
-
* The **bare-line** dialect: after trimming, the entire line must be
|
|
2644
|
-
* `<keyword>[:] #<number>` — keyword case-insensitive, colon optional,
|
|
2645
|
-
* whitespace before the `#` mandatory. Trailing prose, a missing keyword, or
|
|
2646
|
-
* anything else at all is a rejection, never a partial parse; a line carries
|
|
2647
|
-
* one reference or none. Digits past `Number.MAX_SAFE_INTEGER` reject too,
|
|
2648
|
-
* for the same reason {@link harvestIssueReferences} skips them.
|
|
2649
|
-
*
|
|
2650
|
-
* @public
|
|
2651
|
-
*/
|
|
2652
|
-
declare const parseBareLineReference: (line: string) => Option.Option<BareLineReference>;
|
|
2653
|
-
//#endregion
|
|
2654
2553
|
//#region src/PullRequest.d.ts
|
|
2655
2554
|
/** How a pull request is merged. @public */
|
|
2656
2555
|
declare const MergeMethod: Schema.Literals<readonly ["merge", "squash", "rebase"]>;
|
package/index.js
CHANGED
|
@@ -18,7 +18,6 @@ import { CommentOnceResult, GitHubIssue, IssueInfo, LinkedIssue } from "./GitHub
|
|
|
18
18
|
import { GitHubRelease, ReleaseAsset, ReleaseInfo } from "./GitHubRelease.js";
|
|
19
19
|
import { GRAPHQL_ONLY_SETTINGS, GitHubRepository, SECURITY_ANALYSIS_STATUS_FIELDS, transformSecurityAndAnalysis } from "./GitHubRepository.js";
|
|
20
20
|
import { GitTag, SemverTag, TagRef, versionFromTag } from "./GitTag.js";
|
|
21
|
-
import { CLOSING_KEYWORDS, harvestIssueReferences, parseBareLineReference } from "./IssueReferences.js";
|
|
22
21
|
import { PageOptions } from "./Rest.js";
|
|
23
22
|
import { MergeMethod, PullRequest, PullRequestInfo } from "./PullRequest.js";
|
|
24
23
|
import { RepositorySecret } from "./RepositorySecret.js";
|
|
@@ -27,5 +26,6 @@ import { RepositoryVariable } from "./RepositoryVariable.js";
|
|
|
27
26
|
import { Ruleset } from "./Ruleset.js";
|
|
28
27
|
import { ExtraPermission, PermissionGap, PermissionLevel, PermissionResult, TokenPermissionError, TokenPermissions } from "./TokenPermissions.js";
|
|
29
28
|
import { WorkflowDispatch, WorkflowRunStatus } from "./WorkflowDispatch.js";
|
|
29
|
+
import { CLOSING_KEYWORDS, harvestIssueReferences, parseBareLineReference } from "@effected/github-references";
|
|
30
30
|
|
|
31
31
|
export { Annotation, AnnotationLevel, AppIdentity, ArtifactMetadata, Attestation, AttestationListEntry, AttestationRecord, BotIdentity, CLOSING_KEYWORDS, CheckConclusion, CheckRun, CheckRunOutput, CheckRunRef, CodeScanning, CommentMarker, CommentOnceResult, CommentRecord, CommitComparison, CommitFile, CommitRef, CommitSummary, DeploymentEnvironment, ExtraPermission, FileChange, FileContent, FileDeletion, FileMode, FileStatus, GRAPHQL_ONLY_SETTINGS, GitBranch, GitCommit, GitHubApp, GitHubAppError, GitHubClient, GitHubCommit, GitHubContent, GitHubError, GitHubErrorKind, GitHubGraphQLError, GitHubIssue, GitHubRelease, GitHubRepository, GitTag, GraphQLDocument, GraphQLErrorEntry, Installation, InstallationToken, InvalidRepoRefError, IssueInfo, LinkedIssue, MergeMethod, PageOptions, PermissionGap, PermissionLevel, PermissionResult, PullRequest, PullRequestComment, PullRequestInfo, RateLimitSnapshot, ReleaseAsset, ReleaseInfo, Repo, RepoRef, RepositorySecret, RepositorySecurity, RepositoryVariable, RetryPolicy, Ruleset, SECURITY_ANALYSIS_STATUS_FIELDS, SemverTag, StorageRecordInput, TagRef, TokenPermissionError, TokenPermissions, WorkflowDispatch, WorkflowRunStatus, harvestIssueReferences, parseBareLineReference, transformSecurityAndAnalysis, versionFromTag };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effected/github",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.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": [
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"./package.json": "./package.json"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
+
"@effected/github-references": "^0.1.0",
|
|
41
42
|
"@effected/semver": "^0.5.0",
|
|
42
43
|
"@octokit/core": "^7.0.6",
|
|
43
44
|
"@octokit/plugin-paginate-rest": "^15.0.0",
|
package/IssueReferences.js
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { Option } from "effect";
|
|
2
|
-
|
|
3
|
-
//#region src/IssueReferences.ts
|
|
4
|
-
/**
|
|
5
|
-
* GitHub's closing-keyword issue-reference grammar, as pure functions.
|
|
6
|
-
*
|
|
7
|
-
* @remarks
|
|
8
|
-
* GitHub links an issue to a pull request when the PR's description carries
|
|
9
|
-
* `<keyword> #<number>` for one of nine documented keywords. Consumers speak
|
|
10
|
-
* that grammar in two distinct dialects, and this module models exactly those
|
|
11
|
-
* two — no service, no layer, nothing but strings in and values out:
|
|
12
|
-
*
|
|
13
|
-
* - **Inline-in-prose** ({@link harvestIssueReferences}): a reference may appear anywhere in
|
|
14
|
-
* running text — `"fixes #12 and closes #13"` — with mandatory whitespace
|
|
15
|
-
* and **no colon**, because that is the spelling GitHub itself scans PR
|
|
16
|
-
* bodies for. This is the dialect a release pipeline harvests from commit
|
|
17
|
-
* subjects and PR descriptions.
|
|
18
|
-
* - **Bare-line** ({@link parseBareLineReference}): the whole line, after trimming, *is*
|
|
19
|
-
* the reference — `"Closes: #12"` — with an **optional colon**, because a
|
|
20
|
-
* generated references region writes one reference per line and a colon
|
|
21
|
-
* reads better there. GitHub does not require the colon; the region format
|
|
22
|
-
* allows it, so the parser must too. The dialects differ because their
|
|
23
|
-
* producers do: prose is written by humans for GitHub's scanner, the region
|
|
24
|
-
* is written by tooling for humans.
|
|
25
|
-
*
|
|
26
|
-
* Deliberately out of scope this round: cross-repo references
|
|
27
|
-
* (`owner/repo#N`) and full-URL references
|
|
28
|
-
* (`https://github.com/owner/repo/issues/N`). Both are real GitHub spellings;
|
|
29
|
-
* neither dialect's consumers emit them yet, and guessing at their shape here
|
|
30
|
-
* would freeze an API nobody has driven.
|
|
31
|
-
*/
|
|
32
|
-
/**
|
|
33
|
-
* The nine closing keywords GitHub documents, lowercased.
|
|
34
|
-
*
|
|
35
|
-
* @public
|
|
36
|
-
*/
|
|
37
|
-
const CLOSING_KEYWORDS = [
|
|
38
|
-
"close",
|
|
39
|
-
"closes",
|
|
40
|
-
"closed",
|
|
41
|
-
"fix",
|
|
42
|
-
"fixes",
|
|
43
|
-
"fixed",
|
|
44
|
-
"resolve",
|
|
45
|
-
"resolves",
|
|
46
|
-
"resolved"
|
|
47
|
-
];
|
|
48
|
-
/**
|
|
49
|
-
* Both patterns derive from {@link CLOSING_KEYWORDS} so the constant and the
|
|
50
|
-
* grammar cannot drift. Alternation order is safe: the regex engine backtracks
|
|
51
|
-
* through alternatives, so `close` matching inside `closes` fails at the
|
|
52
|
-
* mandatory `#`-introducer and retries the longer keyword.
|
|
53
|
-
*/
|
|
54
|
-
const KEYWORDS = CLOSING_KEYWORDS.join("|");
|
|
55
|
-
/** Inline-in-prose: mandatory whitespace, no colon. */
|
|
56
|
-
const INLINE_PATTERN = new RegExp(`\\b(${KEYWORDS})\\s+#(\\d+)`, "gi");
|
|
57
|
-
/**
|
|
58
|
-
* Bare-line: optional colon, then mandatory same-line whitespace. `[ \t]`
|
|
59
|
-
* rather than `\s`, so an embedded newline cannot smuggle two lines past a
|
|
60
|
-
* parser whose contract is one.
|
|
61
|
-
*/
|
|
62
|
-
const BARE_LINE_PATTERN = new RegExp(`^(${KEYWORDS}):?[ \\t]+#(\\d+)$`, "i");
|
|
63
|
-
/**
|
|
64
|
-
* `#<digits>` parsed to a number — or `undefined` when the digits exceed
|
|
65
|
-
* `Number.MAX_SAFE_INTEGER`, because a silently rounded issue number is worse
|
|
66
|
-
* than a skipped match. Callers skip such matches; they do not fail.
|
|
67
|
-
*/
|
|
68
|
-
const safeIssueNumber = (digits) => {
|
|
69
|
-
const value = Number(digits);
|
|
70
|
-
return Number.isSafeInteger(value) ? value : void 0;
|
|
71
|
-
};
|
|
72
|
-
/**
|
|
73
|
-
* Every inline closing reference in `text`, in document order.
|
|
74
|
-
*
|
|
75
|
-
* @remarks
|
|
76
|
-
* The **inline-in-prose** dialect: case-insensitive `<keyword> #<number>`
|
|
77
|
-
* anywhere in the text, whitespace mandatory, colon not accepted — a colon
|
|
78
|
-
* spelling belongs to the bare-line dialect and {@link parseBareLineReference}.
|
|
79
|
-
* Duplicates are preserved: whether `fixes #1, fixes #1` means one reference
|
|
80
|
-
* or two is the caller's business, not a parser's.
|
|
81
|
-
*
|
|
82
|
-
* A match whose digits exceed `Number.MAX_SAFE_INTEGER` is skipped, not
|
|
83
|
-
* misparsed — see the module remarks for the scope boundary.
|
|
84
|
-
*
|
|
85
|
-
* @public
|
|
86
|
-
*/
|
|
87
|
-
const harvestIssueReferences = (text) => {
|
|
88
|
-
const references = [];
|
|
89
|
-
for (const match of text.matchAll(INLINE_PATTERN)) {
|
|
90
|
-
const issueNumber = safeIssueNumber(match[2] ?? "");
|
|
91
|
-
if (issueNumber === void 0) continue;
|
|
92
|
-
references.push({
|
|
93
|
-
issueNumber,
|
|
94
|
-
keyword: (match[1] ?? "").toLowerCase(),
|
|
95
|
-
start: match.index,
|
|
96
|
-
end: match.index + match[0].length
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
return references;
|
|
100
|
-
};
|
|
101
|
-
/**
|
|
102
|
-
* The reference a whole line carries, or `Option.none()`.
|
|
103
|
-
*
|
|
104
|
-
* @remarks
|
|
105
|
-
* The **bare-line** dialect: after trimming, the entire line must be
|
|
106
|
-
* `<keyword>[:] #<number>` — keyword case-insensitive, colon optional,
|
|
107
|
-
* whitespace before the `#` mandatory. Trailing prose, a missing keyword, or
|
|
108
|
-
* anything else at all is a rejection, never a partial parse; a line carries
|
|
109
|
-
* one reference or none. Digits past `Number.MAX_SAFE_INTEGER` reject too,
|
|
110
|
-
* for the same reason {@link harvestIssueReferences} skips them.
|
|
111
|
-
*
|
|
112
|
-
* @public
|
|
113
|
-
*/
|
|
114
|
-
const parseBareLineReference = (line) => {
|
|
115
|
-
const match = BARE_LINE_PATTERN.exec(line.trim());
|
|
116
|
-
if (match === null) return Option.none();
|
|
117
|
-
const issueNumber = safeIssueNumber(match[2] ?? "");
|
|
118
|
-
if (issueNumber === void 0) return Option.none();
|
|
119
|
-
return Option.some({
|
|
120
|
-
issueNumber,
|
|
121
|
-
keyword: (match[1] ?? "").toLowerCase()
|
|
122
|
-
});
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
//#endregion
|
|
126
|
-
export { CLOSING_KEYWORDS, harvestIssueReferences, parseBareLineReference };
|