Skip to content
Snippets Groups Projects
Select Git revision
  • e27fe66980c5aa4b54ad2a4d30e425df3d318ada
  • main default protected
  • renovate/main-renovatebot-github-action-43.x
  • next
  • renovate/main-containerbase-internal-tools-3.x
  • renovate/main-lock-file-maintenance
  • renovate/main-docs-renovate-renovate-41.x
  • feat/gnupg
  • 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
  • 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

set-branch-commit.ts

Blame
  • validate.ts NaN GiB
    import JSON5 from 'json5';
    import { logger } from '../../../logger';
    import { migrateAndValidate } from '../../../config/migrate-validate';
    import { configFileNames } from '../../../config/app-strings';
    import { platform, Pr } from '../../../platform';
    import { RenovateConfig } from '../../../config';
    import { PR_STATE_OPEN } from '../../../constants/pull-requests';
    import { REPOSITORY_CHANGED } from '../../../constants/error-messages';
    import { BranchStatus } from '../../../types';
    
    async function getRenovatePrs(branchPrefix: string): Promise<Pr[]> {
      return (await platform.getPrList())
        .filter((pr) => pr.state === PR_STATE_OPEN)
        .filter((pr) => pr.branchName && !pr.branchName.startsWith(branchPrefix))
        .filter((pr) => new RegExp('renovate', 'i').test(pr.title));
    }
    
    async function getRenovateFiles(prNo: number): Promise<string[]> {
      return (await platform.getPrFiles(prNo)).filter((file) =>
        configFileNames.includes(file)
      );
    }
    
    export async function validatePrs(config: RenovateConfig): Promise<void> {
      if (
        config.suppressNotifications &&
        config.suppressNotifications.includes('prValidation')
      ) {
        return;
      }
      logger.debug('branchPrefix: ' + config.branchPrefix);
      const renovatePrs = await getRenovatePrs(config.branchPrefix);
      logger.debug({ renovatePrs }, `Found ${renovatePrs.length} Renovate PRs`);
      let validations = [];
      for (const pr of renovatePrs) {
        try {
          const renovateFiles = await getRenovateFiles(pr.number);
          if (!renovateFiles.length) {
            continue; // eslint-disable-line no-continue
          }
          logger.debug(
            { prNo: pr.number, title: pr.title, renovateFiles },
            'PR has renovate files'
          );
          for (const file of renovateFiles) {
            let content: string;
            try {
              content = await platform.getFile(file, pr.sha || pr.branchName);
            } catch (err) /* istanbul ignore next */ {
              content = await platform.getFile(file, pr.branchName);
            }
            // TODO: proper typing
            let parsed: {
              renovate?: RenovateConfig;
              'renovate-config'?: RenovateConfig;
            } & RenovateConfig;
            try {
              // istanbul ignore if
              if (file.endsWith('.json5')) {
                parsed = JSON5.parse(content);
              } else {
                parsed = JSON.parse(content);
              }
            } catch (err) {
              validations.push({
                file,
                message: 'Invalid JSON',
              });
            }
            if (parsed) {
              const toValidate =
                file === 'package.json'
                  ? /* istanbul ignore next */ parsed.renovate ||
                    parsed['renovate-config']
                  : parsed;
              if (toValidate) {
                logger.debug({ config: toValidate }, 'Validating config');
                const { errors } = await migrateAndValidate(config, toValidate);
                if (errors && errors.length) {
                  validations = validations.concat(
                    errors.map((error) => ({
                      file,
                      message: error.message,
                    }))
                  );
                }
              }
            }
          }
          // if the PR has renovate files then we set a status no matter what
          let status: BranchStatus;
          let description: string;
          const topic = `Renovate Configuration Errors`;
          if (validations.length) {
            const content = validations
              .map((v) => `\`${v.file}\`: ${v.message}`)
              .join('\n\n');
            await platform.ensureComment({
              number: pr.number,
              topic,
              content,
            });
            status = BranchStatus.red;
            description = `Renovate config validation failed`; // GitHub limit
          } else {
            description = `Renovate config is valid`;
            status = BranchStatus.green;
            await platform.ensureCommentRemoval(pr.number, topic);
          }
          // istanbul ignore else
          if (pr.sourceRepo === config.repository) {
            logger.debug({ status, description }, 'Setting PR validation status');
            const context = `renovate/validate`;
            await platform.setBranchStatus({
              branchName: pr.branchName,
              context,
              description,
              state: status,
            });
          } else {
            logger.debug('Skipping branch status for forked PR');
          }
        } catch (err) {
          // istanbul ignore if
          if (err.message === REPOSITORY_CHANGED) {
            logger.debug('Cannot access PR files to check them');
          } else {
            logger.warn(
              {
                err,
                prNo: pr.number,
                branchName: pr.branchName,
              },
              'Error checking PR'
            );
          }
        }
      }
    }