renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
114 lines • 4.69 kB
JavaScript
;
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