ensemble-review 1.0.35 → 1.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/plugins/rate-limit.js +22 -0
- package/dist/api/routes/releases.js +181 -0
- package/dist/app.js +3 -0
- package/dist/coding/story-build/base-refs.js +10 -2
- package/dist/coding/story-build/loop/driver.js +1 -1
- package/dist/coding/story-build/loop/routes.js +9 -1
- package/dist/coding/story-build/persist.js +53 -7
- package/dist/coding/story-build/plan-persist.js +1 -1
- package/dist/coding/story-build/push-hotfix.js +293 -0
- package/dist/coding/story-build/push.js +5 -0
- package/dist/coding/story-build/routes-build.js +25 -3
- package/dist/db/erase-account.js +14 -0
- package/dist/db/hotfix-bases.js +31 -0
- package/dist/db/migrations/0195_releases.sql +128 -0
- package/dist/db/migrations/0196_story_build_hotfix.sql +54 -0
- package/dist/db/migrations/0197_release_items_live_tag.sql +11 -0
- package/dist/db/migrations/0198_story_build_port_report.sql +7 -0
- package/dist/db/migrations/meta/_journal.json +28 -0
- package/dist/db/queries.js +21 -0
- package/dist/db/release-check.js +378 -0
- package/dist/db/release-settings.js +94 -0
- package/dist/db/repo-tags.js +82 -0
- package/dist/db/schema.sqlite.js +246 -0
- package/dist/github/mutations.js +67 -0
- package/dist/github/queries.js +5 -0
- package/dist/github/settle-query.js +11 -1
- package/dist/github/tag-queries.js +101 -0
- package/dist/releases/create.js +539 -0
- package/dist/releases/github.js +78 -0
- package/dist/releases/notes.js +152 -0
- package/dist/releases/refresh.js +43 -0
- package/dist/sandbox/session/manager.js +207 -12
- package/dist/sandbox/session/plan.js +19 -7
- package/dist/sandbox/session/routes.js +12 -2
- package/dist/sandbox/workspace/hotfix.js +30 -0
- package/dist/sandbox/workspace/index.js +38 -2
- package/dist/sandbox/workspace/port-report.js +137 -0
- package/dist/sandbox/workspace/seed.js +40 -0
- package/dist/shared/hotfix.js +165 -0
- package/dist/shared/index.js +4 -0
- package/dist/shared/release-check.js +528 -0
- package/dist/shared/release-write.js +264 -0
- package/dist/shared/releases.js +89 -0
- package/dist/shared/story-build.js +2 -0
- package/dist/sync/repo-tags.js +368 -0
- package/dist/sync/settle-sweep.js +47 -2
- package/dist/sync/sync-repo.js +12 -0
- package/dist/sync/tag-ranges.js +350 -0
- package/dist/sync/tags-step.js +77 -0
- package/dist/sync/upsert.js +23 -0
- package/package.json +5 -2
- package/public/assets/{AiFixTab-CVIZl9I8.js → AiFixTab-BC3tDZ3z.js} +1 -1
- package/public/assets/{PrBotBehaviourTab-q0M7RU1e.js → PrBotBehaviourTab-C5j5uhLn.js} +1 -1
- package/public/assets/index-BrjUDY3j.js +138 -0
- package/public/assets/index-D1zhsqSF.css +1 -0
- package/public/index.html +2 -2
- package/dist/ai/check-tool.js +0 -6
- package/dist/api/routes/auth.js +0 -194
- package/dist/api/routes/billing.js +0 -209
- package/dist/api/routes/claude-review.js +0 -522
- package/dist/api/routes/contact.js +0 -318
- package/dist/api/routes/feed.js +0 -21
- package/dist/api/routes/inbox.js +0 -45
- package/dist/api/routes/mentions.js +0 -22
- package/dist/api/routes/teams.js +0 -150
- package/dist/api/routes/webhooks.js +0 -181
- package/dist/coding/activity.js +0 -80
- package/dist/coding/agent.js +0 -147
- package/dist/coding/ai-fix/checks-preview.js +0 -58
- package/dist/coding/ai-fix/comment-seed.js +0 -519
- package/dist/coding/ai-fix/prompts.js +0 -283
- package/dist/coding/ai-resolve/prompt.js +0 -161
- package/dist/coding/ai-resolve/routes.js +0 -97
- package/dist/coding/ai-resolve/run.js +0 -343
- package/dist/coding/ai-resolve/schema.js +0 -26
- package/dist/coding/ai-resolve/validate.js +0 -136
- package/dist/coding/checks/deny-scan.js +0 -75
- package/dist/coding/checks/discover.js +0 -541
- package/dist/coding/checks/docker.js +0 -38
- package/dist/coding/checks/env.js +0 -88
- package/dist/coding/checks/hooks.js +0 -91
- package/dist/coding/checks/index.js +0 -8
- package/dist/coding/checks/local.js +0 -40
- package/dist/coding/checks/sandbox.js +0 -206
- package/dist/coding/checks/session.js +0 -518
- package/dist/coding/checks/spawn.js +0 -123
- package/dist/coding/checks/spec.js +0 -140
- package/dist/coding/checks/types.js +0 -6
- package/dist/coding/partial-spend.js +0 -19
- package/dist/coding/safe-path.js +0 -75
- package/dist/coding/story-build/build-prompts.js +0 -178
- package/dist/coding/story-build/build.js +0 -332
- package/dist/coding/story-build/checkouts.js +0 -66
- package/dist/coding/story-build/docs-runner.js +0 -178
- package/dist/coding/story-build/docs.js +0 -334
- package/dist/coding/story-build/manager.js +0 -999
- package/dist/coding/story-build/plan-agent.js +0 -190
- package/dist/coding/story-build/plan.js +0 -338
- package/dist/coding/story-build/prompts.js +0 -147
- package/dist/coding/story-build/routes-docs.js +0 -113
- package/dist/coding/story-build/routes.js +0 -295
- package/dist/coding/story-build/schema.js +0 -53
- package/dist/db/automation-output.js +0 -349
- package/dist/db/credits.js +0 -79
- package/dist/db/schema.js +0 -321
- package/dist/db/schema.pg.js +0 -2197
- package/dist/db/sprint-repo-suggest.js +0 -257
- package/dist/db/sprint-stories.js +0 -42
- package/dist/db/sprint-story.js +0 -505
- package/dist/db/sprint-ticket-repos.js +0 -195
- package/dist/db/story-selection.js +0 -270
- package/dist/db/team-comparison.js +0 -124
- package/dist/db/workspace-comparison.js +0 -98
- package/dist/feed/fyi-provider.js +0 -10
- package/dist/github/local-user.js +0 -92
- package/dist/github/repo-files.js +0 -26
- package/dist/ml/worker.js +0 -31
- package/dist/platform/advisor/discovery/tier2.js +0 -88
- package/dist/platform/advisor/discovery/tier3.js +0 -57
- package/dist/platform/advisor/emitters/adapter.js +0 -5
- package/dist/platform/advisor/emitters/coderabbit.js +0 -175
- package/dist/platform/advisor/emitters/copilot-prose.js +0 -118
- package/dist/platform/advisor/emitters/greptile.js +0 -176
- package/dist/platform/advisor/emitters/lint.js +0 -37
- package/dist/platform/advisor/emitters/manifest.js +0 -239
- package/dist/platform/advisor/emitters/prose.js +0 -183
- package/dist/platform/advisor/emitters/registry.js +0 -20
- package/dist/platform/advisor/emitters/yaml-doc.js +0 -95
- package/dist/platform/advisor/evidence.js +0 -79
- package/dist/platform/advisor/findings.js +0 -15
- package/dist/platform/advisor/intents.js +0 -269
- package/dist/platform/advisor/measure/effect.js +0 -18
- package/dist/platform/advisor/outputs/brief.js +0 -68
- package/dist/platform/advisor/outputs/config-pr.js +0 -156
- package/dist/platform/advisor/refine/diff-guard.js +0 -38
- package/dist/platform/advisor/refine/refine.js +0 -35
- package/dist/platform/advisor/retro-check.js +0 -98
- package/dist/platform/advisor/routes.js +0 -648
- package/dist/platform/advisor/store.js +0 -321
- package/dist/platform/advisor/taxonomy.js +0 -67
- package/dist/platform/annotations/prompts.js +0 -84
- package/dist/platform/annotations/routes.js +0 -86
- package/dist/platform/annotations/runner.js +0 -234
- package/dist/platform/annotations/targets.js +0 -203
- package/dist/platform/insights/grounded-figures.js +0 -162
- package/dist/platform/insights/period-questions.js +0 -235
- package/dist/platform/work-plan/hash.js +0 -99
- package/dist/platform/work-plan/prompt.js +0 -209
- package/dist/platform/work-plan/routes.js +0 -350
- package/dist/pro/bind.js +0 -309
- package/dist/pro/contract.js +0 -36
- package/dist/pro/event-hooks.js +0 -37
- package/dist/pro/migrate.js +0 -64
- package/dist/review/events.js +0 -24
- package/dist/review/local-settings.js +0 -78
- package/dist/review/memory/capture.js +0 -0
- package/dist/review/memory/retrieval.js +0 -272
- package/dist/review/memory/routes.js +0 -78
- package/dist/review/persist.js +0 -203
- package/dist/review/plugin-providers.js +0 -12
- package/dist/review/prompt.js +0 -264
- package/dist/review/review-manager.js +0 -259
- package/dist/review/routing.js +0 -164
- package/dist/review/sprint-assess/agent.js +0 -145
- package/dist/review/sprint-assess/manager.js +0 -382
- package/dist/review/sprint-assess/prompts.js +0 -99
- package/dist/review/sprint-assess/routes.js +0 -109
- package/dist/review/sprint-assess/schema.js +0 -70
- package/dist/review/sprint-assess/validate.js +0 -180
- package/dist/review/sprint-story/manager.js +0 -98
- package/dist/review/sprint-story/prompt.js +0 -45
- package/dist/review/sprint-story/validate.js +0 -127
- package/dist/review/story-docs/build-prompts.js +0 -153
- package/dist/review/story-docs/build-validate.js +0 -162
- package/dist/review/story-report/agent.js +0 -203
- package/dist/review/story-report/fingerprint.js +0 -45
- package/dist/review/story-report/manager.js +0 -287
- package/dist/review/story-report/routes.js +0 -154
- package/dist/review/story-report/story-detail.js +0 -148
- package/dist/review/story-report/validate.js +0 -105
- package/dist/review/ticket-review/sweep-waits.js +0 -20
- package/dist/review/write-deny.js +0 -170
- package/dist/shared/conflict-ai.js +0 -24
- package/dist/sync/benchmark-rollup.js +0 -50
- package/public/assets/index-CbEfmqOD.css +0 -1
- package/public/assets/index-DBK4RWQu.js +0 -136
package/dist/db/schema.sqlite.js
CHANGED
|
@@ -185,6 +185,12 @@ export const repos = sqliteTable('repos', {
|
|
|
185
185
|
// from GitHub (a nulled selection leaves it as it was); `checked_at` stamps every attempt.
|
|
186
186
|
usesGithubIssues: integer('uses_github_issues', { mode: 'boolean' }),
|
|
187
187
|
githubIssuesCheckedAt: integer('github_issues_checked_at', { mode: 'timestamp' }),
|
|
188
|
+
// ---- TAGS (migration 0195; docs/RELEASES.md) ----
|
|
189
|
+
// What the last COMPLETE tag read saw, as `tagSignature` (sync/repo-tags.ts): the tag count plus
|
|
190
|
+
// the newest tag's name and target. The settle sweep reads the same three facts for ~nothing and
|
|
191
|
+
// starts a tag sync when they differ — a tag push is updatedAt-silent. NULL = never read.
|
|
192
|
+
tagsSignature: text('tags_signature'),
|
|
193
|
+
tagsSyncedAt: integer('tags_synced_at', { mode: 'timestamp' }),
|
|
188
194
|
}, (t) => ({
|
|
189
195
|
// Composite uniques so two accounts can watch the same GitHub repo (each
|
|
190
196
|
// gets its own row). The upsert conflict targets these.
|
|
@@ -408,8 +414,17 @@ export const pullRequests = sqliteTable('pull_requests', {
|
|
|
408
414
|
linearLinks: text('linear_links', { mode: 'json' }).$type(),
|
|
409
415
|
linearLinksRoot: text('linear_links_root'),
|
|
410
416
|
linearLinksCheckedAt: integer('linear_links_checked_at', { mode: 'timestamp' }),
|
|
417
|
+
// ---- RELEASES (migration 0195; docs/RELEASES.md) ----
|
|
418
|
+
// The commit this PR landed as on its base branch (GraphQL `mergeCommit { oid }`): the squash
|
|
419
|
+
// commit, the merge commit, or the last rebased commit. A version tag's range maps the commits
|
|
420
|
+
// between two tags to PRs through it (sync/tag-ranges.ts). ⚠ Cleared only on a positive
|
|
421
|
+
// statement: an oid is written when one arrives; null only for a PR GitHub says is NOT merged
|
|
422
|
+
// (sync/upsert.ts `mergeCommitOidToWrite`). NULL on a merged PR = not observed yet.
|
|
423
|
+
mergeCommitOid: text('merge_commit_oid'),
|
|
411
424
|
}, (t) => ({
|
|
412
425
|
repoIdx: index('pr_repo_idx').on(t.repoId),
|
|
426
|
+
// The tag range's commit → PR lookup (sync/tag-ranges.ts), a batch of shas within one repo.
|
|
427
|
+
mergeCommitIdx: index('pr_account_repo_merge_commit_idx').on(t.accountId, t.repoId, t.mergeCommitOid),
|
|
413
428
|
openedIdx: index('pr_opened_idx').on(t.openedAt),
|
|
414
429
|
accountIdx: index('pr_account_idx').on(t.accountId),
|
|
415
430
|
// Drives getUserStats (the contributor popover) from the person rather than the account.
|
|
@@ -2113,6 +2128,13 @@ export const workspaces = sqliteTable('workspaces', {
|
|
|
2113
2128
|
// `AI_REVIEWS_FIRST_LOOK_DAYS` days). Never moves back. The ONE reader/writer is
|
|
2114
2129
|
// db/ai-reviews-seen.ts.
|
|
2115
2130
|
aiReviewsSeenAt: integer('ai_reviews_seen_at', { mode: 'timestamp' }),
|
|
2131
|
+
// RELEASES (migration 0195; docs/RELEASES.md § Terms and settings): the RELEASE suffix (a
|
|
2132
|
+
// release tag is `<version tag><release suffix>`) and the HOTFIX suffix (a hotfix tag ends in
|
|
2133
|
+
// it). NULL = not set, and there is NO default: the Releases tab and the hotfix option do
|
|
2134
|
+
// nothing until BOTH are set. Validated by shared `validateReleaseSettings`; the ONE reader /
|
|
2135
|
+
// writer is db/release-settings.ts. Per workspace, no inheritance.
|
|
2136
|
+
releaseSuffix: text('release_suffix'),
|
|
2137
|
+
hotfixSuffix: text('hotfix_suffix'),
|
|
2116
2138
|
createdAt: integer('created_at', { mode: 'timestamp' })
|
|
2117
2139
|
.notNull()
|
|
2118
2140
|
.default(sql `(unixepoch())`),
|
|
@@ -4217,6 +4239,10 @@ export const storyBuilds = sqliteTable('story_builds', {
|
|
|
4217
4239
|
endToEnd: integer('end_to_end', { mode: 'boolean' }).notNull().default(false),
|
|
4218
4240
|
e2eTicketClaimedAt: integer('e2e_ticket_claimed_at', { mode: 'timestamp' }),
|
|
4219
4241
|
e2eTicketJson: text('e2e_ticket_json', { mode: 'json' }).$type(),
|
|
4242
|
+
// HOTFIX (migration 0196; docs/STORY-BUILD.md § Hotfix builds): "Treat as a hotfix" at Start. Each repository
|
|
4243
|
+
// with a latest release is fixed there and the fix PORTED to the default branch; the review loop and
|
|
4244
|
+
// "Build end to end" are refused for it.
|
|
4245
|
+
hotfix: integer('hotfix', { mode: 'boolean' }).notNull().default(false),
|
|
4220
4246
|
createdAt: integer('created_at', { mode: 'timestamp' }).notNull().default(sql `(unixepoch())`),
|
|
4221
4247
|
startedAt: integer('started_at', { mode: 'timestamp' }),
|
|
4222
4248
|
completedAt: integer('completed_at', { mode: 'timestamp' }),
|
|
@@ -4282,6 +4308,35 @@ export const storyBuildRepos = sqliteTable('story_build_repos', {
|
|
|
4282
4308
|
loopPushedTree: text('loop_pushed_tree'),
|
|
4283
4309
|
loopPushedAt: integer('loop_pushed_at', { mode: 'timestamp' }),
|
|
4284
4310
|
loopEnded: text('loop_ended'),
|
|
4311
|
+
// HOTFIX (migration 0196; docs/STORY-BUILD.md § Hotfix builds). `hotfix_tag` = the latest release the
|
|
4312
|
+
// release checkout starts at (NULL on an ordinary build and on a read-only repository); `read_only` = no
|
|
4313
|
+
// release yet, its changes are refused at extraction. `main_*` = THE MAIN FIX (the default-branch checkout
|
|
4314
|
+
// in the same sandbox): its base, path, patch and push record, beside the row's own (the RELEASE FIX).
|
|
4315
|
+
hotfixTag: text('hotfix_tag'),
|
|
4316
|
+
readOnly: integer('read_only', { mode: 'boolean' }).notNull().default(false),
|
|
4317
|
+
mainBaseRef: text('main_base_ref'),
|
|
4318
|
+
mainBaseSha: text('main_base_sha'),
|
|
4319
|
+
mainSandboxPath: text('main_sandbox_path'),
|
|
4320
|
+
mainPatch: text('main_patch'),
|
|
4321
|
+
mainPatchSha: text('main_patch_sha'),
|
|
4322
|
+
mainStatJson: text('main_stat_json', { mode: 'json' }).$type(),
|
|
4323
|
+
mainFilesChangedJson: text('main_files_changed_json', { mode: 'json' }).$type(),
|
|
4324
|
+
mainCommitMessage: text('main_commit_message'),
|
|
4325
|
+
// NULL (not built yet) | 'ready' | 'skipped' (no change) | 'failed' | 'pushed'.
|
|
4326
|
+
mainStatus: text('main_status'),
|
|
4327
|
+
mainError: text('main_error'),
|
|
4328
|
+
mainPushedBranch: text('main_pushed_branch'),
|
|
4329
|
+
mainPushedPrNumber: integer('main_pushed_pr_number'),
|
|
4330
|
+
mainPushedPrUrl: text('main_pushed_pr_url'),
|
|
4331
|
+
mainPushedCommitSha: text('main_pushed_commit_sha'),
|
|
4332
|
+
mainPushedAt: integer('main_pushed_at', { mode: 'timestamp' }),
|
|
4333
|
+
mainPushError: text('main_push_error'),
|
|
4334
|
+
mainPushErrorCode: text('main_push_error_code'),
|
|
4335
|
+
// Push's record of `hotfix/<tag>` (shared StoryBuildHotfixBranch): created or found, moved, the PRs on it.
|
|
4336
|
+
hotfixBranchJson: text('hotfix_branch_json', { mode: 'json' }).$type(),
|
|
4337
|
+
// THE PORT REPORT (migration 0198): the agent's claim for this repository (same | adapted | not_needed,
|
|
4338
|
+
// the reason, the evidence), as the host checked and clipped it; NULL = no report. Untrusted model text.
|
|
4339
|
+
portReportJson: text('port_report_json', { mode: 'json' }).$type(),
|
|
4285
4340
|
provider: text('provider'),
|
|
4286
4341
|
model: text('model'),
|
|
4287
4342
|
effort: text('effort'),
|
|
@@ -4853,4 +4908,195 @@ export const limnActions = sqliteTable('limn_actions', {
|
|
|
4853
4908
|
foreignColumns: [pullRequests.id, pullRequests.accountId],
|
|
4854
4909
|
}).onDelete('cascade'),
|
|
4855
4910
|
}));
|
|
4911
|
+
// ---- RELEASES (migration 0195; docs/RELEASES.md) ------------------------------------------------
|
|
4912
|
+
//
|
|
4913
|
+
// FIVE tables, all account-scoped with composite FKs (tenancy as a constraint), all in
|
|
4914
|
+
// `accountScopedTables()` and erased explicitly; the repo-anchored ones in `deleteRepo` too.
|
|
4915
|
+
//
|
|
4916
|
+
// repo_tags one row per (account, repo, tag name): what the tag points at.
|
|
4917
|
+
// repo_tag_ranges one row per (account, repo, tag name): the PRs between the tag and the
|
|
4918
|
+
// tag before it on the default branch, computed once per (tag sha, base sha).
|
|
4919
|
+
// releases one row per reader press of "Create release…".
|
|
4920
|
+
// release_items one row per (release, repo): the release tag and the pre-release.
|
|
4921
|
+
// release_ticket_comments one row per (release, ticket): the tracker comment.
|
|
4922
|
+
// The repo's git tags, synced as part of the default-branch snapshot step (sync/repo-tags.ts) —
|
|
4923
|
+
// STRICTLY NON-FATAL, the newest REPO_TAGS_READ_CAP by the tagged commit's date. A tag PUSH is
|
|
4924
|
+
// updatedAt-silent, so the settle sweep notices it (`repos.tags_signature`).
|
|
4925
|
+
// sha the COMMIT the tag points at (an annotated tag is peeled one level).
|
|
4926
|
+
// tag_object_oid the annotated tag object's oid; NULL for a lightweight tag.
|
|
4927
|
+
// committed_at the tagged commit's date — the order "newest version tag" means.
|
|
4928
|
+
// tagged_at the annotated tag's tagger date (the tie-break "by tag creation"); NULL for a
|
|
4929
|
+
// lightweight tag.
|
|
4930
|
+
// on_default_branch the tagged commit is an ancestor of (or equal to) the default branch head.
|
|
4931
|
+
// NULL = not known yet. `ancestry_head_sha` is the head it was checked against:
|
|
4932
|
+
// true is final for that sha (until the tag moves); false is re-checked when the
|
|
4933
|
+
// head moves.
|
|
4934
|
+
// previous_sha / moved_at the tag was MOVED to another commit (re-pushed with --force): the sha
|
|
4935
|
+
// it pointed at before, and when Ensemble saw the move.
|
|
4936
|
+
export const repoTags = sqliteTable('repo_tags', {
|
|
4937
|
+
id: integer('id').primaryKey({ autoIncrement: true }),
|
|
4938
|
+
accountId: integer('account_id')
|
|
4939
|
+
.notNull()
|
|
4940
|
+
.references(() => accounts.id, { onDelete: 'cascade' }),
|
|
4941
|
+
repoId: integer('repo_id').notNull(),
|
|
4942
|
+
name: text('name').notNull(),
|
|
4943
|
+
sha: text('sha').notNull(),
|
|
4944
|
+
tagObjectOid: text('tag_object_oid'),
|
|
4945
|
+
committedAt: integer('committed_at', { mode: 'timestamp' }),
|
|
4946
|
+
taggedAt: integer('tagged_at', { mode: 'timestamp' }),
|
|
4947
|
+
onDefaultBranch: integer('on_default_branch', { mode: 'boolean' }),
|
|
4948
|
+
ancestryHeadSha: text('ancestry_head_sha'),
|
|
4949
|
+
previousSha: text('previous_sha'),
|
|
4950
|
+
movedAt: integer('moved_at', { mode: 'timestamp' }),
|
|
4951
|
+
firstSeenAt: integer('first_seen_at', { mode: 'timestamp' }).notNull(),
|
|
4952
|
+
lastSeenAt: integer('last_seen_at', { mode: 'timestamp' }).notNull(),
|
|
4953
|
+
}, (t) => ({
|
|
4954
|
+
nameUx: uniqueIndex('repo_tags_account_repo_name').on(t.accountId, t.repoId, t.name),
|
|
4955
|
+
shaIdx: index('repo_tags_account_repo_sha_idx').on(t.accountId, t.repoId, t.sha),
|
|
4956
|
+
repoAccountFk: foreignKey({
|
|
4957
|
+
name: 'repo_tags_repo_account_fk',
|
|
4958
|
+
columns: [t.repoId, t.accountId],
|
|
4959
|
+
foreignColumns: [repos.id, repos.accountId],
|
|
4960
|
+
}).onDelete('cascade'),
|
|
4961
|
+
}));
|
|
4962
|
+
// A tag's range INCREMENT (sync/tag-ranges.ts): the PRs merged into the default branch in
|
|
4963
|
+
// (base, tag], where base is the tag before it on the default branch (by committed date, then
|
|
4964
|
+
// name). Suffix-free on purpose — the release check sums increments from the baseline up to a
|
|
4965
|
+
// version tag, so a new release (a new baseline) or a changed suffix needs no recompute.
|
|
4966
|
+
// base_tag_name / base_sha NULL for the OLDEST tag Ensemble knows: its range is every PR in the
|
|
4967
|
+
// synced history merged into the default branch no later than the tag's commit
|
|
4968
|
+
// (method 'history'), so older PRs are not checked.
|
|
4969
|
+
// method 'compare' (REST compare base...tag) | 'history' (no base: the stored PRs).
|
|
4970
|
+
// pr_numbers the PRs, by NUMBER (a PR the walk has not stored yet still counts). Resolved to
|
|
4971
|
+
// local ids within (account, repo) on read (db/repo-tags.ts).
|
|
4972
|
+
// commit_count / unmatched_commits commits in the range, and how many matched no PR (direct pushes).
|
|
4973
|
+
// truncated the compare had more commits than Ensemble reads (TAG_RANGE_MAX_COMMITS).
|
|
4974
|
+
// moved_from_sha the tag MOVED since the last computation: the sha the old range was for.
|
|
4975
|
+
// Recomputed only when the tag's sha or its base's sha changes.
|
|
4976
|
+
export const repoTagRanges = sqliteTable('repo_tag_ranges', {
|
|
4977
|
+
id: integer('id').primaryKey({ autoIncrement: true }),
|
|
4978
|
+
accountId: integer('account_id')
|
|
4979
|
+
.notNull()
|
|
4980
|
+
.references(() => accounts.id, { onDelete: 'cascade' }),
|
|
4981
|
+
repoId: integer('repo_id').notNull(),
|
|
4982
|
+
tagName: text('tag_name').notNull(),
|
|
4983
|
+
sha: text('sha').notNull(),
|
|
4984
|
+
baseTagName: text('base_tag_name'),
|
|
4985
|
+
baseSha: text('base_sha'),
|
|
4986
|
+
method: text('method', { enum: ['compare', 'history'] }).notNull(),
|
|
4987
|
+
prNumbers: text('pr_numbers', { mode: 'json' }).$type().notNull(),
|
|
4988
|
+
commitCount: integer('commit_count').notNull().default(0),
|
|
4989
|
+
unmatchedCommits: integer('unmatched_commits').notNull().default(0),
|
|
4990
|
+
truncated: integer('truncated', { mode: 'boolean' }).notNull().default(false),
|
|
4991
|
+
movedFromSha: text('moved_from_sha'),
|
|
4992
|
+
computedAt: integer('computed_at', { mode: 'timestamp' }).notNull(),
|
|
4993
|
+
}, (t) => ({
|
|
4994
|
+
tagUx: uniqueIndex('repo_tag_ranges_account_repo_tag').on(t.accountId, t.repoId, t.tagName),
|
|
4995
|
+
repoAccountFk: foreignKey({
|
|
4996
|
+
name: 'repo_tag_ranges_repo_account_fk',
|
|
4997
|
+
columns: [t.repoId, t.accountId],
|
|
4998
|
+
foreignColumns: [repos.id, repos.accountId],
|
|
4999
|
+
}).onDelete('cascade'),
|
|
5000
|
+
}));
|
|
5001
|
+
// One row per press of "Create release…" (docs/RELEASES.md § Releases tab). `notes_markdown` is the
|
|
5002
|
+
// whole document (a section per repo); `release_suffix` the suffix in force when it was made.
|
|
5003
|
+
// state 'writing' (the writes are running) · 'done' (every step worked) · 'partial' (some
|
|
5004
|
+
// failed) · 'failed' (nothing was written) · 'stopped' (Confirm's re-check found a change).
|
|
5005
|
+
export const releases = sqliteTable('releases', {
|
|
5006
|
+
id: integer('id').primaryKey({ autoIncrement: true }),
|
|
5007
|
+
accountId: integer('account_id')
|
|
5008
|
+
.notNull()
|
|
5009
|
+
.references(() => accounts.id, { onDelete: 'cascade' }),
|
|
5010
|
+
workspaceId: integer('workspace_id').notNull(),
|
|
5011
|
+
createdByUserId: integer('created_by_user_id').references(() => users.id),
|
|
5012
|
+
createdByLogin: text('created_by_login'),
|
|
5013
|
+
createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
|
|
5014
|
+
releaseSuffix: text('release_suffix').notNull(),
|
|
5015
|
+
notesMarkdown: text('notes_markdown').notNull().default(''),
|
|
5016
|
+
state: text('state', { enum: ['writing', 'done', 'partial', 'failed', 'stopped'] }).notNull(),
|
|
5017
|
+
finishedAt: integer('finished_at', { mode: 'timestamp' }),
|
|
5018
|
+
}, (t) => ({
|
|
5019
|
+
workspaceIdx: index('releases_account_workspace_idx').on(t.accountId, t.workspaceId, t.createdAt),
|
|
5020
|
+
// The PARENT KEY of the two child tables' composite FKs (the `repos_id_account` trick).
|
|
5021
|
+
idAccountUx: uniqueIndex('releases_id_account').on(t.id, t.accountId),
|
|
5022
|
+
workspaceAccountFk: foreignKey({
|
|
5023
|
+
name: 'releases_workspace_account_fk',
|
|
5024
|
+
columns: [t.workspaceId, t.accountId],
|
|
5025
|
+
foreignColumns: [workspaces.id, workspaces.accountId],
|
|
5026
|
+
}).onDelete('cascade'),
|
|
5027
|
+
}));
|
|
5028
|
+
// One row per (release, repo). Two GitHub writes, each CLAIMED (compare-and-set on its state)
|
|
5029
|
+
// BEFORE the call and NEVER retried: the annotated release tag, then the pre-release on it.
|
|
5030
|
+
// *_state 'pending' → 'claimed' → 'done' | 'failed'; a tag whose name already exists is
|
|
5031
|
+
// 'refused' (never moved); a pre-release whose tag did not land is 'skipped'.
|
|
5032
|
+
// ⚠ UNIQUE (account, repo, release_tag_name) across releases: a second press can never write the
|
|
5033
|
+
// same tag again — the claim is the row.
|
|
5034
|
+
export const releaseItems = sqliteTable('release_items', {
|
|
5035
|
+
id: integer('id').primaryKey({ autoIncrement: true }),
|
|
5036
|
+
accountId: integer('account_id')
|
|
5037
|
+
.notNull()
|
|
5038
|
+
.references(() => accounts.id, { onDelete: 'cascade' }),
|
|
5039
|
+
releaseId: integer('release_id').notNull(),
|
|
5040
|
+
repoId: integer('repo_id').notNull(),
|
|
5041
|
+
versionTag: text('version_tag').notNull(),
|
|
5042
|
+
sha: text('sha').notNull(),
|
|
5043
|
+
releaseTagName: text('release_tag_name').notNull(),
|
|
5044
|
+
notesMarkdown: text('notes_markdown').notNull().default(''),
|
|
5045
|
+
tagState: text('tag_state', { enum: ['pending', 'claimed', 'done', 'failed', 'refused'] })
|
|
5046
|
+
.notNull()
|
|
5047
|
+
.default('pending'),
|
|
5048
|
+
tagObjectOid: text('tag_object_oid'),
|
|
5049
|
+
prereleaseState: text('prerelease_state', {
|
|
5050
|
+
enum: ['pending', 'claimed', 'done', 'failed', 'skipped'],
|
|
5051
|
+
})
|
|
5052
|
+
.notNull()
|
|
5053
|
+
.default('pending'),
|
|
5054
|
+
githubReleaseId: integer('github_release_id'),
|
|
5055
|
+
githubReleaseUrl: text('github_release_url'),
|
|
5056
|
+
error: text('error'),
|
|
5057
|
+
updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull(),
|
|
5058
|
+
}, (t) => ({
|
|
5059
|
+
releaseRepoUx: uniqueIndex('release_items_account_release_repo').on(t.accountId, t.releaseId, t.repoId),
|
|
5060
|
+
// ⚠ The tag-name UNIQUE is PARTIAL — only a live row (pending / claimed / done) holds the name, so
|
|
5061
|
+
// a failed or refused write does not block a later press. It lives in migration 0197 ONLY
|
|
5062
|
+
// (`release_items_account_repo_tag_live`); this is its plain lookup index.
|
|
5063
|
+
tagNameIdx: index('release_items_account_repo_tag_idx').on(t.accountId, t.repoId, t.releaseTagName),
|
|
5064
|
+
releaseAccountFk: foreignKey({
|
|
5065
|
+
name: 'release_items_release_account_fk',
|
|
5066
|
+
columns: [t.releaseId, t.accountId],
|
|
5067
|
+
foreignColumns: [releases.id, releases.accountId],
|
|
5068
|
+
}).onDelete('cascade'),
|
|
5069
|
+
repoAccountFk: foreignKey({
|
|
5070
|
+
name: 'release_items_repo_account_fk',
|
|
5071
|
+
columns: [t.repoId, t.accountId],
|
|
5072
|
+
foreignColumns: [repos.id, repos.accountId],
|
|
5073
|
+
}).onDelete('cascade'),
|
|
5074
|
+
}));
|
|
5075
|
+
// One row per (release, ticket): the tracker comment on a shipped ticket (a ticket whose repos ALL
|
|
5076
|
+
// tagged). CLAIMED before the tracker write, NEVER retried.
|
|
5077
|
+
// state 'pending' → 'claimed' → 'posted' | 'failed'; 'skipped' when the ticket did not ship
|
|
5078
|
+
// whole or the tracker cannot take a comment yet (`error` says which).
|
|
5079
|
+
export const releaseTicketComments = sqliteTable('release_ticket_comments', {
|
|
5080
|
+
id: integer('id').primaryKey({ autoIncrement: true }),
|
|
5081
|
+
accountId: integer('account_id')
|
|
5082
|
+
.notNull()
|
|
5083
|
+
.references(() => accounts.id, { onDelete: 'cascade' }),
|
|
5084
|
+
releaseId: integer('release_id').notNull(),
|
|
5085
|
+
ticketKey: text('ticket_key').notNull(),
|
|
5086
|
+
trackerKind: text('tracker_kind'),
|
|
5087
|
+
state: text('state', { enum: ['pending', 'claimed', 'posted', 'failed', 'skipped'] })
|
|
5088
|
+
.notNull()
|
|
5089
|
+
.default('pending'),
|
|
5090
|
+
commentId: text('comment_id'),
|
|
5091
|
+
error: text('error'),
|
|
5092
|
+
claimedAt: integer('claimed_at', { mode: 'timestamp' }),
|
|
5093
|
+
postedAt: integer('posted_at', { mode: 'timestamp' }),
|
|
5094
|
+
}, (t) => ({
|
|
5095
|
+
releaseTicketUx: uniqueIndex('release_ticket_comments_account_release_ticket').on(t.accountId, t.releaseId, t.ticketKey),
|
|
5096
|
+
releaseAccountFk: foreignKey({
|
|
5097
|
+
name: 'release_ticket_comments_release_account_fk',
|
|
5098
|
+
columns: [t.releaseId, t.accountId],
|
|
5099
|
+
foreignColumns: [releases.id, releases.accountId],
|
|
5100
|
+
}).onDelete('cascade'),
|
|
5101
|
+
}));
|
|
4856
5102
|
//# sourceMappingURL=schema.sqlite.js.map
|
package/dist/github/mutations.js
CHANGED
|
@@ -964,6 +964,73 @@ async function setReactionNow(token, subjectNodeId, content, add) {
|
|
|
964
964
|
viewerCanReact: subject.viewerCanReact === true,
|
|
965
965
|
};
|
|
966
966
|
}
|
|
967
|
+
// ---- Release tags and pre-releases (docs/RELEASES.md § Releases tab 6) ----
|
|
968
|
+
//
|
|
969
|
+
// The READER's Confirm (releases/create.ts) — the caller claims each write first and never retries.
|
|
970
|
+
// `createAnnotatedReleaseTag` makes the annotated tag object on the commit, then its ref; it NEVER moves
|
|
971
|
+
// a ref (no PATCH): a 422 on the ref (the name exists) is reported as `exists`. Errors carry GitHub's
|
|
972
|
+
// `status` (ghRest), which the caller turns into a short sentence.
|
|
973
|
+
export async function createAnnotatedReleaseTag(token, args, origin) {
|
|
974
|
+
return limnWrite(origin, 'release_tag', {}, async () => {
|
|
975
|
+
const seg = encodeURIComponent;
|
|
976
|
+
const obj = await ghRestPostFor(token, `/repos/${seg(args.owner)}/${seg(args.name)}/git/tags`, {
|
|
977
|
+
tag: args.tag,
|
|
978
|
+
message: args.message,
|
|
979
|
+
object: args.sha,
|
|
980
|
+
type: 'commit',
|
|
981
|
+
});
|
|
982
|
+
if (typeof obj.sha !== 'string')
|
|
983
|
+
throw Object.assign(new Error('GitHub returned no tag object'), { status: 422, stage: 'object' });
|
|
984
|
+
try {
|
|
985
|
+
await ghRestPostFor(token, `/repos/${seg(args.owner)}/${seg(args.name)}/git/refs`, { ref: `refs/tags/${args.tag}`, sha: obj.sha });
|
|
986
|
+
}
|
|
987
|
+
catch (err) {
|
|
988
|
+
throw Object.assign(err instanceof Error ? err : new Error(String(err)), { stage: 'ref' });
|
|
989
|
+
}
|
|
990
|
+
return { tagObjectOid: obj.sha };
|
|
991
|
+
}, () => ({ detail: args.tag }));
|
|
992
|
+
}
|
|
993
|
+
// HOTFIX (docs/STORY-BUILD.md § Hotfix builds): `hotfix/<tag>` made at the release commit, on the reader's Push.
|
|
994
|
+
// A NEW ref only (POST git/refs): it never moves one. GitHub's 422 ("Reference already exists") comes back as
|
|
995
|
+
// `exists`, so the caller re-reads the branch instead of guessing.
|
|
996
|
+
export async function createHotfixBranch(token, args, origin) {
|
|
997
|
+
return limnWrite(origin, 'hotfix_branch', {}, async () => {
|
|
998
|
+
const seg = encodeURIComponent;
|
|
999
|
+
try {
|
|
1000
|
+
await ghRestPostFor(token, `/repos/${seg(args.owner)}/${seg(args.name)}/git/refs`, { ref: `refs/heads/${args.branch}`, sha: args.sha });
|
|
1001
|
+
return { outcome: 'created' };
|
|
1002
|
+
}
|
|
1003
|
+
catch (err) {
|
|
1004
|
+
if (err?.status === 422)
|
|
1005
|
+
return { outcome: 'exists' };
|
|
1006
|
+
throw err;
|
|
1007
|
+
}
|
|
1008
|
+
}, () => ({ detail: args.branch }));
|
|
1009
|
+
}
|
|
1010
|
+
/** The OPEN pull requests whose base is `branch` (a hotfix branch that moved past its release: the tab names
|
|
1011
|
+
* them). A read; at most 30, newest first. Throws on a failed read. */
|
|
1012
|
+
export async function fetchOpenPrsOnBase(token, owner, name, branch) {
|
|
1013
|
+
const seg = encodeURIComponent;
|
|
1014
|
+
const rows = await ghRestGetFor(token, `/repos/${seg(owner)}/${seg(name)}/pulls?state=open&base=${seg(branch)}&sort=created&direction=desc&per_page=30`);
|
|
1015
|
+
return (Array.isArray(rows) ? rows : [])
|
|
1016
|
+
.filter((p) => typeof p.number === 'number')
|
|
1017
|
+
.map((p) => ({ number: p.number, title: typeof p.title === 'string' ? p.title : '', url: typeof p.html_url === 'string' ? p.html_url : null }));
|
|
1018
|
+
}
|
|
1019
|
+
export async function createGithubPrerelease(token, args, origin) {
|
|
1020
|
+
return limnWrite(origin, 'prerelease', {}, async () => {
|
|
1021
|
+
const seg = encodeURIComponent;
|
|
1022
|
+
const r = await ghRestPostFor(token, `/repos/${seg(args.owner)}/${seg(args.name)}/releases`, {
|
|
1023
|
+
tag_name: args.tag,
|
|
1024
|
+
name: args.title,
|
|
1025
|
+
body: args.body,
|
|
1026
|
+
prerelease: true,
|
|
1027
|
+
draft: false,
|
|
1028
|
+
});
|
|
1029
|
+
if (typeof r.id !== 'number' || typeof r.html_url !== 'string')
|
|
1030
|
+
throw Object.assign(new Error('GitHub returned no release'), { status: 422 });
|
|
1031
|
+
return { id: r.id, url: r.html_url };
|
|
1032
|
+
}, (r) => ({ detail: r.url }));
|
|
1033
|
+
}
|
|
967
1034
|
// ---- Git data writes (the Implement build claim's placeholder branch) ----
|
|
968
1035
|
// Raw git-data REST writes live here, with the other guarded writes (write-origin.test.ts). The
|
|
969
1036
|
// placeholder belongs to the reader's Implement build, so its caller passes the reader's origin.
|
package/dist/github/queries.js
CHANGED
|
@@ -141,6 +141,11 @@ const PR_NODE_FIELDS = /* GraphQL */ `
|
|
|
141
141
|
# another open PR's head branch in THIS repo, and a fork's branch name says nothing about a branch
|
|
142
142
|
# here — so a parent must be proven same-repo. A Boolean! scalar on a node already fetched.
|
|
143
143
|
isCrossRepository
|
|
144
|
+
# The commit this PR landed as (docs/RELEASES.md): a version tag's range maps commits to PRs
|
|
145
|
+
# through it. A nullable OBJECT, not a connection — no nodes, no cost.
|
|
146
|
+
mergeCommit {
|
|
147
|
+
oid
|
|
148
|
+
}
|
|
144
149
|
mergeable
|
|
145
150
|
mergeStateStatus
|
|
146
151
|
# ---- merge verdict (cluster A: the merge surface) ------------------------------------
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
// enough to tell whether our stored row is still right about the things GitHub changes WITHOUT
|
|
5
5
|
// bumping `updatedAt`: the head commit, its CI rollup, the review-thread resolutions — plus
|
|
6
6
|
// `updatedAt` itself, so a PR the walk missed is noticed too, and the default branch's head, so a
|
|
7
|
-
// trunk move (which silently re-decides every open PR's merge state) is noticed
|
|
7
|
+
// trunk move (which silently re-decides every open PR's merge state) is noticed, and the newest
|
|
8
|
+
// tag + tag count (`refs(first: 1)`, one node), so a tag push is noticed (sync/tags-step.ts).
|
|
8
9
|
//
|
|
9
10
|
// COST — MEASURED 2026-10-28 (`rateLimit { cost }`, read-only, on a real 9-repo workspace): 9
|
|
10
11
|
// points for 9 aliased repos, i.e. ~1 point per repo. GitHub prices a query by the requests its
|
|
@@ -65,6 +66,15 @@ export function buildSettleSweepQuery(count) {
|
|
|
65
66
|
oid
|
|
66
67
|
}
|
|
67
68
|
}
|
|
69
|
+
tags: refs(refPrefix: "refs/tags/", first: 1, orderBy: { field: TAG_COMMIT_DATE, direction: DESC }) {
|
|
70
|
+
totalCount
|
|
71
|
+
nodes {
|
|
72
|
+
name
|
|
73
|
+
target {
|
|
74
|
+
oid
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
68
78
|
pullRequests(
|
|
69
79
|
states: [OPEN]
|
|
70
80
|
first: ${SETTLE_PR_PAGE}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// TAGS (docs/RELEASES.md) — READ only: the repo's tags (GraphQL), the commits between two commits
|
|
2
|
+
// (REST compare), and the PRs a handful of commits came from (GraphQL, the fallback for a commit
|
|
3
|
+
// no stored PR's `merge_commit_oid` names).
|
|
4
|
+
//
|
|
5
|
+
// COST.
|
|
6
|
+
// • REPO_TAGS_QUERY: one `refs(first: 100)` connection with no child connection ⇒ 1 point.
|
|
7
|
+
// • The settle sweep adds `refs(first: 1)` per repo to its own query (github/settle-query.ts):
|
|
8
|
+
// one node, no measurable change to its ~1 point per repo.
|
|
9
|
+
// • compareCommits: REST (the core REST budget, not GraphQL points), one call per page of 100
|
|
10
|
+
// commits; ancestry asks for ONE commit (per_page=1).
|
|
11
|
+
// • buildCommitPrsQuery: ≤ COMMIT_PRS_ALIAS_CAP aliases × associatedPullRequests(first: 3) ⇒
|
|
12
|
+
// ≤ 150 nodes ⇒ 2 points.
|
|
13
|
+
//
|
|
14
|
+
// Nullability: everything a tolerant partial (`graphqlTolerant`) can null is optional below.
|
|
15
|
+
import { ghRestGetFor, withGithubRetry } from './client.js';
|
|
16
|
+
/** Tags read per sync, newest by the tagged commit's date. Past this the read is incomplete. */
|
|
17
|
+
export const REPO_TAGS_READ_CAP = 100;
|
|
18
|
+
export const REPO_TAGS_QUERY = /* GraphQL */ `
|
|
19
|
+
query RepoTags($owner: String!, $name: String!, $first: Int!) {
|
|
20
|
+
rateLimit {
|
|
21
|
+
cost
|
|
22
|
+
remaining
|
|
23
|
+
resetAt
|
|
24
|
+
}
|
|
25
|
+
repository(owner: $owner, name: $name) {
|
|
26
|
+
defaultBranchRef {
|
|
27
|
+
name
|
|
28
|
+
target {
|
|
29
|
+
oid
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
refs(refPrefix: "refs/tags/", first: $first, orderBy: { field: TAG_COMMIT_DATE, direction: DESC }) {
|
|
33
|
+
totalCount
|
|
34
|
+
nodes {
|
|
35
|
+
name
|
|
36
|
+
target {
|
|
37
|
+
__typename
|
|
38
|
+
oid
|
|
39
|
+
... on Commit {
|
|
40
|
+
committedDate
|
|
41
|
+
}
|
|
42
|
+
... on Tag {
|
|
43
|
+
tagger {
|
|
44
|
+
date
|
|
45
|
+
}
|
|
46
|
+
target {
|
|
47
|
+
__typename
|
|
48
|
+
oid
|
|
49
|
+
... on Commit {
|
|
50
|
+
committedDate
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
`;
|
|
60
|
+
// ---- REST compare -------------------------------------------------------------------------------
|
|
61
|
+
const SHA_RE = /^[0-9a-fA-F]{7,64}$/;
|
|
62
|
+
/** One page of `GET /repos/{owner}/{name}/compare/{base}...{head}`. Throws as ghRestGetFor does. */
|
|
63
|
+
export async function fetchComparePage(token, args) {
|
|
64
|
+
if (!SHA_RE.test(args.base) || !SHA_RE.test(args.head))
|
|
65
|
+
throw new Error('compare: not a commit sha');
|
|
66
|
+
const path = `/repos/${encodeURIComponent(args.owner)}/${encodeURIComponent(args.name)}` +
|
|
67
|
+
`/compare/${args.base}...${args.head}?per_page=${args.perPage}&page=${args.page}`;
|
|
68
|
+
return withGithubRetry(() => ghRestGetFor(token, path));
|
|
69
|
+
}
|
|
70
|
+
// ---- The commit → PR fallback -------------------------------------------------------------------
|
|
71
|
+
/** Commits asked about in one request. */
|
|
72
|
+
export const COMMIT_PRS_ALIAS_CAP = 50;
|
|
73
|
+
/** One aliased `object(oid:)` per commit sha; the shas travel as VARIABLES (`s<i>`). */
|
|
74
|
+
export function buildCommitPrsQuery(count) {
|
|
75
|
+
const vars = Array.from({ length: count }, (_, i) => `$s${i}: GitObjectID!`).join(', ');
|
|
76
|
+
const aliases = Array.from({ length: count }, (_, i) => ` c${i}: object(oid: $s${i}) {
|
|
77
|
+
... on Commit {
|
|
78
|
+
associatedPullRequests(first: 3) {
|
|
79
|
+
nodes {
|
|
80
|
+
number
|
|
81
|
+
merged
|
|
82
|
+
baseRefName
|
|
83
|
+
repository {
|
|
84
|
+
nameWithOwner
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}`).join('\n');
|
|
90
|
+
return `query CommitPrs($owner: String!, $name: String!${count > 0 ? `, ${vars}` : ''}) {
|
|
91
|
+
rateLimit {
|
|
92
|
+
cost
|
|
93
|
+
remaining
|
|
94
|
+
resetAt
|
|
95
|
+
}
|
|
96
|
+
repository(owner: $owner, name: $name) {
|
|
97
|
+
${aliases}
|
|
98
|
+
}
|
|
99
|
+
}`;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=tag-queries.js.map
|