From a1a0983416822d0651e684f893497d1b76b897fa Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Fri, 15 Dec 2023 20:13:03 +0100 Subject: [PATCH] fix: PR lookup for PRs with no backports --- src/data.js | 99 +++++++++++++++++++++++++++++------------------- src/routes/pr.js | 41 +++++++++++--------- 2 files changed, 82 insertions(+), 58 deletions(-) diff --git a/src/data.js b/src/data.js index 19e52e8..922f672 100644 --- a/src/data.js +++ b/src/data.js @@ -34,9 +34,14 @@ const getOctokit = async () => { const getReleasesOrUpdate = pMemoize( async () => { - const response = await fetch.default('https://electronjs.org/headers/index.json'); - const releases = await response.json(); - return releases.sort((a, b) => semver.compare(b.version, a.version)); + try { + const response = await fetch.default('https://electronjs.org/headers/index.json'); + const releases = await response.json(); + return releases.sort((a, b) => semver.compare(b.version, a.version)); + } catch (e) { + console.error(e.message); + return []; + } }, { cache: new ExpiryMap(60 * 1000), @@ -46,8 +51,15 @@ const getReleasesOrUpdate = pMemoize( const getActiveReleasesOrUpdate = pMemoize( async () => { - const response = await fetch.default('https://electron-sudowoodo.herokuapp.com/release/active'); - return response.json(); + try { + const response = await fetch.default( + 'https://electron-sudowoodo.herokuapp.com/release/active', + ); + return response.json(); + } catch (e) { + console.error(e.message); + return {}; + } }, { cache: new ExpiryMap(30 * 1000), @@ -71,17 +83,15 @@ const getAllSudowoodoReleasesOrUpdate = pMemoize( const getGitHubRelease = pMemoize( async (version) => { try { - return ( - await ( - await getOctokit() - ).repos.getReleaseByTag({ - owner: 'electron', - repo: version.includes('nightly') ? 'nightlies' : 'electron', - tag: version, - }) - ).data; + const octo = await getOctokit(); + const { data } = await octo.repos.getReleaseByTag({ + owner: 'electron', + repo: version.includes('nightly') ? 'nightlies' : 'electron', + tag: version, + }); + return data; } catch (e) { - console.error(e); + console.error(e.message); return null; } }, @@ -94,19 +104,18 @@ const getGitHubRelease = pMemoize( const getPR = pMemoize( async (prNumber) => { try { - return ( - await ( - await getOctokit() - ).pulls.get({ - owner: 'electron', - repo: 'electron', - pull_number: prNumber, - mediaType: { - format: 'html', - }, - }) - ).data; - } catch { + const octo = await getOctokit(); + const { data } = await octo.pulls.get({ + owner: 'electron', + repo: 'electron', + pull_number: prNumber, + mediaType: { + format: 'html', + }, + }); + return data; + } catch (e) { + console.error(e.message); return null; } }, @@ -128,7 +137,8 @@ const getPRComments = pMemoize( per_page: 100, }), ); - } catch { + } catch (e) { + console.error(e.message); return []; } }, @@ -140,15 +150,19 @@ const getPRComments = pMemoize( const compareTagToCommit = pMemoize( async (tag, commitSha) => { - const compare = await ( - await getOctokit() - ).repos.compareCommits({ - owner: 'electron', - repo: 'electron', - base: tag, - head: commitSha, - }); - return compare.data; + try { + const octo = await getOctokit(); + const { data } = await octo.repos.compareCommits({ + owner: 'electron', + repo: 'electron', + base: tag, + head: commitSha, + }); + return data; + } catch (e) { + console.error(e.message); + return null; + } }, { cache: new ExpiryMap(60 * 60 * 24 * 1000), @@ -158,8 +172,13 @@ const compareTagToCommit = pMemoize( const getTSDefs = pMemoize( async (version) => { - const file = await fetch(`https://unpkg.com/electron@${version}/electron.d.ts`); - return await file.text(); + try { + const file = await fetch(`https://unpkg.com/electron@${version}/electron.d.ts`); + return await file.text(); + } catch (e) { + console.error(e.message); + return null; + } }, { cache: new ExpiryMap(60 * 60 * 24 * 1000), diff --git a/src/routes/pr.js b/src/routes/pr.js index ee22974..4a53c65 100644 --- a/src/routes/pr.js +++ b/src/routes/pr.js @@ -1,7 +1,6 @@ const Handlebars = require('handlebars'); const { Router } = require('express'); const semver = require('semver'); -const MarkdownIt = require('markdown-it'); const createDOMPurify = require('dompurify'); const { JSDOM } = require('jsdom'); @@ -20,15 +19,12 @@ Handlebars.registerHelper('html', (content) => DOMPurify.sanitize(content)); async function getPRReleaseStatus(prNumber) { const releases = [...(await getReleasesOrUpdate())].reverse(); const [prInfo, comments] = await Promise.all([getPR(prNumber), getPRComments(prNumber)]); - if (!prInfo) return null; - // PR is somehow targetting a repo that isn't in the electron org?? - if (prInfo.base.user.login !== 'electron') { - return null; - } + if (!prInfo) return null; - // PR is somehow targetting a repo that isn't the primary repo?? - if (prInfo.base.repo.name !== 'electron') { + // PR is somehow targeting a repo that isn't in the electron org + // or that isn't electron/electron. + if (prInfo.base.user.login !== 'electron' || prInfo.base.repo.name !== 'electron') { return null; } @@ -132,7 +128,6 @@ async function getPRReleaseStatus(prNumber) { // This is the primary PR, we can scan from here for backports return { - highlightPR: prNumber, primary: { pr: prInfo, availableIn, @@ -146,18 +141,28 @@ async function getPRReleaseStatus(prNumber) { }; } - // This is a backport PR, we should scan from here for the primary PR and then re-call getPRReleaseStatus with that primary PR + // This might be a backport PR - scan from here for the primary + // PR and then re-call getPRReleaseStatus with that primary PR. - // c.f. https://github.com/electron/trop/blob/master/src/utils/branch-util.ts#L62 - const backportPattern = - /(?:^|\n)(?:manual |manually )?backport (?:of )?(?:#(\d+)|https:\/\/github.com\/.*\/pull\/(\d+))/gim; - const match = backportPattern.exec(prInfo.body); - if (!match) return null; - const parentPRNumber = match[1] ? parseInt(match[1], 10) : parseInt(match[2], 10); + const isBackport = prInfo.labels.some((l) => l.name === 'backport'); + if (isBackport) { + // https://github.com/electron/trop/blob/master/src/utils/branch-util.ts#L62 + const backportPattern = + /(?:^|\n)(?:manual |manually )?backport (?:of )?(?:#(\d+)|https:\/\/github.com\/.*\/pull\/(\d+))/gim; + const match = backportPattern.exec(prInfo.body); + if (!match) return null; + const parentPRNumber = match[1] ? parseInt(match[1], 10) : parseInt(match[2], 10); + + return { + ...(await getPRReleaseStatus(parentPRNumber)), + }; + } + // This is a PR targeting main with no backports return { - ...(await getPRReleaseStatus(parentPRNumber)), - highlightPR: prNumber, + primary: { + pr: prInfo, + }, }; }