Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion packages/mergebot/src/_tests/fixturedActions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,28 @@ async function testFixture(dir: string) {
const prInfo = response.data.repository?.pullRequest;
if (!prInfo) throw new Error("Should never happen");

// Fixtures recorded before potentialMergeCommit was queried use the head tree.
const prInfoWithMergeCommit =
prInfo.potentialMergeCommit === undefined && prInfo.mergeable !== "CONFLICTING"
? {
...prInfo,
potentialMergeCommit: {
__typename: "Commit" as const,
oid: prInfo.headRefOid,
parents: {
__typename: "CommitConnection" as const,
totalCount: 2,
nodes: [
{ __typename: "Commit" as const, oid: prInfo.baseRefOid },
{ __typename: "Commit" as const, oid: prInfo.headRefOid },
],
},
},
}
: prInfo;

const derived = await deriveStateForPR(
prInfo,
prInfoWithMergeCommit,
(expr: string) => Promise.resolve(files[expr] as string),
(name: string, _until?: Date) => (name in downloads ? downloads[name] : 0),
new Date(readJsonSync(derivedPath).now),
Expand All @@ -58,3 +78,40 @@ describe("Test fixtures", () => {
}
});
});

describe("Potential merge commit validation", () => {
const response: PRQueryResponse = readJsonSync(join(__dirname, "fixtures", "75475", "_response.json"));
const prInfo = response.data.repository?.pullRequest;
const potentialMergeCommit = prInfo?.potentialMergeCommit;
if (!prInfo || !potentialMergeCommit) throw new Error("Fixture must have a potential merge commit");

it("fails closed when the potential merge commit is unavailable", async () => {
const derived = await deriveStateForPR({ ...prInfo, potentialMergeCommit: null });

expect(derived).toMatchObject({
type: "error",
message: "No potential merge commit found",
});
});

it("fails closed when the potential merge commit has unexpected parents", async () => {
const derived = await deriveStateForPR({
...prInfo,
potentialMergeCommit: {
...potentialMergeCommit,
parents: {
...potentialMergeCommit.parents,
nodes: [
{ __typename: "Commit", oid: prInfo.baseRefOid },
{ __typename: "Commit", oid: "attacker-controlled-oid" },
],
},
},
});

expect(derived).toMatchObject({
type: "error",
message: "Potential merge commit does not match the pull request base and head",
});
});
});
3 changes: 3 additions & 0 deletions packages/mergebot/src/_tests/fixtures/75475/_downloads.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"chrome": 15528020
}
4 changes: 4 additions & 0 deletions packages/mergebot/src/_tests/fixtures/75475/_files.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"eded8b3161a48a130df54daefb1005b3807314b0:types/chrome/package.json": "{\n \"private\": true,\n \"name\": \"@types/chrome\",\n \"version\": \"0.2.9999\",\n \"nonNpm\": \"conflict\",\n \"nonNpmDescription\": \"The complete reference to all APIs made available to Chrome Extensions\",\n \"projects\": [\n \"https://developer.chrome.com/docs/extensions\"\n ],\n \"dependencies\": {\n \"@types/filesystem\": \"*\",\n \"@types/har-format\": \"*\"\n },\n \"devDependencies\": {\n \"@types/chrome\": \"workspace:.\"\n },\n \"owners\": [\n {\n \"name\": \"Matthew Kimber\",\n \"githubUsername\": \"matthewkimber\"\n },\n {\n \"name\": \"otiai10\",\n \"githubUsername\": \"otiai10\"\n },\n {\n \"name\": \"sreimer15\",\n \"githubUsername\": \"sreimer15\"\n },\n {\n \"name\": \"MatCarlson\",\n \"githubUsername\": \"MatCarlson\"\n },\n {\n \"name\": \"ekinsol\",\n \"githubUsername\": \"ekinsol\"\n },\n {\n \"name\": \"Brian Wilson\",\n \"githubUsername\": \"echoabstract\"\n },\n {\n \"name\": \"Sebastiaan Pasma\",\n \"githubUsername\": \"spasma\"\n },\n {\n \"name\": \"bdbai\",\n \"githubUsername\": \"bdbai\"\n },\n {\n \"name\": \"Jason Xian\",\n \"githubUsername\": \"JasonXian\"\n },\n {\n \"name\": \"userTim\",\n \"githubUsername\": \"usertim\"\n },\n {\n \"name\": \"Idan Zeierman\",\n \"githubUsername\": \"idan315\"\n },\n {\n \"name\": \"Nicolas Rodriguez\",\n \"githubUsername\": \"nicolas377\"\n },\n {\n \"name\": \"Ido Salomon\",\n \"githubUsername\": \"idosal\"\n },\n {\n \"name\": \"Federico Brigante\",\n \"githubUsername\": \"fregante\"\n },\n {\n \"name\": \"Erwan Jugand\",\n \"githubUsername\": \"erwanjugand\"\n }\n ]\n}\n",
"b9c31f6adfcb83f41dac2e1a3a628801f2e775eb:types/chrome/package.json": "{\n \"private\": true,\n \"name\": \"@types/chrome\",\n \"version\": \"0.2.9999\",\n \"nonNpm\": \"conflict\",\n \"nonNpmDescription\": \"The complete reference to all APIs made available to Chrome Extensions\",\n \"projects\": [\n \"https://developer.chrome.com/docs/extensions\"\n ],\n \"dependencies\": {\n \"@types/filesystem\": \"*\",\n \"@types/har-format\": \"*\"\n },\n \"devDependencies\": {\n \"@types/chrome\": \"workspace:.\"\n },\n \"owners\": [\n {\n \"name\": \"Matthew Kimber\",\n \"githubUsername\": \"matthewkimber\"\n },\n {\n \"name\": \"otiai10\",\n \"githubUsername\": \"otiai10\"\n },\n {\n \"name\": \"sreimer15\",\n \"githubUsername\": \"sreimer15\"\n },\n {\n \"name\": \"MatCarlson\",\n \"githubUsername\": \"MatCarlson\"\n },\n {\n \"name\": \"ekinsol\",\n \"githubUsername\": \"ekinsol\"\n },\n {\n \"name\": \"Brian Wilson\",\n \"githubUsername\": \"echoabstract\"\n },\n {\n \"name\": \"Sebastiaan Pasma\",\n \"githubUsername\": \"spasma\"\n },\n {\n \"name\": \"bdbai\",\n \"githubUsername\": \"bdbai\"\n },\n {\n \"name\": \"Jason Xian\",\n \"githubUsername\": \"JasonXian\"\n },\n {\n \"name\": \"userTim\",\n \"githubUsername\": \"usertim\"\n },\n {\n \"name\": \"Idan Zeierman\",\n \"githubUsername\": \"idan315\"\n },\n {\n \"name\": \"Nicolas Rodriguez\",\n \"githubUsername\": \"nicolas377\"\n },\n {\n \"name\": \"Ido Salomon\",\n \"githubUsername\": \"idosal\"\n },\n {\n \"name\": \"Federico Brigante\",\n \"githubUsername\": \"fregante\"\n },\n {\n \"name\": \"Erwan Jugand\",\n \"githubUsername\": \"erwanjugand\"\n }\n ]\n}\n"
}
246 changes: 246 additions & 0 deletions packages/mergebot/src/_tests/fixtures/75475/_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
{
"data": {
"repository": {
"id": "MDEwOlJlcG9zaXRvcnk2MDkzMzE2",
"pullRequest": {
"id": "PR_kwDOAFz6BM8AAAABBycrvQ",
"title": "chrome: Add global `browser` alias",
"createdAt": "2026-09-01T18:13:36Z",
"author": {
"login": "dgp1130",
"__typename": "User"
},
"authorAssociation": "CONTRIBUTOR",
"baseRef": {
"name": "master",
"__typename": "Ref"
},
"labels": {
"nodes": [
{
"name": "Critical package",
"__typename": "Label"
},
{
"name": "Edits Owners",
"__typename": "Label"
}
],
"__typename": "LabelConnection"
},
"isDraft": false,
"mergeable": "MERGEABLE",
"number": 75475,
"state": "OPEN",
"headRefOid": "4a708f0ad529dfbe67caec58197135d27b223f53",
"baseRefOid": "eded8b3161a48a130df54daefb1005b3807314b0",
"potentialMergeCommit": {
"oid": "b9c31f6adfcb83f41dac2e1a3a628801f2e775eb",
"parents": {
"totalCount": 2,
"nodes": [
{
"oid": "eded8b3161a48a130df54daefb1005b3807314b0",
"__typename": "Commit"
},
{
"oid": "4a708f0ad529dfbe67caec58197135d27b223f53",
"__typename": "Commit"
}
],
"__typename": "CommitConnection"
},
"__typename": "Commit"
},
"changedFiles": 2,
"additions": 8,
"deletions": 0,
"commitIds": {
"totalCount": 1,
"nodes": [
{
"commit": {
"oid": "4a708f0ad529dfbe67caec58197135d27b223f53",
"parents": {
"nodes": [
{
"oid": "5af8fdf21579b2afcb42b447b2def9b5dcc8c540",
"__typename": "Commit"
}
],
"__typename": "CommitConnection"
},
"__typename": "Commit"
},
"__typename": "PullRequestCommit"
}
],
"__typename": "PullRequestCommitConnection"
},
"timelineItems": {
"nodes": [],
"__typename": "PullRequestTimelineItemsConnection"
},
"reviews": {
"totalCount": 0,
"nodes": [],
"__typename": "PullRequestReviewConnection"
},
"commits": {
"totalCount": 1,
"nodes": [
{
"commit": {
"checkSuites": {
"nodes": [
{
"databaseId": 90895116570,
"app": {
"name": "GitHub Actions",
"__typename": "App"
},
"conclusion": "SUCCESS",
"resourcePath": "/DefinitelyTyped/DefinitelyTyped/commit/4a708f0ad529dfbe67caec58197135d27b223f53/checks?check_suite_id=90895116570",
"status": "COMPLETED",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped/commit/4a708f0ad529dfbe67caec58197135d27b223f53/checks?check_suite_id=90895116570",
"checkRuns": {
"nodes": [
{
"title": null,
"__typename": "CheckRun"
}
],
"__typename": "CheckRunConnection"
},
"createdAt": "2026-09-01T18:13:42Z",
"workflowRun": {
"databaseId": 33542389231,
"file": {
"path": ".github/workflows/CI.yml",
"__typename": "WorkflowRunFile"
},
"__typename": "WorkflowRun"
},
"__typename": "CheckSuite"
}
],
"__typename": "CheckSuiteConnection"
},
"status": null,
"authoredDate": "2026-09-01T17:35:31Z",
"committedDate": "2026-09-01T18:05:38Z",
"pushedDate": null,
"oid": "4a708f0ad529dfbe67caec58197135d27b223f53",
"__typename": "Commit"
},
"__typename": "PullRequestCommit"
}
],
"__typename": "PullRequestCommitConnection"
},
"comments": {
"totalCount": 3,
"nodes": [
{
"id": "IC_kwDOAFz6BM8AAAABR7oZYA",
"author": {
"login": "typescript-automation",
"__typename": "Bot"
},
"authorAssociation": "CONTRIBUTOR",
"databaseId": 5498345824,
"body": "@dgp1130 Thank you for submitting this PR!\n\n***This is a live comment that I will keep updated.***\n\n## 1 package in this PR\n\n* `chrome` — [on npm](https://www.npmjs.com/package/chrome), [on unpkg](https://unpkg.com/browse/chrome@latest/)\n - 4 added owners: @couven92, @rreverser, @tregagnon, @pokutuna\n - 7 removed owners: @JasonXian, @usertim, @idan315, @nicolas377, @idosal, @fregante, @erwanjugand\n\n## Code Reviews\n\nBecause this is a widely-used package, a DT maintainer will need to review it before it can be merged.\n\nYou can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=75475&install-plugin=playground-dt-review).\n\n## Status\n\n * ✅ No merge conflicts\n * ✅ Continuous integration tests have passed\n * 🕐 Most recent commit is approved by a DT maintainer\n\nOnce every item on this list is checked, I'll ask you for permission to merge and publish the changes.\n\n----------------------\n... diagnostics scrubbed ...\n<!--typescript_bot_welcome-->",
"createdAt": "2026-09-01T18:14:14Z",
"reactions": {
"nodes": [],
"__typename": "ReactionConnection"
},
"__typename": "IssueComment"
},
{
"id": "IC_kwDOAFz6BM8AAAABR7obgQ",
"author": {
"login": "typescript-automation",
"__typename": "Bot"
},
"authorAssociation": "CONTRIBUTOR",
"databaseId": 5498346369,
"body": "🔔 @matthewkimber @otiai10 @sreimer15 @MatCarlson @ekinsol @echoabstract @spasma @bdbai @JasonXian @usertim @idan315 @nicolas377 @idosal @fregante @erwanjugand — please [review this PR](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/75475/files) in the next few days. Be sure to explicitly select **`Approve`** or **`Request Changes`** in the GitHub UI so I know what's going on.\n<!--typescript_bot_pinging-reviewers-->",
"createdAt": "2026-09-01T18:14:17Z",
"reactions": {
"nodes": [],
"__typename": "ReactionConnection"
},
"__typename": "IssueComment"
},
{
"id": "IC_kwDOAFz6BM8AAAABR7sgwQ",
"author": {
"login": "DangerBotOSS",
"__typename": "User"
},
"authorAssociation": "NONE",
"databaseId": 5498413249,
"body": "\n<!--\n 0 failure: \n 0 warning: \n \n 1 markdown notices\n DangerID: danger-id-Danger;\n-->\n\n\n\n## Formatting\n\nThe following files are not formatted:\n1. types/chrome/test/index.ts\n\nConsider running `pnpm dprint fmt` on these files to make review easier.\n<p align=\"right\">\n Generated by :no_entry_sign: <a href=\"https://danger.systems/js\">dangerJS</a> against 4a708f0ad529dfbe67caec58197135d27b223f53\n</p>\n",
"createdAt": "2026-09-01T18:20:01Z",
"reactions": {
"nodes": [],
"__typename": "ReactionConnection"
},
"__typename": "IssueComment"
}
],
"__typename": "IssueCommentConnection"
},
"files": {
"totalCount": 2,
"nodes": [
{
"path": "types/chrome/index.d.ts",
"additions": 2,
"deletions": 0,
"__typename": "PullRequestChangedFile"
},
{
"path": "types/chrome/test/index.ts",
"additions": 6,
"deletions": 0,
"__typename": "PullRequestChangedFile"
}
],
"pageInfo": {
"hasNextPage": false,
"endCursor": "Mg",
"__typename": "PageInfo"
},
"__typename": "PullRequestChangedFileConnection"
},
"projectItems": {
"nodes": [
{
"id": "PVTI_lADOADeBNM4AkH1qzg48-iw",
"project": {
"id": "PVT_kwDOADeBNM4AkH1q",
"number": 1,
"__typename": "ProjectV2"
},
"fieldValueByName": {
"name": "Needs Maintainer Review",
"field": {
"id": "PVTSSF_lADOADeBNM4AkH1qzgcYOEM",
"__typename": "ProjectV2SingleSelectField"
},
"__typename": "ProjectV2ItemFieldSingleSelectValue"
},
"updatedAt": "2026-09-01T18:20:43Z",
"__typename": "ProjectV2Item"
}
],
"__typename": "ProjectV2ItemConnection"
},
"__typename": "PullRequest"
},
"__typename": "Repository"
}
}
}
56 changes: 56 additions & 0 deletions packages/mergebot/src/_tests/fixtures/75475/derived.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"type": "info",
"now": "2026-09-01T18:46:48.035Z",
"pr_number": 75475,
"author": "dgp1130",
"headCommitOid": "4a708f0ad529dfbe67caec58197135d27b223f53",
"mergeBaseOid": "eded8b3161a48a130df54daefb1005b3807314b0",
"lastPushDate": "2026-09-01T18:13:36.000Z",
"lastActivityDate": "2026-09-01T18:20:01.000Z",
"hasMergeConflict": false,
"isFirstContribution": false,
"tooManyFiles": false,
"hugeChange": false,
"tooManyCommits": false,
"tooManyReviews": false,
"popularityLevel": "Critical",
"pkgInfo": [
{
"name": "chrome",
"kind": "edit",
"files": [
{
"path": "types/chrome/index.d.ts",
"kind": "definition"
},
{
"path": "types/chrome/test/index.ts",
"kind": "test"
}
],
"owners": [
"matthewkimber",
"otiai10",
"sreimer15",
"MatCarlson",
"ekinsol",
"echoabstract",
"spasma",
"bdbai",
"JasonXian",
"usertim",
"idan315",
"nicolas377",
"idosal",
"fregante",
"erwanjugand"
],
"addedOwners": [],
"deletedOwners": [],
"popularityLevel": "Critical"
}
],
"reviews": [],
"mainBotCommentID": 5498345824,
"ciResult": "pass"
}
Loading
Loading