|
| 1 | +// This script relies on getTypeScriptNPMVersions.js having been ran already |
| 2 | +// it will grab the latest TypeScript issue with info about the iteration plan |
| 3 | +// and turn that into structured data. |
| 4 | + |
| 5 | +// node packages/typescriptlang-org/scripts/getTypeScriptReleasePlan.js |
| 6 | + |
| 7 | +const Octokit = require("@octokit/rest") |
| 8 | +const versionMeta = require("../src/lib/release-info.json") |
| 9 | +const fetch = require("node-fetch") |
| 10 | +const { format } = require("prettier") |
| 11 | +const { writeFileSync } = require("fs") |
| 12 | +const { join } = require("path") |
| 13 | + |
| 14 | +const token = process.env.GITHUB_BOT_TOKEN || process.env.GITHUB_TOKEN |
| 15 | +if (!token) throw new Error("No GitHub Token at process.env.GITHUB_BOT_TOKEN") |
| 16 | + |
| 17 | +const go = async () => { |
| 18 | + const octokit = new Octokit({ |
| 19 | + auth: token, |
| 20 | + userAgent: "TS Website Issue Searcher", |
| 21 | + }) |
| 22 | + |
| 23 | + const issues = await octokit.search.issuesAndPullRequests({ |
| 24 | + q: "iteration plan repo:microsoft/typescript state:open type:issues", |
| 25 | + }) |
| 26 | + |
| 27 | + const upcoming = issues.data.items.find( |
| 28 | + i => |
| 29 | + i.title.toLowerCase().includes(versionMeta.tags.next) && |
| 30 | + i.labels.find(l => l.name === "Planning") |
| 31 | + ) |
| 32 | + |
| 33 | + // Couldn't find the issue, bail, |
| 34 | + if (!upcoming) { |
| 35 | + return sendTeamsFail( |
| 36 | + `Could not find an iteration plan issue for ${versionMeta.tags.next} during the most recent site deploy - see https://github.com/microsoft/TypeScript-website/blob/v2/packages/typescriptlang-org/scripts/getTypeScriptReleaseInfo.js` |
| 37 | + ) |
| 38 | + } |
| 39 | + |
| 40 | + const lines = upcoming.body.toLowerCase().split("\n") |
| 41 | + const lastRelease = lines.find( |
| 42 | + l => |
| 43 | + l.includes(`${versionMeta.tags.stableMajMin} release`) && l.includes("|") |
| 44 | + ) |
| 45 | + const beta = lines.find( |
| 46 | + l => l.includes(`${versionMeta.tags.next} beta release`) && l.includes("|") |
| 47 | + ) |
| 48 | + |
| 49 | + const rc = lines.find( |
| 50 | + l => l.includes(`${versionMeta.tags.next} rc release`) && l.includes("|") |
| 51 | + ) |
| 52 | + |
| 53 | + const release = lines.find( |
| 54 | + l => l.includes(`${versionMeta.tags.next} final release`) && l.includes("|") |
| 55 | + ) |
| 56 | + |
| 57 | + // Making sure we got good data |
| 58 | + const dates = { |
| 59 | + lastRelease, |
| 60 | + beta, |
| 61 | + rc, |
| 62 | + release, |
| 63 | + } |
| 64 | + const missing = [] |
| 65 | + Object.keys(dates).forEach(key => { |
| 66 | + if (!dates[key]) { |
| 67 | + missing.push(key) |
| 68 | + } |
| 69 | + }) |
| 70 | + if (missing.length) { |
| 71 | + // prettier-ignore |
| 72 | + return sendTeamsFail(`Could not parse the md table for ${missing.join(",")} in https://github.com/microsoft/TypeScript/issues/${upcoming.number} - see https://github.com/microsoft/TypeScript-website/blob/v2/packages/typescriptlang-org/scripts/getTypeScriptReleaseInfo.js`) |
| 73 | + } |
| 74 | + |
| 75 | + // "june 29th | **typescript 4.4 beta release**\r" -> Date |
| 76 | + const toDate = str => { |
| 77 | + const date = str.split("|")[0].trim() |
| 78 | + const components = date.split(" ") |
| 79 | + const month = components[0] |
| 80 | + const day = components[1].replace("th", "").replace("st", "") |
| 81 | + const thisYear = new Date().getFullYear() |
| 82 | + const year = parseInt(components[2]) || thisYear |
| 83 | + return new Date(`${month} ${day} ${year}`).toISOString() |
| 84 | + } |
| 85 | + |
| 86 | + const results = { |
| 87 | + "_generated by": |
| 88 | + "node packages/typescriptlang-org/scripts/getTypeScriptReleasePlan.js", |
| 89 | + upcoming_version: versionMeta.tags.next, |
| 90 | + iteration_plan_url: `https://github.com/microsoft/TypeScript/issues/${upcoming.number}`, |
| 91 | + last_release_date: toDate(lastRelease), |
| 92 | + upcoming_beta_date: toDate(beta), |
| 93 | + upcoming_rc_date: toDate(rc), |
| 94 | + upcoming_release_date: toDate(release), |
| 95 | + } |
| 96 | + const jsonPath = join(__dirname, "..", "src", "lib", "release-plan.json") |
| 97 | + |
| 98 | + writeFileSync( |
| 99 | + jsonPath, |
| 100 | + format(JSON.stringify(results), { filepath: jsonPath }) |
| 101 | + ) |
| 102 | +} |
| 103 | + |
| 104 | +go() |
| 105 | + |
| 106 | +const sendTeamsFail = title => { |
| 107 | + const teamsURL = process.env.TEAMS_WEB_BOT_INCOMING_URL |
| 108 | + const message = { |
| 109 | + "@type": "MessageCard", |
| 110 | + "@context": "https://schema.org/extensions", |
| 111 | + summary: "Website issue", |
| 112 | + themeColor: "0078D7", |
| 113 | + title, |
| 114 | + } |
| 115 | + |
| 116 | + fetch(teamsURL, { |
| 117 | + method: "post", |
| 118 | + body: JSON.stringify(message), |
| 119 | + headers: { "Content-Type": "application/json" }, |
| 120 | + }) |
| 121 | +} |
0 commit comments