mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-12 23:16: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
|
||||
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
|
||||
);
|
||||
}
|
||||
|
|
66
lib/util/cache/repository/impl/base.ts
vendored
66
lib/util/cache/repository/impl/base.ts
vendored
|
@ -4,23 +4,11 @@ import is from '@sindresorhus/is';
|
|||
import hasha from 'hasha';
|
||||
import { GlobalConfig } from '../../../../config/global';
|
||||
import { logger } from '../../../../logger';
|
||||
import * as schema from '../../../schema';
|
||||
import { safeStringify } from '../../../stringify';
|
||||
import {
|
||||
CACHE_REVISION,
|
||||
isValidRev10,
|
||||
isValidRev11,
|
||||
isValidRev12,
|
||||
isValidRev13,
|
||||
} from '../common';
|
||||
import type {
|
||||
RepoCache,
|
||||
RepoCacheData,
|
||||
RepoCacheRecord,
|
||||
RepoCacheRecordV10,
|
||||
RepoCacheRecordV11,
|
||||
RepoCacheRecordV12,
|
||||
RepoCacheRecordV13,
|
||||
} from '../types';
|
||||
import { CACHE_REVISION } from '../common';
|
||||
import { RepoCacheRecord, RepoCacheV13 } from '../schemas';
|
||||
import type { RepoCache, RepoCacheData } from '../types';
|
||||
|
||||
const compress = promisify(zlib.brotliCompress);
|
||||
const decompress = promisify(zlib.brotliDecompress);
|
||||
|
@ -39,17 +27,11 @@ export abstract class RepoCacheBase implements RepoCache {
|
|||
|
||||
protected abstract write(data: RepoCacheRecord): Promise<void>;
|
||||
|
||||
private restoreFromRev10(oldCache: RepoCacheRecordV10): void {
|
||||
delete oldCache.repository;
|
||||
delete oldCache.revision;
|
||||
this.data = oldCache;
|
||||
}
|
||||
|
||||
private restoreFromRev11(oldCache: RepoCacheRecordV11): void {
|
||||
this.data = oldCache.data;
|
||||
}
|
||||
|
||||
private async restoreFromRev12(oldCache: RepoCacheRecordV12): Promise<void> {
|
||||
private async restore(oldCache: RepoCacheRecord): Promise<void> {
|
||||
if (oldCache.fingerprint !== this.fingerprint) {
|
||||
logger.debug('Repository cache fingerprint is invalid');
|
||||
return;
|
||||
}
|
||||
const compressed = Buffer.from(oldCache.payload, 'base64');
|
||||
const uncompressed = await decompress(compressed);
|
||||
const jsonStr = uncompressed.toString('utf8');
|
||||
|
@ -57,14 +39,6 @@ export abstract class RepoCacheBase implements RepoCache {
|
|||
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> {
|
||||
try {
|
||||
const rawOldCache = await this.read();
|
||||
|
@ -76,30 +50,12 @@ export abstract class RepoCacheBase implements RepoCache {
|
|||
}
|
||||
const oldCache = JSON.parse(rawOldCache) as unknown;
|
||||
|
||||
if (isValidRev13(oldCache)) {
|
||||
await this.restoreFromRev13(oldCache);
|
||||
if (schema.match(RepoCacheV13, oldCache)) {
|
||||
await this.restore(oldCache);
|
||||
logger.debug('Repository cache is restored from revision 13');
|
||||
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');
|
||||
} catch (err) {
|
||||
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 { logger } from '../../../../logger';
|
||||
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 { RepoCacheLocal } from './local';
|
||||
|
||||
|
@ -109,102 +110,6 @@ describe('util/cache/repository/impl/local', () => {
|
|||
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 () => {
|
||||
fs.readCacheFile.mockResolvedValue(JSON.stringify({ foo: 'bar' }));
|
||||
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 { logger } from '../../../../logger';
|
||||
import { cachePathExists, outputCacheFile, readCacheFile } from '../../../fs';
|
||||
import type { RepoCacheRecord } from '../types';
|
||||
import type { RepoCacheRecord } from '../schemas';
|
||||
import { RepoCacheBase } from './base';
|
||||
|
||||
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 { logger } from '../../../../logger';
|
||||
import { parseS3Url } from '../../../s3';
|
||||
import type { RepoCacheRecord } from '../types';
|
||||
import type { RepoCacheRecord } from '../schemas';
|
||||
import { CacheFactory } from './cache-factory';
|
||||
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 { getS3Client, parseS3Url } from '../../../s3';
|
||||
import { streamToString } from '../../../streams';
|
||||
import type { RepoCacheRecord } from '../types';
|
||||
import type { RepoCacheRecord } from '../schemas';
|
||||
import { RepoCacheBase } from './base';
|
||||
|
||||
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>>;
|
||||
}
|
||||
|
||||
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 {
|
||||
load(): Promise<void>;
|
||||
save(): Promise<void>;
|
||||
|
|
Loading…
Reference in a new issue