From 04e789c6da29537a633328685225f57f81ff8adf Mon Sep 17 00:00:00 2001 From: Gabriel-Ladzaretti <97394622+Gabriel-Ladzaretti@users.noreply.github.com> Date: Fri, 10 Jun 2022 07:48:51 +0300 Subject: [PATCH] docs: add per manager known list of issues (#15956) --- tools/docs/github-query-items.ts | 16 +++++ tools/docs/manager.ts | 120 +++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 tools/docs/github-query-items.ts diff --git a/tools/docs/github-query-items.ts b/tools/docs/github-query-items.ts new file mode 100644 index 0000000000..f9668ce59b --- /dev/null +++ b/tools/docs/github-query-items.ts @@ -0,0 +1,16 @@ +export type GithubApiQueryResponse = { + total_count: number; + incomplete_results: boolean; + items: ItemsEntity[]; +}; + +export type ItemsEntity = { + html_url: string; + number: number; + title: string; + labels: LabelsEntity[]; +}; + +export type LabelsEntity = { + name: string; +}; diff --git a/tools/docs/manager.ts b/tools/docs/manager.ts index b8bb426982..d6cb995592 100644 --- a/tools/docs/manager.ts +++ b/tools/docs/manager.ts @@ -1,8 +1,29 @@ +import { DateTime } from 'luxon'; import type { RenovateConfig } from '../../lib/config/types'; +import { logger } from '../../lib/logger'; import { getManagers } from '../../lib/modules/manager'; +import * as hostRules from '../../lib/util/host-rules'; +import { GithubHttp } from '../../lib/util/http/github'; +import { getQueryString } from '../../lib/util/url'; import { readFile, updateFile } from '../utils'; +import type { GithubApiQueryResponse, ItemsEntity } from './github-query-items'; import { getDisplayName, getNameWithUrl, replaceContent } from './utils'; +const gitHubApiUrl = 'https://api.github.com/search/issues?'; + +if (process.env.GITHUB_TOKEN) { + logger.debug('Using GITHUB_TOKEN from env'); + hostRules.add({ + matchHost: 'api.github.com', + token: process.env.GITHUB_TOKEN, + }); +} + +interface ManagerIssues { + bugs: ItemsEntity[]; + features: ItemsEntity[]; +} + function getTitle(manager: string, displayName: string): string { if (manager === 'regex') { return `Custom Manager Support using Regex`; @@ -14,8 +35,84 @@ function getManagerLink(manager: string): string { return `[\`${manager}\`](${manager}/)`; } +function stringifyIssues(items: ItemsEntity[]): [string, number] { + if (!items) { + return ['', 0]; + } + let list = ''; + for (const item of items) { + list += ` - ${item.title} [#${item.number}](${item.html_url})\n`; + } + return [list, items.length]; +} + +function extractIssues( + managerIssuesMap: Record<string, ManagerIssues>, + items: ItemsEntity[] +): void { + if (!items || !managerIssuesMap) { + return; + } + for (const item of items) { + const type = item.labels + .find((l) => l.name.startsWith('type:')) + ?.name.split(':')[1]; + if (!type) { + continue; + } + const manager = item.labels + .find((l) => l.name.startsWith('manager:')) + ?.name.split(':')[1]; + if (!manager) { + continue; + } + if (!managerIssuesMap[manager]) { + managerIssuesMap[manager] = { bugs: [], features: [] }; + } + switch (type) { + case 'bug': + managerIssuesMap[manager].bugs.push(item); + break; + case 'feature': + managerIssuesMap[manager].features.push(item); + break; + default: + break; + } + } +} + +export async function getManagersGitHubIssues(): Promise< + Record<string, ManagerIssues> +> { + const q = `repo:renovatebot/renovate type:issue is:open -label:priority-5-triage`; + const per_page = 100; + const managerIssuesMap: Record<string, ManagerIssues> = {}; + const githubApi = new GithubHttp('manager-issues'); + try { + const query = getQueryString({ q, per_page }); + const res = await githubApi.getJson<GithubApiQueryResponse>( + gitHubApiUrl + query, + { + paginationField: 'items', + paginate: true, + } + ); + const items = res.body?.items ?? []; + extractIssues( + managerIssuesMap, + items.sort((a, b) => a.number - b.number) + ); + } catch (err) { + logger.error({ err }, 'Error getting query results'); + throw err; + } + return managerIssuesMap; +} + export async function generateManagers(dist: string): Promise<void> { const managers = getManagers(); + const managerIssuesMap = await getManagersGitHubIssues(); const allLanguages: Record<string, string[]> = {}; for (const [manager, definition] of managers) { const language = definition.language ?? 'other'; @@ -73,6 +170,29 @@ sidebar_label: ${displayName} } md += managerReadmeContent + '\n\n'; + const [featureList] = stringifyIssues(managerIssuesMap[manager]?.features); + if (featureList) { + md += '## Open feature requests\n\n'; + md += featureList; + md += '\n'; + } + + const [bugList] = stringifyIssues(managerIssuesMap[manager]?.bugs); + if (bugList) { + md += '## Open bug reports\n\n'; + md += bugList; + md += '\n'; + } + + if (featureList || bugList) { + const now = DateTime.utc().toFormat('MMMM dd, yyyy'); + const lists = `list of ${featureList ? 'features' : ''}${ + featureList && bugList ? ' and ' : '' + }${bugList ? 'bugs' : ''}`; + md += '\n\n'; + md += `The above ${lists} were current when this page was generated on ${now}.\n`; + } + await updateFile(`${dist}/modules/manager/${manager}/index.md`, md); } const languages = Object.keys(allLanguages).filter( -- GitLab