diff --git a/.github/workflows/watchdog-publisher.yml b/.github/workflows/watchdog-publisher.yml deleted file mode 100644 index 58854e7b4cb4a7..00000000000000 --- a/.github/workflows/watchdog-publisher.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Publisher watchdog - -on: - schedule: - # Hourly - - cron: '15 0/2 * * *' - workflow_dispatch: - -jobs: - watchdog: - if: github.repository == 'DefinitelyTyped/DefinitelyTyped' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: ./.github/actions/setup-for-scripts - - - run: node ./scripts/watchdog-publisher.js - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Notify dedicated teams channel - if: ${{ failure() }} - uses: jdcargile/ms-teams-notification@28e5ca976c053d54e2b852f3f38da312f35a24fc # v1.4 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - ms-teams-webhook-uri: ${{ secrets.MS_TEAMS_WATCHDOG_WEBHOOK_URI }} - notification-summary: Publisher watchdog failed - notification-color: dc3545 - timezone: America/Los_Angeles - verbose-logging: true diff --git a/.github/workflows/watchdog-typescript-bot.yml b/.github/workflows/watchdog-typescript-bot.yml deleted file mode 100644 index c1f6d069c24133..00000000000000 --- a/.github/workflows/watchdog-typescript-bot.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: typescript-bot watchdog - -on: - schedule: - # Hourly - - cron: '15 1/2 * * *' - workflow_dispatch: - -jobs: - watchdog: - if: github.repository == 'DefinitelyTyped/DefinitelyTyped' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: ./.github/actions/setup-for-scripts - - - run: node ./scripts/watchdog-typescript-bot.js - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 18641b7e7f4389..b5acde147ea6d5 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,7 @@ It may be helpful for contributors experiencing any issues with their PRs and pa - Most recent build [type-checked/linted](https://github.com/microsoft/DefinitelyTyped-tools/tree/master/packages/dtslint) cleanly: [![Build status](https://github.com/DefinitelyTyped/DefinitelyTyped/actions/workflows/CI.yml/badge.svg?branch=master&event=push)](https://github.com/DefinitelyTyped/DefinitelyTyped/actions/workflows/CI.yml?query=branch%3Amaster+event%3Apush) - All packages are type-checking/linting cleanly: [![Build status](https://github.com/DefinitelyTyped/DefinitelyTyped/actions/workflows/CI.yml/badge.svg?branch=master&event=schedule)](https://github.com/DefinitelyTyped/DefinitelyTyped/actions/workflows/CI.yml?query=branch%3Amaster+event%3Aschedule) -- All packages are being [published to npm](https://github.com/microsoft/DefinitelyTyped-tools/tree/master/packages/publisher) in under an hour and a half: [![Publish Status](https://github.com/DefinitelyTyped/DefinitelyTyped/actions/workflows/watchdog-publisher.yml/badge.svg)](https://github.com/DefinitelyTyped/DefinitelyTyped/actions/workflows/watchdog-publisher.yml) -- [typescript-bot](https://github.com/typescript-bot) has been active on Definitely Typed: [![Activity Status](https://github.com/DefinitelyTyped/DefinitelyTyped/actions/workflows/watchdog-typescript-bot.yml/badge.svg)](https://github.com/DefinitelyTyped/DefinitelyTyped/actions/workflows/watchdog-typescript-bot.yml) +- All packages are being [published to npm](https://github.com/microsoft/DefinitelyTyped-tools/tree/master/packages/publisher): [![Publish Status](https://github.com/microsoft/DefinitelyTyped-tools/actions/workflows/publish-packages.yml/badge.svg?event=schedule)](https://github.com/microsoft/DefinitelyTyped-tools/actions/workflows/publish-packages.yml) - Current [infrastructure status updates](https://github.com/DefinitelyTyped/DefinitelyTyped/issues/44317) If anything here seems wrong or any of the above are failing, please let us know in [the Definitely Typed channel on the TypeScript Community Discord server](https://discord.gg/typescript). diff --git a/scripts/package.json b/scripts/package.json index 992ef784be6585..f8c87f4a706e88 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -9,12 +9,8 @@ "@types/d3-time": "^3.0.0", "@types/d3-time-format": "^4.0.0", "@types/jsdom": "^21.1.0", - "@types/json-stable-stringify": "^1.0.0", "@types/node": "*", - "@types/shelljs": "^0.8.0", "@types/w3c-xmlserializer": "^2.0.0", - "@types/yargs": "^17.0.0", - "comment-json": "^4.2.3", "d3-array": "^3.0.2", "d3-axis": "^3.0.0", "d3-scale": "^4.0.0", @@ -22,11 +18,7 @@ "d3-time": "^3.0.0", "d3-time-format": "^4.0.0", "jsdom": "^17.0.0", - "json-stable-stringify": "^1.0.2", "octokit": "^4.0.2", - "shelljs": "^0.8.5", - "typescript": "next", - "w3c-xmlserializer": "^2.0.0", - "yargs": "^17.1.1" + "w3c-xmlserializer": "^2.0.0" } } diff --git a/scripts/watchdog-publisher.js b/scripts/watchdog-publisher.js deleted file mode 100644 index 3c2e1f17195c03..00000000000000 --- a/scripts/watchdog-publisher.js +++ /dev/null @@ -1,185 +0,0 @@ -import { Octokit } from "octokit"; -import sh from "shelljs"; - -var gh = new Octokit({ - auth: process.env.GITHUB_TOKEN, -}); - -// This script calls out to npm; ensure corepack doesn't complain if present. -process.env.COREPACK_ENABLE_STRICT = "0"; - -async function main() { - const prs = await recentPrs(); - const longestLatency = recentPackages(prs); - if (longestLatency > 5400) { - console.log("types-publisher's longest unpublished latency was over 1.5 hour."); - throw new Error(); - } -} - -/** - * 1. Only match paths that begin with types/ - * 2. Only match paths that end with index.d.ts; test changes don't cause a republish - * 3. Capture the package name - */ -const packageNameFromIndexDts = /^types\/([^\/]+?)\/index.d.ts$/; - -/** - * @param {"created" | "updated"} sort - */ -async function getTopFiveMerged(sort) { - const iterator = gh.paginate.iterator(gh.rest.pulls.list, { - owner: "DefinitelyTyped", - repo: "DefinitelyTyped", - state: "closed", - per_page: 100, - direction: "desc", - sort, - }); - - const result = []; - - for await (const { data: pulls } of iterator) { - for (const pull of pulls) { - if (result.length === 5) { - return result; - } - - if (!pull.merged_at) { - continue; - } - - result.push(pull); - } - } - - return result; -} - -/** @returns {Promise>} */ -async function recentPrs() { - console.log("search for 5 most recently created PRs"); - const searchByCreatedDate = await getTopFiveMerged("created"); - console.log("search for 5 most recently updated PRs"); - const searchByUpdateDate = await getTopFiveMerged("updated"); - - /** @type {Map} */ - const prs = new Map(); - for (const it of searchByCreatedDate) { - await addPr(it, prs); - } - for (const it of searchByUpdateDate) { - await addPr(it, prs); - } - return prs; -} -/** - * @param {{ number: number }} item - * @param {Map} prs - */ -async function addPr(item, prs) { - console.log("get merge_at date for PR", item.number); - const mergedAt = (await gh.rest.pulls.get({ - owner: "DefinitelyTyped", - repo: "DefinitelyTyped", - pull_number: item.number, - })).data.merged_at; - if (mergedAt == null) { - return; - } - const mergeDate = new Date(mergedAt); - console.log("list first 100 files for PR", item.number); - const fileEntries = (await gh.rest.pulls.listFiles({ - owner: "DefinitelyTyped", - repo: "DefinitelyTyped", - pull_number: item.number, - per_page: 100, - })).data; - /** @type {Set} */ - const packages = new Set(); - /** @type {Set} */ - const deleteds = new Set(); - const editsNotNeededPackages = !!fileEntries.find(e => e.filename.match("notNeededPackages.json")); - for (const fileChange of fileEntries) { - const packageName = fileChange.filename.match(packageNameFromIndexDts); - if (packageName == null) { - continue; - } - if (fileChange.status === "removed") { - if (editsNotNeededPackages) { - deleteds.add(packageName[1]); - packages.add(packageName[1]); - } - } else { - packages.add(packageName[1]); - } - } - for (const name of packages) { - const prev = prs.get(name); - if (!prev || mergeDate > prev.mergeDate) { - prs.set(name, { mergeDate, pr: item.number, deleted: deleteds.has(name) }); - } - } -} -/** - * @param {Date} m1 - * @param {Date} m2 - */ -function monthSpan(m1, m2) { - var diff = m1.getMonth() - m2.getMonth(); - return diff < 0 ? diff + 12 : diff; -} -/** @param {Map} prs */ -function recentPackages(prs) { - console.log(); - console.log(); - console.log("## Interesting PRs ##"); - let longest = 0; - let longestName = "No unpublished PRs found"; - for (const [name, { mergeDate, pr, deleted }] of prs) { - const { deprecated, publishDate } = parseNpmInfo( - sh.exec(`npm info @types/${name} time.modified deprecated`, { silent: true }).stdout.toString(), - ); - if (monthSpan(publishDate, mergeDate) > 1) { - console.log(`${name}: published long before merge; probably a rogue edit to #${pr}`); - console.log(" merged:" + mergeDate); - console.log(" published:" + publishDate); - } else if (mergeDate > publishDate || isNaN(publishDate.getTime()) || deprecated !== deleted) { - console.log( - `${name}: #${pr} not published yet; latency so far: ${(Date.now() - mergeDate.valueOf()) / 1000}`, - ); - console.log(" merged:" + mergeDate); - console.log(" published:" + publishDate); - const latency = Date.now() - mergeDate.valueOf(); - if (latency > longest) { - longest = latency; - longestName = name; - } - } else if (publishDate.valueOf() - mergeDate.valueOf() > 100000000) { - console.log(`${name}: #${pr} very long latency: ${(publishDate.valueOf() - mergeDate.valueOf()) / 1000}`); - console.log(" merged:" + mergeDate); - console.log(" published:" + publishDate); - } - } - console.log(); - console.log(); - console.log("## Longest publish latency ##"); - console.log(longestName + ": " + (longest / 1000)); - return longest / 1000; -} -/** @param {string} info */ -function parseNpmInfo(info) { - if (info.includes("deprecated")) { - const firstLine = info.split("\n")[0]; - return { - publishDate: new Date(firstLine.slice(firstLine.indexOf("'") + 1, firstLine.length - 1)), - deprecated: true, - }; - } else { - return { publishDate: new Date(info.trim()), deprecated: false }; - } -} -main().catch(error => { - console.error(error && (error.stack || error.message || error)); - process.exit(1); -}); diff --git a/scripts/watchdog-typescript-bot.js b/scripts/watchdog-typescript-bot.js deleted file mode 100644 index 0187c0559cf45b..00000000000000 --- a/scripts/watchdog-typescript-bot.js +++ /dev/null @@ -1,54 +0,0 @@ -import { Octokit } from "octokit"; -var gh = new Octokit({ - auth: process.env.GITHUB_TOKEN, -}); - -async function main() { - const activity = await recentActivity(); - - if (!activity) { - console.log("Couldn't find any recent activity for typescript-bot"); - throw new Error(); - } - const [anyRecent, botRecent] = activity; - // 1. anyRecent - botRecent < 2 hours || present - botRecent < 2 hour - console.log(); - console.log(); - console.log("Time since typescript-bot's last activity: " + (new Date().valueOf() - botRecent.valueOf()) / 1000); - console.log( - "Time between most recent activity and typescript-bot's most recent activity: " - + (anyRecent.valueOf() - botRecent.valueOf()) / 1000, - ); - if ( - (new Date().valueOf() - botRecent.valueOf()) > 7200000 && (anyRecent.valueOf() - botRecent.valueOf()) > 7200000 - ) { - console.log("typescript-bot hasn't responded or been active in over 2 hours (7200 seconds)"); - throw new Error(); - } -} - -/** @returns {Promise<[Date, Date] | undefined>} */ -async function recentActivity() { - const dtEvents = await gh.rest.activity.listRepoEvents({ owner: "DefinitelyTyped", repo: "DefinitelyTyped" }); - let latestEvent; - for (const event of dtEvents.data) { - if (!event.created_at) continue; - latestEvent = new Date(event.created_at); - break; - } - if (!latestEvent) { - throw new Error("couldn't get events for DefinitelyTyped repo"); - } - - const events = await gh.rest.activity.listPublicEventsForUser({ username: "typescript-bot" }); - for (const event of events.data) { - if (!event.created_at) continue; - if (event.repo.name === "DefinitelyTyped/DefinitelyTyped") { - return [latestEvent, new Date(event.created_at)]; - } - } -} -main().catch(e => { - console.log(e); - process.exit(1); -});