renovate
Version:
Automated dependency updates. Flexible so you don't need to be.
139 lines • 6.49 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateReconfigureBranch = validateReconfigureBranch;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const json5_1 = tslib_1.__importDefault(require("json5"));
const massage_1 = require("../../../config/massage");
const validation_1 = require("../../../config/validation");
const logger_1 = require("../../../logger");
const platform_1 = require("../../../modules/platform");
const comment_1 = require("../../../modules/platform/comment");
const scm_1 = require("../../../modules/platform/scm");
const repository_1 = require("../../../util/cache/repository");
const fs_1 = require("../../../util/fs");
const git_1 = require("../../../util/git");
const regex_1 = require("../../../util/regex");
const merge_1 = require("../init/merge");
const reconfigure_cache_1 = require("./reconfigure-cache");
const utils_1 = require("./utils");
async function setBranchStatus(branchName, description, state, context) {
if (!is_1.default.nonEmptyString(context)) {
// already logged this case when validating the status check
return;
}
await platform_1.platform.setBranchStatus({
branchName,
context,
description,
state,
});
}
async function validateReconfigureBranch(config) {
logger_1.logger.debug('validateReconfigureBranch()');
const context = config.statusCheckNames?.configValidation;
const branchName = (0, utils_1.getReconfigureBranchName)(config.branchPrefix);
// look for config file
// 1. check reconfigure branch cache and use the configFileName if it exists
// 2. checkout reconfigure branch and look for the config file, don't assume default configFileName
const branchSha = (0, git_1.getBranchCommit)(branchName);
const cache = (0, repository_1.getCache)();
let configFileName = null;
const reconfigureCache = cache.reconfigureBranchCache;
// only use valid cached information
if (reconfigureCache?.reconfigureBranchSha === branchSha) {
logger_1.logger.debug('Skipping validation check as branch sha is unchanged');
return;
}
if (context) {
const validationStatus = await platform_1.platform.getBranchStatusCheck(branchName, context);
// if old status check is present skip validation
if (is_1.default.nonEmptyString(validationStatus)) {
logger_1.logger.debug('Skipping validation check because status check already exists.');
return;
}
}
else {
logger_1.logger.debug('Status check is null or an empty string, skipping status check addition.');
}
try {
await scm_1.scm.checkoutBranch(branchName);
configFileName = await (0, merge_1.detectConfigFile)();
}
catch (err) {
logger_1.logger.error({ err }, 'Error while searching for config file in reconfigure branch');
}
if (!is_1.default.nonEmptyString(configFileName)) {
logger_1.logger.warn('No config file found in reconfigure branch');
await setBranchStatus(branchName, 'Validation Failed - No config file found', 'red', context);
(0, reconfigure_cache_1.setReconfigureBranchCache)(branchSha, false);
await scm_1.scm.checkoutBranch(config.defaultBranch);
return;
}
let configFileRaw = null;
try {
configFileRaw = await (0, fs_1.readLocalFile)(configFileName, 'utf8');
}
catch (err) {
logger_1.logger.error({ err }, 'Error while reading config file');
}
if (!is_1.default.nonEmptyString(configFileRaw)) {
logger_1.logger.warn('Empty or invalid config file');
await setBranchStatus(branchName, 'Validation Failed - Empty/Invalid config file', 'red', context);
(0, reconfigure_cache_1.setReconfigureBranchCache)(branchSha, false);
await scm_1.scm.checkoutBranch(config.baseBranch);
return;
}
let configFileParsed;
try {
configFileParsed = json5_1.default.parse(configFileRaw);
// no need to confirm renovate field in package.json we already do it in `detectConfigFile()`
if (configFileName === 'package.json') {
configFileParsed = configFileParsed.renovate;
}
}
catch (err) {
logger_1.logger.error({ err }, 'Error while parsing config file');
await setBranchStatus(branchName, 'Validation Failed - Unparsable config file', 'red', context);
(0, reconfigure_cache_1.setReconfigureBranchCache)(branchSha, false);
await scm_1.scm.checkoutBranch(config.baseBranch);
return;
}
// perform validation and provide a passing or failing check based on result
const massagedConfig = (0, massage_1.massageConfig)(configFileParsed);
const validationResult = await (0, validation_1.validateConfig)('repo', massagedConfig);
// failing check
if (validationResult.errors.length > 0) {
logger_1.logger.debug({ errors: validationResult.errors.map((err) => err.message).join(', ') }, 'Validation Errors');
const reconfigurePr = await platform_1.platform.findPr({
branchName,
state: 'open',
includeOtherAuthors: true,
targetBranch: config.defaultBranch,
});
// add comment to reconfigure PR if it exists
if (reconfigurePr) {
let body = `There is an error with this repository's Renovate configuration that needs to be fixed.\n\n`;
body += `Location: \`${configFileName}\`\n`;
body += `Message: \`${validationResult.errors
.map((e) => e.message)
.join(', ')
.replace((0, regex_1.regEx)(/`/g), "'")}\`\n`;
await (0, comment_1.ensureComment)({
number: reconfigurePr.number,
topic: 'Action Required: Fix Renovate Configuration',
content: body,
});
}
await setBranchStatus(branchName, 'Validation Failed', 'red', context);
(0, reconfigure_cache_1.setReconfigureBranchCache)(branchSha, false);
await scm_1.scm.checkoutBranch(config.baseBranch);
return;
}
// passing check
await setBranchStatus(branchName, 'Validation Successful', 'green', context);
(0, reconfigure_cache_1.setReconfigureBranchCache)(branchSha, true);
await scm_1.scm.checkoutBranch(config.baseBranch);
return;
}
//# sourceMappingURL=validate.js.map