mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-13 07:26:26 +00:00
fix: Remove repository cache migrations (#18025)
This commit is contained in:
parent
3f0303c167
commit
db1086a79f
8 changed files with 29 additions and 247 deletions
68
lib/util/cache/repository/common.ts
vendored
68
lib/util/cache/repository/common.ts
vendored
|
@ -1,70 +1,2 @@
|
||||||
import is from '@sindresorhus/is';
|
|
||||||
import type {
|
|
||||||
RepoCacheRecordV10,
|
|
||||||
RepoCacheRecordV11,
|
|
||||||
RepoCacheRecordV12,
|
|
||||||
RepoCacheRecordV13,
|
|
||||||
} from './types';
|
|
||||||
|
|
||||||
// Increment this whenever there could be incompatibilities between old and new cache structure
|
// Increment this whenever there could be incompatibilities between old and new cache structure
|
||||||
export const CACHE_REVISION = 13;
|
export const CACHE_REVISION = 13;
|
||||||
|
|
||||||
export function isValidRev10(
|
|
||||||
input: unknown,
|
|
||||||
repo?: string
|
|
||||||
): input is RepoCacheRecordV10 {
|
|
||||||
return (
|
|
||||||
is.plainObject(input) &&
|
|
||||||
is.safeInteger(input.revision) &&
|
|
||||||
input.revision === 10 &&
|
|
||||||
is.string(input.repository) &&
|
|
||||||
(!repo || repo === input.repository)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isValidRev11(
|
|
||||||
input: unknown,
|
|
||||||
repo?: string
|
|
||||||
): input is RepoCacheRecordV11 {
|
|
||||||
return (
|
|
||||||
is.plainObject(input) &&
|
|
||||||
is.safeInteger(input.revision) &&
|
|
||||||
input.revision === 11 &&
|
|
||||||
is.string(input.repository) &&
|
|
||||||
is.plainObject(input.data) &&
|
|
||||||
(!repo || repo === input.repository)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isValidRev12Shape(
|
|
||||||
input: unknown,
|
|
||||||
repo?: string
|
|
||||||
): input is RepoCacheRecordV12 {
|
|
||||||
return (
|
|
||||||
is.plainObject(input) &&
|
|
||||||
is.safeInteger(input.revision) &&
|
|
||||||
is.string(input.repository) &&
|
|
||||||
is.string(input.payload) &&
|
|
||||||
is.string(input.hash)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isValidRev12(
|
|
||||||
input: unknown,
|
|
||||||
repo?: string
|
|
||||||
): input is RepoCacheRecordV12 {
|
|
||||||
return (
|
|
||||||
isValidRev12Shape(input, repo) &&
|
|
||||||
input.revision === 12 &&
|
|
||||||
(!repo || repo === input.repository)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isValidRev13(input: unknown): input is RepoCacheRecordV13 {
|
|
||||||
return (
|
|
||||||
is.plainObject(input) &&
|
|
||||||
is.string(input.fingerprint) &&
|
|
||||||
isValidRev12Shape(input) &&
|
|
||||||
input.revision === 13
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
64
lib/util/cache/repository/impl/base.ts
vendored
64
lib/util/cache/repository/impl/base.ts
vendored
|
@ -4,23 +4,11 @@ import is from '@sindresorhus/is';
|
||||||
import hasha from 'hasha';
|
import hasha from 'hasha';
|
||||||
import { GlobalConfig } from '../../../../config/global';
|
import { GlobalConfig } from '../../../../config/global';
|
||||||
import { logger } from '../../../../logger';
|
import { logger } from '../../../../logger';
|
||||||
|
import * as schema from '../../../schema';
|
||||||
import { safeStringify } from '../../../stringify';
|
import { safeStringify } from '../../../stringify';
|
||||||
import {
|
import { CACHE_REVISION } from '../common';
|
||||||
CACHE_REVISION,
|
import { RepoCacheRecord, RepoCacheV13 } from '../schemas';
|
||||||
isValidRev10,
|
import type { RepoCache, RepoCacheData } from '../types';
|
||||||
isValidRev11,
|
|
||||||
isValidRev12,
|
|
||||||
isValidRev13,
|
|
||||||
} from '../common';
|
|
||||||
import type {
|
|
||||||
RepoCache,
|
|
||||||
RepoCacheData,
|
|
||||||
RepoCacheRecord,
|
|
||||||
RepoCacheRecordV10,
|
|
||||||
RepoCacheRecordV11,
|
|
||||||
RepoCacheRecordV12,
|
|
||||||
RepoCacheRecordV13,
|
|
||||||
} from '../types';
|
|
||||||
|
|
||||||
const compress = promisify(zlib.brotliCompress);
|
const compress = promisify(zlib.brotliCompress);
|
||||||
const decompress = promisify(zlib.brotliDecompress);
|
const decompress = promisify(zlib.brotliDecompress);
|
||||||
|
@ -39,17 +27,11 @@ export abstract class RepoCacheBase implements RepoCache {
|
||||||
|
|
||||||
protected abstract write(data: RepoCacheRecord): Promise<void>;
|
protected abstract write(data: RepoCacheRecord): Promise<void>;
|
||||||
|
|
||||||
private restoreFromRev10(oldCache: RepoCacheRecordV10): void {
|
private async restore(oldCache: RepoCacheRecord): Promise<void> {
|
||||||
delete oldCache.repository;
|
if (oldCache.fingerprint !== this.fingerprint) {
|
||||||
delete oldCache.revision;
|
logger.debug('Repository cache fingerprint is invalid');
|
||||||
this.data = oldCache;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private restoreFromRev11(oldCache: RepoCacheRecordV11): void {
|
|
||||||
this.data = oldCache.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async restoreFromRev12(oldCache: RepoCacheRecordV12): Promise<void> {
|
|
||||||
const compressed = Buffer.from(oldCache.payload, 'base64');
|
const compressed = Buffer.from(oldCache.payload, 'base64');
|
||||||
const uncompressed = await decompress(compressed);
|
const uncompressed = await decompress(compressed);
|
||||||
const jsonStr = uncompressed.toString('utf8');
|
const jsonStr = uncompressed.toString('utf8');
|
||||||
|
@ -57,14 +39,6 @@ export abstract class RepoCacheBase implements RepoCache {
|
||||||
this.oldHash = oldCache.hash;
|
this.oldHash = oldCache.hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async restoreFromRev13(oldCache: RepoCacheRecordV13): Promise<void> {
|
|
||||||
if (oldCache.fingerprint !== this.fingerprint) {
|
|
||||||
logger.debug('Repository cache fingerprint is invalid');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await this.restoreFromRev12(oldCache);
|
|
||||||
}
|
|
||||||
|
|
||||||
async load(): Promise<void> {
|
async load(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const rawOldCache = await this.read();
|
const rawOldCache = await this.read();
|
||||||
|
@ -76,30 +50,12 @@ export abstract class RepoCacheBase implements RepoCache {
|
||||||
}
|
}
|
||||||
const oldCache = JSON.parse(rawOldCache) as unknown;
|
const oldCache = JSON.parse(rawOldCache) as unknown;
|
||||||
|
|
||||||
if (isValidRev13(oldCache)) {
|
if (schema.match(RepoCacheV13, oldCache)) {
|
||||||
await this.restoreFromRev13(oldCache);
|
await this.restore(oldCache);
|
||||||
logger.debug('Repository cache is restored from revision 13');
|
logger.debug('Repository cache is restored from revision 13');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isValidRev12(oldCache, this.repository)) {
|
|
||||||
await this.restoreFromRev12(oldCache);
|
|
||||||
logger.debug('Repository cache is restored from revision 12');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isValidRev11(oldCache, this.repository)) {
|
|
||||||
this.restoreFromRev11(oldCache);
|
|
||||||
logger.debug('Repository cache is restored from revision 11');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isValidRev10(oldCache, this.repository)) {
|
|
||||||
this.restoreFromRev10(oldCache);
|
|
||||||
logger.debug('Repository cache is restored from revision 10');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug('Repository cache is invalid');
|
logger.debug('Repository cache is invalid');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.debug({ err }, 'Error reading repository cache');
|
logger.debug({ err }, 'Error reading repository cache');
|
||||||
|
|
99
lib/util/cache/repository/impl/local.spec.ts
vendored
99
lib/util/cache/repository/impl/local.spec.ts
vendored
|
@ -5,7 +5,8 @@ import { fs } from '../../../../../test/util';
|
||||||
import { GlobalConfig } from '../../../../config/global';
|
import { GlobalConfig } from '../../../../config/global';
|
||||||
import { logger } from '../../../../logger';
|
import { logger } from '../../../../logger';
|
||||||
import { CACHE_REVISION } from '../common';
|
import { CACHE_REVISION } from '../common';
|
||||||
import type { RepoCacheData, RepoCacheRecord } from '../types';
|
import type { RepoCacheRecord } from '../schemas';
|
||||||
|
import type { RepoCacheData } from '../types';
|
||||||
import { CacheFactory } from './cache-factory';
|
import { CacheFactory } from './cache-factory';
|
||||||
import { RepoCacheLocal } from './local';
|
import { RepoCacheLocal } from './local';
|
||||||
|
|
||||||
|
@ -109,102 +110,6 @@ describe('util/cache/repository/impl/local', () => {
|
||||||
expect(cache2.getData()).toBeEmpty();
|
expect(cache2.getData()).toBeEmpty();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('migrates revision from 10 to 13', async () => {
|
|
||||||
fs.readCacheFile.mockResolvedValue(
|
|
||||||
JSON.stringify({
|
|
||||||
revision: 10,
|
|
||||||
repository: 'some/repo',
|
|
||||||
semanticCommits: 'enabled',
|
|
||||||
})
|
|
||||||
);
|
|
||||||
const localRepoCache = CacheFactory.get(
|
|
||||||
'some/repo',
|
|
||||||
'0123456789abcdef',
|
|
||||||
'local'
|
|
||||||
);
|
|
||||||
|
|
||||||
await localRepoCache.load();
|
|
||||||
await localRepoCache.save();
|
|
||||||
|
|
||||||
const cacheRecord = await createCacheRecord({ semanticCommits: 'enabled' });
|
|
||||||
expect(fs.outputCacheFile).toHaveBeenCalledWith(
|
|
||||||
'/tmp/cache/renovate/repository/github/some/repo.json',
|
|
||||||
JSON.stringify(cacheRecord)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('migrates revision from 11 to 13', async () => {
|
|
||||||
fs.readCacheFile.mockResolvedValue(
|
|
||||||
JSON.stringify({
|
|
||||||
revision: 11,
|
|
||||||
repository: 'some/repo',
|
|
||||||
data: { semanticCommits: 'enabled' },
|
|
||||||
})
|
|
||||||
);
|
|
||||||
const localRepoCache = CacheFactory.get(
|
|
||||||
'some/repo',
|
|
||||||
'0123456789abcdef',
|
|
||||||
'local'
|
|
||||||
);
|
|
||||||
|
|
||||||
await localRepoCache.load();
|
|
||||||
await localRepoCache.save();
|
|
||||||
|
|
||||||
const cacheRecord = await createCacheRecord({ semanticCommits: 'enabled' });
|
|
||||||
expect(fs.outputCacheFile).toHaveBeenCalledWith(
|
|
||||||
'/tmp/cache/renovate/repository/github/some/repo.json',
|
|
||||||
JSON.stringify(cacheRecord)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('migrates revision from 12 to 13', async () => {
|
|
||||||
const { repository, payload, hash } = await createCacheRecord({
|
|
||||||
semanticCommits: 'enabled',
|
|
||||||
});
|
|
||||||
|
|
||||||
fs.readCacheFile.mockResolvedValue(
|
|
||||||
JSON.stringify({ revision: 12, repository, payload, hash })
|
|
||||||
);
|
|
||||||
const localRepoCache = CacheFactory.get(
|
|
||||||
'some/repo',
|
|
||||||
'0123456789abcdef',
|
|
||||||
'local'
|
|
||||||
);
|
|
||||||
|
|
||||||
await localRepoCache.load();
|
|
||||||
const data = localRepoCache.getData();
|
|
||||||
data.semanticCommits = 'disabled';
|
|
||||||
await localRepoCache.save();
|
|
||||||
|
|
||||||
expect(fs.outputCacheFile).toHaveBeenCalledWith(
|
|
||||||
'/tmp/cache/renovate/repository/github/some/repo.json',
|
|
||||||
JSON.stringify(
|
|
||||||
await createCacheRecord({
|
|
||||||
semanticCommits: 'disabled',
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not migrate from older revisions to 11', async () => {
|
|
||||||
fs.readCacheFile.mockResolvedValueOnce(
|
|
||||||
JSON.stringify({
|
|
||||||
revision: 9,
|
|
||||||
repository: 'some/repo',
|
|
||||||
semanticCommits: 'enabled',
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const localRepoCache = CacheFactory.get(
|
|
||||||
'some/repo',
|
|
||||||
'0123456789abcdef',
|
|
||||||
'local'
|
|
||||||
);
|
|
||||||
await localRepoCache.load();
|
|
||||||
|
|
||||||
expect(localRepoCache.getData()).toBeEmpty();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('handles invalid data', async () => {
|
it('handles invalid data', async () => {
|
||||||
fs.readCacheFile.mockResolvedValue(JSON.stringify({ foo: 'bar' }));
|
fs.readCacheFile.mockResolvedValue(JSON.stringify({ foo: 'bar' }));
|
||||||
const localRepoCache = CacheFactory.get(
|
const localRepoCache = CacheFactory.get(
|
||||||
|
|
2
lib/util/cache/repository/impl/local.ts
vendored
2
lib/util/cache/repository/impl/local.ts
vendored
|
@ -2,7 +2,7 @@ import upath from 'upath';
|
||||||
import { GlobalConfig } from '../../../../config/global';
|
import { GlobalConfig } from '../../../../config/global';
|
||||||
import { logger } from '../../../../logger';
|
import { logger } from '../../../../logger';
|
||||||
import { cachePathExists, outputCacheFile, readCacheFile } from '../../../fs';
|
import { cachePathExists, outputCacheFile, readCacheFile } from '../../../fs';
|
||||||
import type { RepoCacheRecord } from '../types';
|
import type { RepoCacheRecord } from '../schemas';
|
||||||
import { RepoCacheBase } from './base';
|
import { RepoCacheBase } from './base';
|
||||||
|
|
||||||
export class RepoCacheLocal extends RepoCacheBase {
|
export class RepoCacheLocal extends RepoCacheBase {
|
||||||
|
|
2
lib/util/cache/repository/impl/s3.spec.ts
vendored
2
lib/util/cache/repository/impl/s3.spec.ts
vendored
|
@ -12,7 +12,7 @@ import { partial } from '../../../../../test/util';
|
||||||
import { GlobalConfig } from '../../../../config/global';
|
import { GlobalConfig } from '../../../../config/global';
|
||||||
import { logger } from '../../../../logger';
|
import { logger } from '../../../../logger';
|
||||||
import { parseS3Url } from '../../../s3';
|
import { parseS3Url } from '../../../s3';
|
||||||
import type { RepoCacheRecord } from '../types';
|
import type { RepoCacheRecord } from '../schemas';
|
||||||
import { CacheFactory } from './cache-factory';
|
import { CacheFactory } from './cache-factory';
|
||||||
import { RepoCacheS3 } from './s3';
|
import { RepoCacheS3 } from './s3';
|
||||||
|
|
||||||
|
|
2
lib/util/cache/repository/impl/s3.ts
vendored
2
lib/util/cache/repository/impl/s3.ts
vendored
|
@ -8,7 +8,7 @@ import {
|
||||||
import { logger } from '../../../../logger';
|
import { logger } from '../../../../logger';
|
||||||
import { getS3Client, parseS3Url } from '../../../s3';
|
import { getS3Client, parseS3Url } from '../../../s3';
|
||||||
import { streamToString } from '../../../streams';
|
import { streamToString } from '../../../streams';
|
||||||
import type { RepoCacheRecord } from '../types';
|
import type { RepoCacheRecord } from '../schemas';
|
||||||
import { RepoCacheBase } from './base';
|
import { RepoCacheBase } from './base';
|
||||||
|
|
||||||
export class RepoCacheS3 extends RepoCacheBase {
|
export class RepoCacheS3 extends RepoCacheBase {
|
||||||
|
|
13
lib/util/cache/repository/schemas.ts
vendored
Normal file
13
lib/util/cache/repository/schemas.ts
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const RepoCacheV13 = z
|
||||||
|
.object({
|
||||||
|
repository: z.string().min(1),
|
||||||
|
revision: z.number().refine((v) => v === 13),
|
||||||
|
payload: z.string().min(1),
|
||||||
|
hash: z.string().min(1),
|
||||||
|
fingerprint: z.string().min(1),
|
||||||
|
})
|
||||||
|
.strict();
|
||||||
|
|
||||||
|
export type RepoCacheRecord = z.infer<typeof RepoCacheV13>;
|
24
lib/util/cache/repository/types.ts
vendored
24
lib/util/cache/repository/types.ts
vendored
|
@ -75,30 +75,6 @@ export interface RepoCacheData {
|
||||||
prComments?: Record<number, Record<string, string>>;
|
prComments?: Record<number, Record<string, string>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RepoCacheRecordV10 extends RepoCacheData {
|
|
||||||
repository?: string;
|
|
||||||
revision?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RepoCacheRecordV11 {
|
|
||||||
repository: string;
|
|
||||||
revision: number;
|
|
||||||
data: RepoCacheData;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RepoCacheRecordV12 {
|
|
||||||
repository: string;
|
|
||||||
revision: number;
|
|
||||||
payload: string;
|
|
||||||
hash: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RepoCacheRecordV13 extends RepoCacheRecordV12 {
|
|
||||||
fingerprint: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type RepoCacheRecord = RepoCacheRecordV13;
|
|
||||||
|
|
||||||
export interface RepoCache {
|
export interface RepoCache {
|
||||||
load(): Promise<void>;
|
load(): Promise<void>;
|
||||||
save(): Promise<void>;
|
save(): Promise<void>;
|
||||||
|
|
Loading…
Reference in a new issue