UNPKG

renovate

Version:

Automated dependency updates. Flexible so you don't need to be.

114 lines 4.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPrCache = getPrCache; exports.updatePrCache = updatePrCache; const tslib_1 = require("tslib"); const is_1 = tslib_1.__importDefault(require("@sindresorhus/is")); const logger_1 = require("../../../logger"); const external_host_error_1 = require("../../../types/errors/external-host-error"); const repository_1 = require("../../../util/cache/repository"); const repository_http_cache_provider_1 = require("../../../util/http/cache/repository-http-cache-provider"); const url_1 = require("../../../util/url"); const api_cache_1 = require("./api-cache"); const common_1 = require("./common"); function getPrApiCache() { const repoCache = (0, repository_1.getCache)(); if (!repoCache?.platform?.github?.pullRequestsCache) { logger_1.logger.debug('PR cache: cached data not found, creating new cache'); repoCache.platform ??= {}; repoCache.platform.github ??= {}; repoCache.platform.github.pullRequestsCache ??= { items: {} }; } const prApiCache = new api_cache_1.ApiCache(repoCache.platform.github.pullRequestsCache); return prApiCache; } /** * Fetch and return Pull Requests from GitHub repository: * * 1. Synchronize long-term cache. * * 2. Store items in raw format, i.e. exactly what * has been returned by GitHub REST API. * * 3. Convert items to the Renovate format and return. * * In order synchronize ApiCache properly, we handle 3 cases: * * a. We never fetched PR list for this repo before. * If cached PR list is empty, we assume it's the case. * * In this case, we're falling back to quick fetch via * `paginate=true` option (see `util/http/github.ts`). * * b. Some of PRs had changed since last run. * * In this case, we sequentially fetch page by page * until `ApiCache.coerce` function indicates that * no more fresh items can be found in the next page. * * We expect to fetch just one page per run in average, * since it's rare to have more than 100 updated PRs. */ async function getPrCache(http, repo, username) { const prApiCache = getPrApiCache(); const isInitial = is_1.default.emptyArray(prApiCache.getItems()); try { let requestsTotal = 0; let apiQuotaAffected = false; let needNextPageFetch = true; let needNextPageSync = true; let pageIdx = 1; while (needNextPageFetch && needNextPageSync) { const opts = { paginate: false, memCache: false }; if (pageIdx === 1) { opts.cacheProvider = repository_http_cache_provider_1.repoCacheProvider; if (isInitial) { // Speed up initial fetch opts.paginate = true; } } let perPage; if (isInitial) { logger_1.logger.debug('PR cache: initial fetch'); perPage = 100; } else { logger_1.logger.debug('PR cache: sync fetch'); perPage = 20; } const urlPath = `repos/${repo}/pulls?per_page=${perPage}&state=all&sort=updated&direction=desc&page=${pageIdx}`; const res = await http.getJsonUnchecked(urlPath, opts); apiQuotaAffected = true; requestsTotal += 1; const { headers: { link: linkHeader }, } = res; let { body: page } = res; if (username) { const filteredPage = page.filter((ghPr) => ghPr?.user?.login && ghPr.user.login === username); logger_1.logger.debug(`PR cache: Filtered ${page.length} PRs to ${filteredPage.length} (user=${username})`); page = filteredPage; } const items = page.map(common_1.coerceRestPr); needNextPageSync = prApiCache.reconcile(items); needNextPageFetch = !!(0, url_1.parseLinkHeader)(linkHeader)?.next; if (pageIdx === 1) { needNextPageFetch &&= !opts.paginate; } pageIdx += 1; } logger_1.logger.debug({ pullsTotal: prApiCache.getItems().length, requestsTotal, apiQuotaAffected, }, `PR cache: getPrList success`); } catch (err) /* v8 ignore start */ { logger_1.logger.debug({ err }, 'PR cache: getPrList err'); throw new external_host_error_1.ExternalHostError(err, 'github'); } /* v8 ignore stop */ return prApiCache.getItems(); } function updatePrCache(pr) { const cache = getPrApiCache(); cache.updateItem(pr); } //# sourceMappingURL=pr.js.map