Skip to content
Snippets Groups Projects
Commit c1fd79ba authored by Rhys Arkins's avatar Rhys Arkins
Browse files

feat: cache github datasource results for 10 minutes

parent 6cf6eab8
No related branches found
No related tags found
No related merge requests found
const cacache = require('cacache/en');
const os = require('os');
const { DateTime } = require('luxon');
const ghGot = require('../platform/github/gh-got-wrapper'); const ghGot = require('../platform/github/gh-got-wrapper');
const versioning = require('../versioning'); const versioning = require('../versioning');
module.exports = { module.exports = {
getPreset, getPreset,
getPkgReleases, getPkgReleases,
rmAllCache,
}; };
const datasourceCache =
(process.env.RENOVATE_TMPDIR || os.tmpdir()) +
'/renovate-gh-datasource-cache-v1';
async function getCachedResult(repo, type) {
try {
const cacheVal = await cacache.get(datasourceCache, `${repo}-${type}`);
const cachedResult = JSON.parse(cacheVal.data.toString());
if (cachedResult) {
if (DateTime.local() < DateTime.fromISO(cachedResult.expiry)) {
logger.debug(
{ repo, type },
'Returning cached github datasource result'
);
delete cachedResult.expiry;
return cachedResult;
}
// istanbul ignore next
logger.debug('Cache expiry');
}
} catch (err) {
logger.debug('Cache miss');
}
return null;
}
async function setCachedResult(repo, type, res) {
logger.debug({ repo, type }, 'Saving cached github datasource');
await cacache.put(
datasourceCache,
`${repo}-${type}`,
JSON.stringify({ ...res, expiry: DateTime.local().plus({ minutes: 10 }) })
);
}
async function rmAllCache() {
await cacache.rm.all(datasourceCache);
}
const map = new Map(); const map = new Map();
async function getPreset(pkgName, presetName = 'default') { async function getPreset(pkgName, presetName = 'default') {
...@@ -35,6 +79,10 @@ async function getPkgReleases(purl, config) { ...@@ -35,6 +79,10 @@ async function getPkgReleases(purl, config) {
const { versionScheme } = config || {}; const { versionScheme } = config || {};
const { fullname: repo, qualifiers: options } = purl; const { fullname: repo, qualifiers: options } = purl;
let versions; let versions;
const cachedResult = await getCachedResult(repo, options.ref);
if (cachedResult) {
return cachedResult;
}
try { try {
if (options.ref === 'release') { if (options.ref === 'release') {
const url = `repos/${repo}/releases?per_page=100`; const url = `repos/${repo}/releases?per_page=100`;
...@@ -69,5 +117,6 @@ async function getPkgReleases(purl, config) { ...@@ -69,5 +117,6 @@ async function getPkgReleases(purl, config) {
version: options.sanitize === 'true' ? isVersion(version) : version, version: options.sanitize === 'true' ? isVersion(version) : version,
gitRef: version, gitRef: version,
})); }));
setCachedResult(repo, options.ref, dependency);
return dependency; return dependency;
} }
...@@ -31,3 +31,19 @@ Object { ...@@ -31,3 +31,19 @@ Object {
"repositoryUrl": "https://github.com/some/dep", "repositoryUrl": "https://github.com/some/dep",
} }
`; `;
exports[`datasource/github getPkgReleases returns releases from cache 1`] = `
Object {
"releases": Array [
Object {
"gitRef": "1.0.0",
"version": "1.0.0",
},
Object {
"gitRef": "v1.1.0",
"version": "v1.1.0",
},
],
"repositoryUrl": "https://github.com/some/dep",
}
`;
const delay = require('delay');
const datasource = require('../../lib/datasource'); const datasource = require('../../lib/datasource');
const github = require('../../lib/datasource/github'); const github = require('../../lib/datasource/github');
const ghGot = require('../../lib/platform/github/gh-got-wrapper'); const ghGot = require('../../lib/platform/github/gh-got-wrapper');
...@@ -37,6 +39,7 @@ describe('datasource/github', () => { ...@@ -37,6 +39,7 @@ describe('datasource/github', () => {
}); });
}); });
describe('getPkgReleases', () => { describe('getPkgReleases', () => {
beforeAll(() => github.rmAllCache());
it('returns cleaned tags', async () => { it('returns cleaned tags', async () => {
const body = [ const body = [
{ name: 'a' }, { name: 'a' },
...@@ -71,6 +74,17 @@ describe('datasource/github', () => { ...@@ -71,6 +74,17 @@ describe('datasource/github', () => {
res.releases.find(release => release.version === 'v1.1.0') res.releases.find(release => release.version === 'v1.1.0')
).toBeDefined(); ).toBeDefined();
}); });
it('returns releases from cache', async () => {
await delay(1000);
const res = await datasource.getPkgReleases(
'pkg:github/some/dep?ref=release'
);
expect(res).toMatchSnapshot();
expect(res.releases).toHaveLength(2);
expect(
res.releases.find(release => release.version === 'v1.1.0')
).toBeDefined();
});
it('returns null for invalid ref', async () => { it('returns null for invalid ref', async () => {
expect( expect(
await datasource.getPkgReleases('pkg:github/some/dep?ref=invalid') await datasource.getPkgReleases('pkg:github/some/dep?ref=invalid')
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment