const tmp = require('tmp'); const presets = require('../../config/presets'); // Workers const branchWorker = require('../branch'); // children const apis = require('./apis'); const onboarding = require('./onboarding'); const upgrades = require('./upgrades'); const cleanup = require('./cleanup'); module.exports = { renovateRepository, }; async function renovateRepository(repoConfig, token) { let config = { ...repoConfig }; const { logger } = config; config.tmpDir = tmp.dirSync({ unsafeCleanup: true }); config.errors = []; config.warnings = []; logger.trace({ config }, 'renovateRepository'); try { config = await apis.initApis(config, token); config = await apis.mergeRenovateJson(config); if (config.enabled === false) { logger.debug('repository is disabled'); await cleanup.pruneStaleBranches(config, []); return; } if (config.isFork && !config.renovateJsonPresent) { logger.debug('repository is a fork and not manually configured'); return; } if (config.baseBranch) { // Renovate should read content and target PRs here if (await config.api.branchExists(config.baseBranch)) { config.api.setBaseBranch(config.baseBranch); } else { // Warn and ignore setting (use default branch) const message = `The configured baseBranch "${config.baseBranch}" is not present. Ignoring`; config.errors.push({ depName: 'baseBranch', message, }); logger.warn(message); } } // Detect package files in default branch if not manually provisioned if (config.packageFiles.length === 0) { logger.debug('Detecting package files'); config = await apis.detectPackageFiles(config); // If we can't detect any package.json then return if (config.packageFiles.length === 0) { logger.info('Cannot detect package.json'); return; } logger.debug( `Detected ${config.packageFiles .length} package files: ${config.packageFiles}` ); } logger.debug('Resolving package files and content'); config = await apis.resolvePackageFiles(config); logger.trace({ config }, 'post-packageFiles config'); // TODO: why is this fix needed?! config.logger = logger; config.repoIsOnboarded = await onboarding.getOnboardingStatus(config); if (!config.repoIsOnboarded) { config.contentBaseBranch = `${config.branchPrefix}configure`; // Remove packageFile list in case they are provisioned in renovate.json const packageFiles = config.packageFiles.map( packageFile => packageFile.packageFile ); config.packageFiles = []; config = await apis.mergeRenovateJson(config, config.contentBaseBranch); // Restore previous packageFile list if not provisioned manually if (config.packageFiles.length === 0) { config.packageFiles = packageFiles; } if (config.baseBranch) { if (await config.api.branchExists(config.baseBranch)) { config.contentBaseBranch = config.baseBranch; } else { const message = `The configured baseBranch "${config.baseBranch}" is not present. Ignoring`; config.errors.push({ depName: 'baseBranch', message, }); logger.warn(message); } } config = await apis.resolvePackageFiles(config); config = await presets.resolveConfigPresets(config); config.logger = logger; logger.trace({ config }, 'onboarding config'); } const allUpgrades = await upgrades.determineRepoUpgrades(config); const res = await upgrades.branchifyUpgrades(allUpgrades, logger); config.errors = config.errors.concat(res.errors); config.warnings = config.warnings.concat(res.warnings); const branchUpgrades = res.upgrades; logger.debug(`Updating ${branchUpgrades.length} branch(es)`); logger.trace({ config: branchUpgrades }, 'branchUpgrades'); let branchList; if (config.repoIsOnboarded) { for (const branchUpgrade of branchUpgrades) { await branchWorker.processBranch( branchUpgrade, config.errors, config.warnings ); } branchList = branchUpgrades.map(upgrade => upgrade.branchName); logger.debug(`branchList=${branchList}`); } else { await onboarding.ensurePr(config, branchUpgrades); logger.info('"Configure Renovate" PR needs to be closed first'); branchList = [`${config.branchPrefix}configure`]; } await cleanup.pruneStaleBranches(config, branchList); } catch (err) { // Swallow this error so that other repositories can be processed if (err.message === 'uninitiated') { logger.info('Repository is uninitiated - skipping'); } else { logger.error(`Failed to process repository: ${err.message}`); logger.debug({ err }); } } config.tmpDir.removeCallback(); }