diff --git a/packages/mergebot/src/_tests/fixtures/69997/derived.json b/packages/mergebot/src/_tests/fixtures/69997/derived.json index 4b157c5e92..02d33915da 100644 --- a/packages/mergebot/src/_tests/fixtures/69997/derived.json +++ b/packages/mergebot/src/_tests/fixtures/69997/derived.json @@ -5,7 +5,7 @@ "author": "ckohen", "headCommitOid": "75598a6c7b65424bccbae67e2f99b0967b1d3696", "mergeBaseOid": "85343a692d8add5c4c280280a80bcbd65f418906", - "lastPushDate": "2024-07-08T01:23:57.000Z", + "lastPushDate": "2024-10-11T02:18:44.000Z", "lastActivityDate": "2024-10-11T02:18:44.000Z", "hasMergeConflict": true, "isFirstContribution": true, diff --git a/packages/mergebot/src/_tests/fixtures/75112-force-push/_downloads.json b/packages/mergebot/src/_tests/fixtures/75112-force-push/_downloads.json new file mode 100644 index 0000000000..f9edea1374 --- /dev/null +++ b/packages/mergebot/src/_tests/fixtures/75112-force-push/_downloads.json @@ -0,0 +1,3 @@ +{ + "npmcli__config": 32095 +} diff --git a/packages/mergebot/src/_tests/fixtures/75112-force-push/_files.json b/packages/mergebot/src/_tests/fixtures/75112-force-push/_files.json new file mode 100644 index 0000000000..1b077fb460 --- /dev/null +++ b/packages/mergebot/src/_tests/fixtures/75112-force-push/_files.json @@ -0,0 +1,4 @@ +{ + "1096f8189e52f26bbb77c1325cf9c2867d54fbc5:types/npmcli__config/package.json": "{\n \"private\": true,\n \"name\": \"@types/npmcli__config\",\n \"version\": \"6.0.9999\",\n \"projects\": [\n \"https://github.com/npm/config#readme\"\n ],\n \"dependencies\": {\n \"@types/node\": \"*\",\n \"@types/semver\": \"*\"\n },\n \"devDependencies\": {\n \"@types/npmcli__config\": \"workspace:.\"\n },\n \"owners\": [\n {\n \"name\": \"Emily M Klassen\",\n \"githubUsername\": \"forivall\"\n }\n ]\n}\n", + "48de9998d2b6ee226235ecd29e4d4e7ea5b57bc4:types/npmcli__config/package.json": "{\n \"private\": true,\n \"name\": \"@types/npmcli__config\",\n \"version\": \"6.0.9999\",\n \"projects\": [\n \"https://github.com/npm/config#readme\"\n ],\n \"dependencies\": {\n \"@types/node\": \"*\",\n \"@types/semver\": \"*\"\n },\n \"devDependencies\": {\n \"@types/npmcli__config\": \"workspace:.\"\n },\n \"owners\": [\n {\n \"name\": \"Emily M Klassen\",\n \"githubUsername\": \"forivall\"\n }\n ]\n}\n" +} diff --git a/packages/mergebot/src/_tests/fixtures/75112-force-push/_response.json b/packages/mergebot/src/_tests/fixtures/75112-force-push/_response.json new file mode 100644 index 0000000000..a61b0299db --- /dev/null +++ b/packages/mergebot/src/_tests/fixtures/75112-force-push/_response.json @@ -0,0 +1,186 @@ +{ + "data": { + "repository": { + "id": "MDEwOlJlcG9zaXRvcnk2MDkzMzE2", + "pullRequest": { + "id": "PR_kwDOAFz6BM7l36mp", + "title": "Add types for @npmcli/config/lib/definitions", + "createdAt": "2026-06-12T18:10:31Z", + "author": { + "login": "MattIPv4", + "__typename": "User" + }, + "authorAssociation": "CONTRIBUTOR", + "baseRef": { + "name": "master", + "__typename": "Ref" + }, + "labels": { + "nodes": [ + { + "name": "Where is GH Actions?", + "__typename": "Label" + } + ], + "__typename": "LabelConnection" + }, + "isDraft": false, + "mergeable": "MERGEABLE", + "number": 75112, + "state": "OPEN", + "headRefOid": "48de9998d2b6ee226235ecd29e4d4e7ea5b57bc4", + "baseRefOid": "1096f8189e52f26bbb77c1325cf9c2867d54fbc5", + "changedFiles": 2, + "additions": 29, + "deletions": 0, + "commitIds": { + "totalCount": 1, + "nodes": [ + { + "commit": { + "oid": "48de9998d2b6ee226235ecd29e4d4e7ea5b57bc4", + "parents": { + "nodes": [ + { + "oid": "1096f8189e52f26bbb77c1325cf9c2867d54fbc5", + "__typename": "Commit" + } + ], + "__typename": "CommitConnection" + }, + "__typename": "Commit" + }, + "__typename": "PullRequestCommit" + } + ], + "__typename": "PullRequestCommitConnection" + }, + "timelineItems": { + "nodes": [ + { + "actor": { + "login": "MattIPv4", + "__typename": "User" + }, + "createdAt": "2026-06-12T18:20:11Z", + "__typename": "HeadRefForcePushedEvent" + } + ], + "__typename": "PullRequestTimelineItemsConnection" + }, + "reviews": { + "totalCount": 0, + "nodes": [], + "__typename": "PullRequestReviewConnection" + }, + "commits": { + "totalCount": 1, + "nodes": [ + { + "commit": { + "checkSuites": { + "nodes": [], + "__typename": "CheckSuiteConnection" + }, + "status": null, + "authoredDate": "2026-06-12T18:06:28Z", + "committedDate": "2026-06-12T18:20:05Z", + "pushedDate": null, + "oid": "48de9998d2b6ee226235ecd29e4d4e7ea5b57bc4", + "__typename": "Commit" + }, + "__typename": "PullRequestCommit" + } + ], + "__typename": "PullRequestCommitConnection" + }, + "comments": { + "totalCount": 2, + "nodes": [ + { + "id": "IC_kwDOAFz6BM8AAAABF8jQRA", + "author": { + "login": "typescript-automation", + "__typename": "Bot" + }, + "authorAssociation": "NONE", + "databaseId": 4694003780, + "body": "@MattIPv4 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* `npmcli__config` \u2014 [on npm](https://www.npmjs.com/package/@npmcli/config), [on unpkg](https://unpkg.com/browse/@npmcli/config@latest/)\n\n## Code Reviews\n\nBecause you edited one package and updated the tests (\ud83d\udc4f), I can help you merge this PR once someone else signs off on it.\n\nYou can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=75112&install-plugin=playground-dt-review).\n\n## Status\n\n * \u2705 No merge conflicts\n * \u2753 Continuous integration tests have gone missing\n * \ud83d\udd50 Most recent commit is approved by type definition owners, DT maintainers or others\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", + "createdAt": "2026-06-12T18:11:06Z", + "reactions": { + "nodes": [], + "__typename": "ReactionConnection" + }, + "__typename": "IssueComment" + }, + { + "id": "IC_kwDOAFz6BM8AAAABF8jQ3g", + "author": { + "login": "typescript-automation", + "__typename": "Bot" + }, + "authorAssociation": "NONE", + "databaseId": 4694003934, + "body": "\ud83d\udd14 @forivall \u2014 please [review this PR](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/75112/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", + "createdAt": "2026-06-12T18:11:08Z", + "reactions": { + "nodes": [], + "__typename": "ReactionConnection" + }, + "__typename": "IssueComment" + } + ], + "__typename": "IssueCommentConnection" + }, + "files": { + "totalCount": 2, + "nodes": [ + { + "path": "types/npmcli__config/lib/definitions/index.d.ts", + "additions": 12, + "deletions": 0, + "__typename": "PullRequestChangedFile" + }, + { + "path": "types/npmcli__config/npmcli__config-tests.ts", + "additions": 17, + "deletions": 0, + "__typename": "PullRequestChangedFile" + } + ], + "pageInfo": { + "hasNextPage": false, + "endCursor": "Mg", + "__typename": "PageInfo" + }, + "__typename": "PullRequestChangedFileConnection" + }, + "projectItems": { + "nodes": [ + { + "id": "PVTI_lADOADeBNM4AkH1qzgvk33k", + "project": { + "id": "PVT_kwDOADeBNM4AkH1q", + "number": 1, + "__typename": "ProjectV2" + }, + "fieldValueByName": { + "name": "Other", + "field": { + "id": "PVTSSF_lADOADeBNM4AkH1qzgcYOEM", + "__typename": "ProjectV2SingleSelectField" + }, + "__typename": "ProjectV2ItemFieldSingleSelectValue" + }, + "updatedAt": "2026-06-12T18:20:49Z", + "__typename": "ProjectV2Item" + } + ], + "__typename": "ProjectV2ItemConnection" + }, + "__typename": "PullRequest" + }, + "__typename": "Repository" + } + } +} diff --git a/packages/mergebot/src/_tests/fixtures/75112-force-push/derived.json b/packages/mergebot/src/_tests/fixtures/75112-force-push/derived.json new file mode 100644 index 0000000000..8eb08aba16 --- /dev/null +++ b/packages/mergebot/src/_tests/fixtures/75112-force-push/derived.json @@ -0,0 +1,42 @@ +{ + "type": "info", + "now": "2026-06-12T18:20:15.000Z", + "pr_number": 75112, + "author": "MattIPv4", + "headCommitOid": "48de9998d2b6ee226235ecd29e4d4e7ea5b57bc4", + "mergeBaseOid": "1096f8189e52f26bbb77c1325cf9c2867d54fbc5", + "lastPushDate": "2026-06-12T18:20:11.000Z", + "lastActivityDate": "2026-06-12T18:20:11.000Z", + "hasMergeConflict": false, + "isFirstContribution": false, + "tooManyFiles": false, + "hugeChange": false, + "tooManyCommits": false, + "tooManyReviews": false, + "popularityLevel": "Well-liked by everyone", + "pkgInfo": [ + { + "name": "npmcli__config", + "kind": "edit", + "files": [ + { + "path": "types/npmcli__config/lib/definitions/index.d.ts", + "kind": "definition" + }, + { + "path": "types/npmcli__config/npmcli__config-tests.ts", + "kind": "test" + } + ], + "owners": [ + "forivall" + ], + "addedOwners": [], + "deletedOwners": [], + "popularityLevel": "Well-liked by everyone" + } + ], + "reviews": [], + "mainBotCommentID": 4694003780, + "ciResult": "missing" +} diff --git a/packages/mergebot/src/_tests/fixtures/75112-force-push/mutations.json b/packages/mergebot/src/_tests/fixtures/75112-force-push/mutations.json new file mode 100644 index 0000000000..2723b7196b --- /dev/null +++ b/packages/mergebot/src/_tests/fixtures/75112-force-push/mutations.json @@ -0,0 +1,22 @@ +[ + { + "mutation": "mutation ($input: UpdateIssueCommentInput!) {\n updateIssueComment(input: $input) {\n __typename\n }\n}", + "variables": { + "input": { + "id": "IC_kwDOAFz6BM8AAAABF8jQRA", + "body": "@MattIPv4 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* `npmcli__config` — [on npm](https://www.npmjs.com/package/@npmcli/config), [on unpkg](https://unpkg.com/browse/@npmcli/config@latest/)\n\n## Code Reviews\n\nBecause you edited one package and updated the tests (👏), I can help you merge this PR once someone else signs off on it.\n\nYou can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=75112&install-plugin=playground-dt-review).\n\n## Status\n\n * ✅ No merge conflicts\n * ❓ Continuous integration tests have gone missing\n * 🕐 Most recent commit is approved by type definition owners, DT maintainers or others\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" + } + } + }, + { + "mutation": "mutation ($input: RemoveLabelsFromLabelableInput!) {\n removeLabelsFromLabelable(input: $input) {\n __typename\n }\n}", + "variables": { + "input": { + "labelIds": [ + "MDU6TGFiZWwyMDk2NzQ1NzQx" + ], + "labelableId": "PR_kwDOAFz6BM7l36mp" + } + } + } +] diff --git a/packages/mergebot/src/_tests/fixtures/75112-force-push/result.json b/packages/mergebot/src/_tests/fixtures/75112-force-push/result.json new file mode 100644 index 0000000000..cf806c912a --- /dev/null +++ b/packages/mergebot/src/_tests/fixtures/75112-force-push/result.json @@ -0,0 +1,16 @@ +{ + "labels": [], + "responseComments": [ + { + "tag": "welcome", + "status": "@MattIPv4 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* `npmcli__config` — [on npm](https://www.npmjs.com/package/@npmcli/config), [on unpkg](https://unpkg.com/browse/@npmcli/config@latest/)\n\n## Code Reviews\n\nBecause you edited one package and updated the tests (👏), I can help you merge this PR once someone else signs off on it.\n\nYou can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=75112&install-plugin=playground-dt-review).\n\n## Status\n\n * ✅ No merge conflicts\n * ❓ Continuous integration tests have gone missing\n * 🕐 Most recent commit is approved by type definition owners, DT maintainers or others\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 ..." + }, + { + "tag": "pinging-reviewers", + "status": "🔔 @forivall — please [review this PR](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/75112/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." + } + ], + "shouldClose": false, + "shouldMerge": false, + "shouldUpdateLabels": true +} diff --git a/packages/mergebot/src/pr-info.ts b/packages/mergebot/src/pr-info.ts index 000368cd30..52bc288e92 100644 --- a/packages/mergebot/src/pr-info.ts +++ b/packages/mergebot/src/pr-info.ts @@ -235,13 +235,16 @@ export async function deriveStateForPR( const isFirstContribution = prInfo.authorAssociation === "FIRST_TIME_CONTRIBUTOR"; const createdDate = new Date(prInfo.createdAt); - // apparently `headCommit.pushedDate` can be null in some cases (see #48708), use the PR creation time for that + const lastForcePushDate = getLastForcePushDate(prInfo.timelineItems); + // `headCommit.pushedDate` is deprecated and now always null, so fall back to the last force-push + // event date (a reliable server timestamp) when present, otherwise the PR creation time. // (it would be bad to use `committedDate`/`authoredDate`, since these can be set to arbitrary values) - const lastPushDate = new Date(headCommit.pushedDate || prInfo.createdAt); + const lastPushDate = headCommit.pushedDate + ? new Date(headCommit.pushedDate) + : (lastForcePushDate ?? new Date(prInfo.createdAt)); const lastCommentDate = getLastCommentishActivityDate(prInfo); const blessing = getLastMaintainerBlessing(lastPushDate, prInfo); const reopenedDate = getReopenedDate(prInfo.timelineItems); - const lastForcePushDate = getLastForcePushDate(prInfo.timelineItems); // we should generally have all files (except for draft PRs) const fileCount = prInfo.changedFiles; // we fetch all files so this shouldn't happen, but GH has a limit of 3k files even with