mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-10 16:58:55 -05:00
chore: make pr-pinger a workspace extension (#312757)
* chore: make pr-pinger a workspace extension * Update .vscode/extensions/vscode-pr-pinger/src/extension.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
1
.vscode/extensions.json
vendored
1
.vscode/extensions.json
vendored
@@ -7,7 +7,6 @@
|
||||
"github.vscode-pull-request-github",
|
||||
"ms-vscode.vscode-github-issue-notebooks",
|
||||
"ms-vscode.extension-test-runner",
|
||||
"jrieken.vscode-pr-pinger",
|
||||
"typescriptteam.native-preview",
|
||||
"ms-vscode.ts-customized-language-service"
|
||||
]
|
||||
|
||||
5
.vscode/extensions/vscode-pr-pinger/.vscodeignore
vendored
Normal file
5
.vscode/extensions/vscode-pr-pinger/.vscodeignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.gitignore
|
||||
.vscode/**
|
||||
.vscode-test/**
|
||||
src/**
|
||||
**/tsconfig.json
|
||||
269
.vscode/extensions/vscode-pr-pinger/package-lock.json
generated
vendored
Normal file
269
.vscode/extensions/vscode-pr-pinger/package-lock.json
generated
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
{
|
||||
"name": "vscode-pr-pinger",
|
||||
"version": "0.0.6",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "vscode-pr-pinger",
|
||||
"version": "0.0.6",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/graphql": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.67.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.2.tgz",
|
||||
"integrity": "sha512-8/AUACfE9vpRpehE6ZLfEtzkibe5nfsSwFZVMsG8qabqRt1M81qZYUFRZa1B8w8lP6cdfDJfRq9HWS+MbmR7tw==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^7.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.1.tgz",
|
||||
"integrity": "sha512-sxmnewSwAixkP1TrLdE6yRG53eEhHhDTYUykUwdV9x8f91WcbhunIHk9x1PZLALdBZKRPUO2HRcm4kezZ79HoA==",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^6.0.0",
|
||||
"@octokit/types": "^7.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "13.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-13.10.0.tgz",
|
||||
"integrity": "sha512-wPQDpTyy35D6VS/lekXDaKcxy6LI2hzcbmXBnP180Pdgz3dXRzoHdav0w09yZzzWX8HHLGuqwAeyMqEPtWY2XA=="
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.1.tgz",
|
||||
"integrity": "sha512-gYKRCia3cpajRzDSU+3pt1q2OcuC6PK8PmFIyxZDWCzRXRSIBH8jXjFJ8ZceoygBIm0KsEUg4x1+XcYBz7dHPQ==",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^7.0.0",
|
||||
"@octokit/request-error": "^3.0.0",
|
||||
"@octokit/types": "^7.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.1.tgz",
|
||||
"integrity": "sha512-ym4Bp0HTP7F3VFssV88WD1ZyCIRoE8H35pXSKwLeMizcdZAYc/t6N9X9Yr9n6t3aG9IH75XDnZ6UeZph0vHMWQ==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^7.0.0",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "7.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-7.4.0.tgz",
|
||||
"integrity": "sha512-ln1GW0p72+P8qeRjHGj0wyR5ePy6slqvczveOqonMk1w1UWua6UgrkwFzv6S0vKWjSqt/ijYXF1ehNVRRRSvLA==",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^13.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.2.tgz",
|
||||
"integrity": "sha512-8/AUACfE9vpRpehE6ZLfEtzkibe5nfsSwFZVMsG8qabqRt1M81qZYUFRZa1B8w8lP6cdfDJfRq9HWS+MbmR7tw==",
|
||||
"requires": {
|
||||
"@octokit/types": "^7.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/graphql": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.1.tgz",
|
||||
"integrity": "sha512-sxmnewSwAixkP1TrLdE6yRG53eEhHhDTYUykUwdV9x8f91WcbhunIHk9x1PZLALdBZKRPUO2HRcm4kezZ79HoA==",
|
||||
"requires": {
|
||||
"@octokit/request": "^6.0.0",
|
||||
"@octokit/types": "^7.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/openapi-types": {
|
||||
"version": "13.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-13.10.0.tgz",
|
||||
"integrity": "sha512-wPQDpTyy35D6VS/lekXDaKcxy6LI2hzcbmXBnP180Pdgz3dXRzoHdav0w09yZzzWX8HHLGuqwAeyMqEPtWY2XA=="
|
||||
},
|
||||
"@octokit/request": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.1.tgz",
|
||||
"integrity": "sha512-gYKRCia3cpajRzDSU+3pt1q2OcuC6PK8PmFIyxZDWCzRXRSIBH8jXjFJ8ZceoygBIm0KsEUg4x1+XcYBz7dHPQ==",
|
||||
"requires": {
|
||||
"@octokit/endpoint": "^7.0.0",
|
||||
"@octokit/request-error": "^3.0.0",
|
||||
"@octokit/types": "^7.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/request-error": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.1.tgz",
|
||||
"integrity": "sha512-ym4Bp0HTP7F3VFssV88WD1ZyCIRoE8H35pXSKwLeMizcdZAYc/t6N9X9Yr9n6t3aG9IH75XDnZ6UeZph0vHMWQ==",
|
||||
"requires": {
|
||||
"@octokit/types": "^7.0.0",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "7.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-7.4.0.tgz",
|
||||
"integrity": "sha512-ln1GW0p72+P8qeRjHGj0wyR5ePy6slqvczveOqonMk1w1UWua6UgrkwFzv6S0vKWjSqt/ijYXF1ehNVRRRSvLA==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^13.10.0"
|
||||
}
|
||||
},
|
||||
"deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"requires": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"requires": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
42
.vscode/extensions/vscode-pr-pinger/package.json
vendored
Normal file
42
.vscode/extensions/vscode-pr-pinger/package.json
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "vscode-pr-pinger",
|
||||
"displayName": "VSCode PR Pinger",
|
||||
"description": "PR Pinger shows a PR in the statusbar for you to review (VS Code Team Only)",
|
||||
"engines": {
|
||||
"vscode": "^1.67.0"
|
||||
},
|
||||
"version": "0.0.6",
|
||||
"publisher": "ms-vscode",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/microsoft/vscode.git"
|
||||
},
|
||||
"main": "out/extension.js",
|
||||
"activationEvents": [
|
||||
"onStartupFinished"
|
||||
],
|
||||
"contributes": {
|
||||
"configuration": {
|
||||
"title": "PR Pinger",
|
||||
"properties": {
|
||||
"prpinger.presentation": {
|
||||
"type": "string",
|
||||
"default": "short",
|
||||
"enum": [
|
||||
"number",
|
||||
"short"
|
||||
],
|
||||
"description": "How PR are shown in the status bar - either as number or without vowels"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"watch": "gulp watch-extension:vscode-pr-pinger",
|
||||
"compile": "gulp compile-extension:vscode-pr-pinger"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/graphql": "^5.0.1"
|
||||
}
|
||||
}
|
||||
241
.vscode/extensions/vscode-pr-pinger/src/extension.ts
vendored
Normal file
241
.vscode/extensions/vscode-pr-pinger/src/extension.ts
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { graphql } from '@octokit/graphql';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
const item = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1);
|
||||
context.subscriptions.push(item);
|
||||
|
||||
let session: vscode.AuthenticationSession | undefined;
|
||||
|
||||
context.subscriptions.push(vscode.commands.registerCommand('pr.promptLogin', async () => {
|
||||
session = await vscode.authentication.getSession('github', ['repo'], { createIfNone: true });
|
||||
updateItem();
|
||||
}));
|
||||
|
||||
context.subscriptions.push(vscode.commands.registerCommand('pr.show', async (pr: PrInfo) => {
|
||||
vscode.env.openExternal(vscode.Uri.parse(pr.url));
|
||||
item.hide();
|
||||
}));
|
||||
|
||||
let currentShow: vscode.Disposable | undefined = undefined;
|
||||
context.subscriptions.push(new vscode.Disposable(() => currentShow?.dispose()));
|
||||
|
||||
// monitor focus/unfocus to "nudge harder" after a context switch
|
||||
let lastGone: number | undefined;
|
||||
context.subscriptions.push(vscode.window.onDidChangeWindowState(e => {
|
||||
if (!e.focused) {
|
||||
// gone
|
||||
lastGone = Date.now();
|
||||
return;
|
||||
}
|
||||
|
||||
if (lastGone && Date.now() - lastGone > 1000 * 60 * 5) {
|
||||
// back after 5 minutes
|
||||
updateItem(true);
|
||||
}
|
||||
}));
|
||||
|
||||
async function updateItem(afterAway?: boolean) {
|
||||
const currentSession = session;
|
||||
|
||||
if (!currentSession) {
|
||||
item.text = 'Not Logged In';
|
||||
item.command = 'pr.promptLogin';
|
||||
item.show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentShow) {
|
||||
// already showing a PR
|
||||
return;
|
||||
}
|
||||
|
||||
const tooLongAgo = Date.now() - 1000 * 60 * 60 * 24 * 4;
|
||||
const data: Query = await graphql(query, { headers: { authorization: `Bearer ${currentSession.accessToken}` } });
|
||||
|
||||
const prs = data.repository.pullRequests.edges.map(edge => edge.node)
|
||||
.filter(needsTeamReview) // from team
|
||||
.filter(pr => pr.author.login !== currentSession.account.label) // not YOU
|
||||
.map(pr => ({ pr, date: new Date(pr.createdAt) }))
|
||||
.filter(({ date }) => date.getTime() > tooLongAgo) // not dated
|
||||
.sort((a, b) => b.date.getTime() - a.date.getTime()); // sorted
|
||||
|
||||
if (prs.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Unless forced you only need to review with a certain chance
|
||||
if (!afterAway) {
|
||||
const chance = Math.ceil(prs.length / 7);
|
||||
if (Math.random() > chance) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// pick a random PR so that not everyone gets the same one
|
||||
const n = Math.floor(Math.random() * prs.length);
|
||||
const pr = prs[n].pr;
|
||||
|
||||
item.text = makeLabel(pr);
|
||||
item.tooltip = new vscode.MarkdownString(`[${pr.title}](${pr.url}) needs your review. Thanks $(heart-filled)`, true);
|
||||
item.command = { command: 'pr.show', title: 'Show PR', arguments: [pr] };
|
||||
item.backgroundColor = afterAway ? new vscode.ThemeColor('statusBarItem.warningBackground') : undefined;
|
||||
item.show();
|
||||
|
||||
// refresh every 20 seconds
|
||||
const checkHandle = setInterval(async function () {
|
||||
const data: Check = await graphql(check, {
|
||||
pr: pr.number,
|
||||
headers: { authorization: `Bearer ${currentSession.accessToken}` },
|
||||
});
|
||||
if (!needsTeamReview(data.repository.pullRequest)) {
|
||||
currentShow?.dispose();
|
||||
}
|
||||
}, 1000 * 20);
|
||||
currentShow = new vscode.Disposable(() => {
|
||||
clearInterval(checkHandle);
|
||||
currentShow = undefined;
|
||||
item.hide();
|
||||
});
|
||||
}
|
||||
|
||||
vscode.authentication.getSession('github', ['repo']).then(_session => {
|
||||
session = _session;
|
||||
updateItem();
|
||||
});
|
||||
|
||||
const handle = setInterval(updateItem, 1000 * 60 * 10); // update every 10 minutes
|
||||
context.subscriptions.push(new vscode.Disposable(() => clearInterval(handle)));
|
||||
}
|
||||
|
||||
function makeLabel(pr: PrInfo): string {
|
||||
const style = vscode.workspace.getConfiguration('prpinger').get<'short' | 'number'>('presentation');
|
||||
if (style === 'number') {
|
||||
return `$(git-pull-request) #${pr.number}`;
|
||||
}
|
||||
|
||||
const ignore = new Set(['`', '.', ':']);
|
||||
const vowels = new Set(['a', 'e', 'i', 'o', 'u']);
|
||||
const newTitle: string[] = [];
|
||||
for (const ch of pr.title) {
|
||||
if (ignore.has(ch)) {
|
||||
break;
|
||||
}
|
||||
if (newTitle.length > 8 && !/\w/.test(ch)) {
|
||||
break;
|
||||
}
|
||||
if (newTitle.length > 15) {
|
||||
break;
|
||||
}
|
||||
if (!vowels.has(ch)) {
|
||||
newTitle.push(ch);
|
||||
}
|
||||
}
|
||||
|
||||
return `$(git-pull-request) ${newTitle.join('')}`;
|
||||
}
|
||||
|
||||
function needsTeamReview(pr: PrInfo): boolean {
|
||||
return pr.authorAssociation === 'MEMBER'
|
||||
&& !pr.isDraft
|
||||
&& pr.reviewRequests.totalCount === 0
|
||||
&& pr.reviews.totalCount === 0
|
||||
&& pr.assignees.nodes.length === 1 && pr.assignees.nodes[0].login === pr.author.login; // our PR bot assigns the poster as owner -> we use that as filter
|
||||
}
|
||||
|
||||
type PrInfo = {
|
||||
number: number;
|
||||
author: { login: string };
|
||||
authorAssociation: 'MEMBER' | string;
|
||||
assignees: { nodes: { login: string }[] };
|
||||
createdAt: string;
|
||||
isDraft: string;
|
||||
reviewRequests: { totalCount: number };
|
||||
reviews: { totalCount: number };
|
||||
title: string;
|
||||
url: string;
|
||||
};
|
||||
|
||||
|
||||
// ---- query
|
||||
|
||||
type Query = {
|
||||
repository: {
|
||||
pullRequests: {
|
||||
edges: { node: PrInfo }[];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
const query = `{
|
||||
repository(owner: "microsoft", name: "vscode") {
|
||||
pullRequests(
|
||||
first: 30
|
||||
states: OPEN
|
||||
orderBy: {field: CREATED_AT, direction: DESC}
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
number
|
||||
url
|
||||
createdAt
|
||||
authorAssociation
|
||||
author {
|
||||
login
|
||||
}
|
||||
assignees(first:5) {
|
||||
nodes {
|
||||
login
|
||||
}
|
||||
}
|
||||
isDraft
|
||||
reviewRequests(last: 1) {
|
||||
totalCount
|
||||
}
|
||||
reviews(last:1) {
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
// --- check
|
||||
|
||||
type Check = {
|
||||
repository: {
|
||||
pullRequest: PrInfo;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
const check = `query validate($pr: Int!) {
|
||||
repository(owner: "microsoft", name: "vscode") {
|
||||
pullRequest(number: $pr) {
|
||||
authorAssociation
|
||||
author {
|
||||
login
|
||||
}
|
||||
assignees(first:5) {
|
||||
nodes {
|
||||
login
|
||||
}
|
||||
}
|
||||
isDraft
|
||||
reviewRequests(last: 1) {
|
||||
totalCount
|
||||
}
|
||||
reviews(last: 1) {
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
14
.vscode/extensions/vscode-pr-pinger/tsconfig.json
vendored
Normal file
14
.vscode/extensions/vscode-pr-pinger/tsconfig.json
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "../../../extensions/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./out",
|
||||
"types": [
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"../../../src/vscode-dts/vscode.d.ts"
|
||||
]
|
||||
}
|
||||
@@ -97,6 +97,7 @@ const compilations = [
|
||||
'.vscode/extensions/vscode-selfhost-test-provider/tsconfig.json',
|
||||
'.vscode/extensions/vscode-selfhost-import-aid/tsconfig.json',
|
||||
'.vscode/extensions/vscode-extras/tsconfig.json',
|
||||
'.vscode/extensions/vscode-pr-pinger/tsconfig.json',
|
||||
];
|
||||
|
||||
const getBaseUrl = (out: string) => `https://main.vscode-cdn.net/sourcemaps/${commit}/${out}`;
|
||||
|
||||
@@ -63,6 +63,7 @@ export const dirs = [
|
||||
'.vscode/extensions/vscode-selfhost-import-aid',
|
||||
'.vscode/extensions/vscode-selfhost-test-provider',
|
||||
'.vscode/extensions/vscode-extras',
|
||||
'.vscode/extensions/vscode-pr-pinger',
|
||||
];
|
||||
|
||||
if (existsSync(`${import.meta.dirname}/../../.build/distro/npm`)) {
|
||||
|
||||
Reference in New Issue
Block a user