Skip to content
Snippets Groups Projects
Select Git revision
  • 93b13b55db544651963dd80f4b97dc7fc1bb96cf
  • main default protected
  • feat/gnupg
  • next
  • fix/36615b-branch-reuse-no-cache
  • renovate/main-redis-5.x
  • chore/punycode
  • refactor/pin-new-value
  • feat/36219--git-x509-signing
  • feat/structured-logger
  • hotfix/39.264.1
  • feat/skip-dangling
  • gh-readonly-queue/next/pr-36034-7a061c4ca1024a19e2c295d773d9642625d1c2be
  • hotfix/39.238.3
  • refactor/gitlab-auto-approve
  • feat/template-strings
  • gh-readonly-queue/next/pr-35654-137d934242c784e0c45d4b957362214f0eade1d7
  • fix/32307-global-extends-merging
  • fix/32307-global-extends-repositories
  • gh-readonly-queue/next/pr-35009-046ebf7cb84ab859f7fefceb5fa53a54ce9736f8
  • gh-readonly-queue/next/pr-35009-9d5e583b7d7251148ab0d11ee8dd38149618d162
  • 41.43.5
  • 41.43.4
  • 41.43.3
  • 41.43.2
  • 41.43.1
  • 41.43.0
  • 41.42.12
  • 41.42.11
  • 41.42.10
  • 41.42.9
  • 41.42.8
  • 41.42.7
  • 41.42.6
  • 41.42.5
  • 41.42.4
  • 41.42.3
  • 41.42.2
  • 41.42.1
  • 41.42.0
  • 41.41.0
41 results

npm.js

Blame
  • index.js 6.83 KiB
    const schedule = require('./schedule');
    const { getUpdatedPackageFiles } = require('../../manager');
    const { getUpdatedLockFiles } = require('./lock-files');
    const { commitFilesToBranch } = require('./commit');
    const { getParentBranch } = require('./parent');
    const { tryBranchAutomerge } = require('./automerge');
    const { setUnpublishable } = require('./status-checks');
    const { prAlreadyExisted } = require('./check-existing');
    const prWorker = require('../pr');
    
    const { isScheduledNow } = schedule;
    
    module.exports = {
      processBranch,
    };
    
    async function processBranch(branchConfig) {
      const config = { ...branchConfig };
      let dependencies = config.upgrades
        .map(upgrade => upgrade.depName)
        .filter(v => v); // remove nulls (happens for lock file maintenance)
      // remove duplicates
      dependencies = dependencies.filter(
        (item, index) => dependencies.indexOf(item) === index
      );
      logger.setMeta({
        repository: config.repository,
        branch: config.branchName,
        dependencies,
      });
      logger.trace({ config }, 'processBranch');
      try {
        logger.info(`Branch has ${dependencies.length} upgrade(s)`);
    
        // Check if branch already existed
        const pr = await prAlreadyExisted(config);
        if (pr) {
          logger.info(
            { prTitle: config.prTitle },
            'Closed PR already exists. Skipping branch.'
          );
          const subject = 'Renovate Ignore Notification';
          let content;
          if (config.isMajor) {
            content = `As this PR has been closed unmerged, Renovate will ignore this upgrade and you will not receive PRs for *any* future ${
              config.newVersionMajor
            }.x releases. However, if you upgrade to ${
              config.newVersionMajor
            }.x manually then Renovate will then reenable updates for minor and patch updates automatically.`;
          } else if (config.isDigest) {
            content = `As this PR has been closed unmerged, Renovate will ignore this upgrade type and you will not receive PRs for *any* future ${
              config.depName
            }:${
              config.currentTag
            } digest updates. Digest updates will resume if you update the specified tag at any time.`;
          } else {
            content = `As this PR has been closed unmerged, Renovate will now ignore this update (${
              config.newVersion
            }). You will still receive a PR once a newer version is released, so if you wish to permanently ignore this dependency, please add it to the \`ignoreDeps\` array of your renovate config.`;
          }
          content +=
            '\n\nIf this PR was closed by mistake or you changed your mind, you can simply reopen or rename it to reactivate Renovate for this dependency version.';
          await platform.ensureComment(pr.number, subject, content);
          return 'already-existed';
        }
    
        // Check schedule
        config.isScheduledNow = isScheduledNow(config);
        if (!config.isScheduledNow) {
          if (!await platform.branchExists(config.branchName)) {
            logger.info('Skipping branch creation as not within schedule');
            return 'not-scheduled';
          }
          if (config.updateNotScheduled === false) {
            logger.debug('Skipping branch update as not within schedule');
            return 'not-scheduled';
          }
          logger.debug(
            'Branch exists but is not scheduled -- will update if necessary'
          );
        }
    
        Object.assign(config, await getParentBranch(config));
        logger.debug(`Using parentBranch: ${config.parentBranch}`);
        Object.assign(config, await getUpdatedPackageFiles(config));
        if (config.updatedPackageFiles.length) {
          logger.debug(
            { updatedPackageFiles: config.updatedPackageFiles },
            `Updated ${config.updatedPackageFiles.length} package files`
          );
        } else {
          logger.debug('No package files need updating');
        }
        Object.assign(config, await getUpdatedLockFiles(config));
        if (config.updatedLockFiles.length) {
          logger.debug(
            { updatedLockFiles: config.updatedLockFiles.map(f => f.name) },
            `Updated ${config.updatedLockFiles.length} lock files`
          );
        } else {
          logger.debug('No updated lock files in branch');
        }
        await commitFilesToBranch(config);
    
        // Set branch statuses
        await setUnpublishable(config);
    
        // Try to automerge branch and finish if successful
        logger.debug('Checking if we should automerge the branch');
        const mergeStatus = await tryBranchAutomerge(config);
        if (mergeStatus === 'automerged') {
          logger.debug('Branch is automerged - returning');
          return 'automerged';
        } else if (mergeStatus === 'failed') {
          config.forcePr = true;
        }
      } catch (err) {
        logger.error({ err }, `Error updating branch: ${err.message}`);
        // Don't throw here - we don't want to stop the other renovations
        return 'error';
      }
      try {
        logger.debug('Ensuring PR');
        logger.debug(
          `There are ${config.errors.length} errors and ${
            config.warnings.length
          } warnings`
        );
        const pr = await prWorker.ensurePr(config);
        // TODO: ensurePr should check for automerge itself
        if (pr) {
          const topic = 'Lock file problem';
          if (config.lockFileErrors && config.lockFileErrors.length) {
            logger.warn(
              { lockFileErrors: config.lockFileErrors },
              'lockFileErrors'
            );
            let content = `Renovate failed when attempting to generate `;
            content +=
              config.lockFileErrors.length > 1 ? 'lock files' : 'a lock file';
            content +=
              '. This is usually happens when you have private modules but have not added configuration for [private module support](https://renovateapp.com/docs/deep-dives/private-modules). It is strongly recommended that you do not merge this PR as-is.';
            content +=
              '\n\nRenovate **will not retry** generating a lockfile for this PR unless either (a) the `package.json` in this branch needs updating, or (b) ';
            if (config.recreateClosed) {
              content +=
                'you manually delete this PR so that it can be regenerated.';
            } else {
              content +=
                'you rename then delete this PR unmerged, so that it can be regenerated.';
            }
            content += '\n\nThe output from `stderr` is included below:\n\n';
            config.lockFileErrors.forEach(error => {
              content += `##### ${error.lockFile}\n\n`;
              content += `\`\`\`\n${error.stderr}\n\`\`\`\n\n`;
            });
            await platform.ensureComment(pr.number, topic, content);
          } else {
            if (config.updatedLockFiles && config.updatedLockFiles.length) {
              await platform.ensureCommentRemoval(pr.number, topic);
            }
            const prAutomerged = await prWorker.checkAutoMerge(pr, config);
            if (prAutomerged) {
              return 'automerged';
            }
          }
        }
      } catch (err) {
        logger.error({ err }, `Error ensuring PR: ${err.message}`);
        // Don't throw here - we don't want to stop the other renovations
      }
      return 'done';
    }