diff --git a/packages/ci/package.json b/packages/ci/package.json index 8c8ffe9d1..f24f2a979 100644 --- a/packages/ci/package.json +++ b/packages/ci/package.json @@ -29,6 +29,7 @@ "@code-pushup/models": "0.91.0", "@code-pushup/portal-client": "^0.16.0", "@code-pushup/utils": "0.91.0", + "ansis": "^3.3.2", "glob": "^11.0.1", "simple-git": "^3.20.0", "yaml": "^2.5.1", diff --git a/packages/ci/src/lib/cli/exec.ts b/packages/ci/src/lib/cli/exec.ts index 724db0c6d..cf71c88fe 100644 --- a/packages/ci/src/lib/cli/exec.ts +++ b/packages/ci/src/lib/cli/exec.ts @@ -8,15 +8,56 @@ import { } from '@code-pushup/utils'; import type { CommandContext } from './context.js'; +/** + * Executes Code PushUp CLI command and logs output in a way that's more readable in CI. + * @param args Arguments for Code PushUp CLI + * @param context Command context + * @param options Optional information on whether all persist formats are set (if known) + */ export async function executeCliCommand( args: string[], context: CommandContext, options?: { hasFormats: boolean }, ): Promise { + const { logOutputChunk, logOutputEnd, logSilencedOutput } = + createLogCallbacks(context); + + const observer: ProcessObserver = { + onStdout: logOutputChunk, + onStderr: logOutputChunk, + onComplete: logOutputEnd, + onError: logOutputEnd, + }; + + const config: ProcessConfig = { + command: context.bin, + args: combineArgs(args, context, options), + cwd: context.directory, + observer, + silent: true, + }; + const bin = serializeCommandWithArgs(config); + + try { + await logger.command(bin, async () => { + try { + await executeProcess(config); + } catch (error) { + // ensure output of failed process is always logged for debugging + logSilencedOutput(); + throw error; + } + }); + } finally { + logger.newline(); + } +} + +function createLogCallbacks(context: Pick) { // eslint-disable-next-line functional/no-let let output = ''; - const logRaw = (message: string) => { + const logOutputChunk = (message: string) => { if (!context.silent) { if (!output) { logger.newline(); @@ -26,43 +67,23 @@ export async function executeCliCommand( output += message; }; - const logEnd = () => { + const logOutputEnd = () => { if (!context.silent && output) { logger.newline(); } }; - const observer: ProcessObserver = { - onStdout: logRaw, - onStderr: logRaw, - onComplete: logEnd, - onError: logEnd, - }; - - const config: ProcessConfig = { - command: context.bin, - args: combineArgs(args, context, options), - cwd: context.directory, - observer, - silent: true, - }; - const bin = serializeCommandWithArgs(config); - - await logger.command(bin, async () => { - try { - await executeProcess(config); - } catch (error) { - // ensure output of failed process is always logged for debugging - if (context.silent) { + const logSilencedOutput = () => { + if (context.silent) { + logger.newline(); + logger.info(output, { noIndent: true }); + if (!output.endsWith('\n')) { logger.newline(); - logger.info(output, { noIndent: true }); - if (!output.endsWith('\n')) { - logger.newline(); - } } - throw error; } - }); + }; + + return { logOutputChunk, logOutputEnd, logSilencedOutput }; } function combineArgs( diff --git a/packages/ci/src/lib/cli/exec.unit.test.ts b/packages/ci/src/lib/cli/exec.unit.test.ts index cb44f2398..25896ebbe 100644 --- a/packages/ci/src/lib/cli/exec.unit.test.ts +++ b/packages/ci/src/lib/cli/exec.unit.test.ts @@ -130,6 +130,7 @@ describe('executeCliCommand', () => { ` - $ npx code-pushup ✔ $ npx code-pushup (42 ms) + `.trimStart(), ); }); @@ -152,6 +153,7 @@ WARN: API key is missing, skipping upload Collected report files in .code-pushup directory ✔ $ npx code-pushup (42 ms) + `.trimStart(), ); }); @@ -197,6 +199,7 @@ Collected report Uploaded report to portal ✔ $ npx code-pushup (42 ms) + `.trimStart(), ); }); @@ -222,6 +225,7 @@ Code PushUp CLI v0.42.0 ERROR: Config file not found ✖ $ npx code-pushup + `.trimStart(), ); }); @@ -236,6 +240,7 @@ ERROR: Config file not found ` - $ npx code-pushup ✔ $ npx code-pushup (42 ms) + `.trimStart(), ); }); @@ -261,6 +266,7 @@ Code PushUp CLI v0.42.0 ERROR: Config file not found ✖ $ npx code-pushup + `.trimStart(), ); }); diff --git a/packages/ci/src/lib/comment.ts b/packages/ci/src/lib/comment.ts index 0877785ca..4ce8f2050 100644 --- a/packages/ci/src/lib/comment.ts +++ b/packages/ci/src/lib/comment.ts @@ -1,5 +1,5 @@ import { readFile } from 'node:fs/promises'; -import { logger } from '@code-pushup/utils'; +import { logDebug, logInfo, logWarning } from './log.js'; import type { ProviderAPIClient, Settings } from './models.js'; export async function commentOnPR( @@ -17,12 +17,12 @@ export async function commentOnPR( ); const comments = await api.listComments(); - logger.debug(`Fetched ${comments.length} comments for pull request`); + logDebug(`Fetched ${comments.length} comments for pull request`); const prevComment = comments.find(comment => comment.body.includes(identifier), ); - logger.debug( + logDebug( prevComment ? `Found previous comment ${prevComment.id} from Code PushUp` : 'Previous Code PushUp comment not found', @@ -30,19 +30,19 @@ export async function commentOnPR( if (prevComment) { const updatedComment = await api.updateComment(prevComment.id, body); - logger.info(`Updated body of comment ${updatedComment.url}`); + logInfo(`Updated body of comment ${updatedComment.url}`); return updatedComment.id; } const createdComment = await api.createComment(body); - logger.info(`Created new comment ${createdComment.url}`); + logInfo(`Created new comment ${createdComment.url}`); return createdComment.id; } function truncateBody(body: string, max: number): string { const truncateWarning = '...*[Comment body truncated]*'; if (body.length > max) { - logger.warn(`Comment body is too long. Truncating to ${max} characters.`); + logWarning(`Comment body is too long. Truncating to ${max} characters.`); return body.slice(0, max - truncateWarning.length) + truncateWarning; } return body; diff --git a/packages/ci/src/lib/comment.unit.test.ts b/packages/ci/src/lib/comment.unit.test.ts index e18aa061c..bcb1d6d0c 100644 --- a/packages/ci/src/lib/comment.unit.test.ts +++ b/packages/ci/src/lib/comment.unit.test.ts @@ -1,3 +1,4 @@ +import ansis from 'ansis'; import { vol } from 'memfs'; import { writeFile } from 'node:fs/promises'; import path from 'node:path'; @@ -112,7 +113,7 @@ describe('commentOnPR', () => { expect.stringContaining('...*[Comment body truncated]*'), ); expect(logger.warn).toHaveBeenCalledWith( - 'Comment body is too long. Truncating to 1000000 characters.', + `${ansis.bold.blue('<✓>')} Comment body is too long. Truncating to 1000000 characters.\n`, ); }); }); diff --git a/packages/ci/src/lib/log.ts b/packages/ci/src/lib/log.ts new file mode 100644 index 000000000..a387d2f2d --- /dev/null +++ b/packages/ci/src/lib/log.ts @@ -0,0 +1,59 @@ +import ansis from 'ansis'; +import { + CODE_PUSHUP_UNICODE_LOGO, + logger, + transformLines, +} from '@code-pushup/utils'; + +const LOG_PREFIX = ansis.bold.blue(CODE_PUSHUP_UNICODE_LOGO); + +/** + * Logs error message with top-level CI log styles (lines prefixed with logo, ends in empty line). + * @param message Log message + */ +export function logError(message: string): void { + log('error', message); +} + +/** + * Logs warning message with top-level CI log styles (lines prefixed with logo, ends in empty line). + * @param message Log message + */ +export function logWarning(message: string): void { + log('warn', message); +} + +/** + * Logs info message with top-level CI log styles (lines prefixed with logo, ends in empty line). + * @param message Log message + */ +export function logInfo(message: string): void { + log('info', message); +} + +/** + * Logs debug message with top-level CI log styles (lines prefixed with logo, ends in empty line). + * @param message Log message + */ +export function logDebug(message: string): void { + log('debug', message); +} + +/** + * Prefixes CI logs with logo and ensures each CI log is followed by an empty line. + * This is to make top-level CI logs more visually distinct from printed process logs. + * @param level Log level + * @param message Log message + */ +export function log( + level: 'error' | 'warn' | 'info' | 'debug', + message: string, +): void { + const prefixedLines = transformLines( + message.trim(), + line => `${LOG_PREFIX} ${line}`, + ); + const styledMessage = `${prefixedLines}\n`; + + logger[level](styledMessage); +} diff --git a/packages/ci/src/lib/log.unit.test.ts b/packages/ci/src/lib/log.unit.test.ts new file mode 100644 index 000000000..ffa641456 --- /dev/null +++ b/packages/ci/src/lib/log.unit.test.ts @@ -0,0 +1,31 @@ +import ansis from 'ansis'; +import { logger } from '@code-pushup/utils'; +import { log } from './log.js'; + +describe('log', () => { + it('should add logo prefix and ending line-break to message', () => { + log('info', 'Running Code PushUp in standalone mode'); + expect(logger.info).toHaveBeenCalledWith( + `${ansis.bold.blue('<✓>')} Running Code PushUp in standalone mode\n`, + ); + }); + + it('should add logo prefix to each line', () => { + log('debug', 'Found 3 Nx projects:\n- api\n- backoffice\n- frontoffice'); + expect(logger.debug).toHaveBeenCalledWith( + ` +${ansis.bold.blue('<✓>')} Found 3 Nx projects: +${ansis.bold.blue('<✓>')} - api +${ansis.bold.blue('<✓>')} - backoffice +${ansis.bold.blue('<✓>')} - frontoffice +`.trimStart(), + ); + }); + + it('should not add final line-break if already present', () => { + log('warn', 'Comment body is too long, truncating to 1000 characters\n'); + expect(logger.warn).toHaveBeenCalledWith( + `${ansis.bold.blue('<✓>')} Comment body is too long, truncating to 1000 characters\n`, + ); + }); +}); diff --git a/packages/ci/src/lib/monorepo/list-projects.ts b/packages/ci/src/lib/monorepo/list-projects.ts index 4b3b805e3..9cbc07ba0 100644 --- a/packages/ci/src/lib/monorepo/list-projects.ts +++ b/packages/ci/src/lib/monorepo/list-projects.ts @@ -1,6 +1,6 @@ import { glob } from 'glob'; import path from 'node:path'; -import { logger } from '@code-pushup/utils'; +import { logDebug, logInfo } from '../log.js'; import type { Settings } from '../models.js'; import { detectMonorepoTool } from './detect-tool.js'; import { getToolHandler } from './handlers/index.js'; @@ -31,8 +31,8 @@ export async function listMonorepoProjects( if (tool) { const handler = getToolHandler(tool); const projects = await handler.listProjects(options); - logger.info(`Found ${projects.length} projects in ${tool} monorepo`); - logger.debug(`Projects: ${projects.map(({ name }) => name).join(', ')}`); + logInfo(`Found ${projects.length} projects in ${tool} monorepo`); + logDebug(`Projects: ${projects.map(({ name }) => name).join(', ')}`); return { tool, projects, @@ -70,15 +70,15 @@ async function resolveMonorepoTool( } if (typeof settings.monorepo === 'string') { - logger.info(`Using monorepo tool "${settings.monorepo}" from inputs`); + logInfo(`Using monorepo tool "${settings.monorepo}" from inputs`); return settings.monorepo; } const tool = await detectMonorepoTool(options); if (tool) { - logger.info(`Auto-detected monorepo tool ${tool}`); + logInfo(`Auto-detected monorepo tool ${tool}`); } else { - logger.info("Couldn't auto-detect any supported monorepo tool"); + logInfo("Couldn't auto-detect any supported monorepo tool"); } return tool; @@ -110,12 +110,12 @@ async function listProjectsByGlobs(args: { { cwd }, ); - logger.info( + logInfo( `Found ${directories.length} project folders matching "${patterns.join( ', ', )}" from configuration`, ); - logger.debug(`Projects: ${directories.join(', ')}`); + logDebug(`Projects: ${directories.join(', ')}`); return directories.toSorted().map(directory => ({ name: directory, @@ -132,8 +132,8 @@ async function listProjectsByNpmPackages(args: { const packages = await listPackages(cwd); - logger.info(`Found ${packages.length} NPM packages in repository`); - logger.debug(`Projects: ${packages.map(({ name }) => name).join(', ')}`); + logInfo(`Found ${packages.length} NPM packages in repository`); + logDebug(`Projects: ${packages.map(({ name }) => name).join(', ')}`); return packages.map(({ name, directory }) => ({ name, diff --git a/packages/ci/src/lib/output-files.ts b/packages/ci/src/lib/output-files.ts index f77710fb4..81dc3a8ca 100644 --- a/packages/ci/src/lib/output-files.ts +++ b/packages/ci/src/lib/output-files.ts @@ -1,7 +1,8 @@ import { copyFile, mkdir } from 'node:fs/promises'; import path from 'node:path'; import { DEFAULT_PERSIST_FILENAME, type Format } from '@code-pushup/models'; -import { logger, objectFromEntries, objectToKeys } from '@code-pushup/utils'; +import { objectFromEntries, objectToKeys } from '@code-pushup/utils'; +import { logDebug } from './log.js'; import type { OutputFiles, Settings } from './models.js'; import type { ProjectConfig } from './monorepo/tools.js'; @@ -45,7 +46,7 @@ export async function saveOutputFiles>({ const src = files[format]!; const dest = outputs[format]; await copyFile(src, dest); - logger.debug(`Copied ${type} report from ${src} to ${dest}`); + logDebug(`Copied ${type} report from ${src} to ${dest}`); }), ); diff --git a/packages/ci/src/lib/output-files.unit.test.ts b/packages/ci/src/lib/output-files.unit.test.ts index d00c725d1..fa1f63b58 100644 --- a/packages/ci/src/lib/output-files.unit.test.ts +++ b/packages/ci/src/lib/output-files.unit.test.ts @@ -1,3 +1,4 @@ +import ansis from 'ansis'; import { vol } from 'memfs'; import { readFile } from 'node:fs/promises'; import path from 'node:path'; @@ -120,10 +121,10 @@ describe('saveOutputFiles', () => { }); expect(logger.debug).toHaveBeenCalledWith( - `Copied current report from ${path.join(MEMFS_VOLUME, 'report.json')} to ${path.join(MEMFS_VOLUME, '.code-pushup/.ci/.current/report.json')}`, + `${ansis.bold.blue('<✓>')} Copied current report from ${path.join(MEMFS_VOLUME, 'report.json')} to ${path.join(MEMFS_VOLUME, '.code-pushup/.ci/.current/report.json')}\n`, ); expect(logger.debug).toHaveBeenCalledWith( - `Copied current report from ${path.join(MEMFS_VOLUME, 'report.md')} to ${path.join(MEMFS_VOLUME, '.code-pushup/.ci/.current/report.md')}`, + `${ansis.bold.blue('<✓>')} Copied current report from ${path.join(MEMFS_VOLUME, 'report.md')} to ${path.join(MEMFS_VOLUME, '.code-pushup/.ci/.current/report.md')}\n`, ); }); diff --git a/packages/ci/src/lib/run-monorepo.ts b/packages/ci/src/lib/run-monorepo.ts index f3fd83a06..bf3cb0f50 100644 --- a/packages/ci/src/lib/run-monorepo.ts +++ b/packages/ci/src/lib/run-monorepo.ts @@ -4,7 +4,6 @@ import { type ExcludeNullableProps, asyncSequential, hasNoNullableProps, - logger, } from '@code-pushup/utils'; import { type CommandContext, @@ -16,6 +15,7 @@ import { runMergeDiffs, } from './cli/index.js'; import { commentOnPR } from './comment.js'; +import { logDebug, logInfo } from './log.js'; import type { GitBranch, MonorepoRunResult, @@ -52,7 +52,7 @@ export async function runInMonorepoMode( ): Promise { const { api, settings } = env; - logger.info('Running Code PushUp in monorepo mode'); + logInfo('Running Code PushUp in monorepo mode'); const { projects, runManyCommand } = await listMonorepoProjects(settings); const projectResults = runManyCommand @@ -71,7 +71,7 @@ export async function runInMonorepoMode( diffJsonPaths, createCommandContext(settings, projects[0]), ); - logger.debug(`Merged ${diffJsonPaths.length} diffs into ${tmpDiffPath}`); + logDebug(`Merged ${diffJsonPaths.length} diffs into ${tmpDiffPath}`); const { md: diffPath } = await saveOutputFiles({ project: null, type: 'comparison', @@ -105,7 +105,7 @@ function runProjectsIndividually( projects: ProjectConfig[], env: RunEnv, ): Promise { - logger.info(`Running on ${projects.length} projects individually`); + logInfo(`Running on ${projects.length} projects individually`); return asyncSequential(projects, project => runOnProject(project, env)); } @@ -119,7 +119,7 @@ async function runProjectsInBulk( settings, } = env; - logger.info( + logInfo( `Running on ${projects.length} projects in bulk (parallel: ${settings.parallel})`, ); @@ -173,7 +173,7 @@ async function loadProjectEnvs( const hasFormats = allProjectsHaveDefaultPersistFormats(projectEnvs); - logger.debug( + logDebug( [ configPatterns ? `Parsed ${projectEnvs.length} persist and upload configs by interpolating configPatterns option for each project.` @@ -211,7 +211,7 @@ async function compareProjectsInBulk( const uncachedProjectReports = projectReportsWithCache.filter( ({ prevReport }) => !prevReport, ); - logger.info( + logInfo( `${currProjectReports.length - uncachedProjectReports.length} out of ${currProjectReports.length} projects loaded previous report from artifact cache`, ); @@ -314,10 +314,10 @@ async function collectPreviousReports( .map(({ project }) => project.name) .filter(name => !onlyProjects.includes(name)); if (invalidProjects.length > 0) { - logger.debug( + logDebug( `Printing config failed for ${invalidProjects.length} projects - ${invalidProjects.join(', ')}`, ); - logger.info( + logInfo( `Skipping ${invalidProjects.length} projects which aren't configured in base branch ${base.ref}`, ); } @@ -325,7 +325,7 @@ async function collectPreviousReports( if (onlyProjects.length > 0) { const hasFormats = allProjectsHaveDefaultPersistFormats(validProjectConfigs); - logger.info( + logInfo( `Collecting previous reports for ${onlyProjects.length} projects`, ); await collectMany(runManyCommand, env, { hasFormats, onlyProjects }); @@ -377,7 +377,7 @@ async function collectMany( const countText = onlyProjects ? `${onlyProjects.length} previous` : 'all current'; - logger.debug(`Collected ${countText} reports using command \`${command}\``); + logDebug(`Collected ${countText} reports using command \`${command}\``); } async function compareMany( @@ -397,7 +397,7 @@ async function compareMany( await runCompare(ctx, { hasFormats }); - logger.debug('Compared all project reports'); + logDebug('Compared all project reports'); } export function allProjectsHaveDefaultPersistFormats( diff --git a/packages/ci/src/lib/run-standalone.ts b/packages/ci/src/lib/run-standalone.ts index 9c49aa81f..c21de2a2a 100644 --- a/packages/ci/src/lib/run-standalone.ts +++ b/packages/ci/src/lib/run-standalone.ts @@ -1,5 +1,5 @@ -import { logger } from '@code-pushup/utils'; import { commentOnPR } from './comment.js'; +import { logInfo } from './log.js'; import type { StandaloneRunResult } from './models.js'; import { type RunEnv, runOnProject } from './run-utils.js'; @@ -8,7 +8,7 @@ export async function runInStandaloneMode( ): Promise { const { api, settings } = env; - logger.info('Running Code PushUp in standalone project mode'); + logInfo('Running Code PushUp in standalone project mode'); const { files, newIssues } = await runOnProject(null, env); diff --git a/packages/ci/src/lib/run-utils.ts b/packages/ci/src/lib/run-utils.ts index 000ca1883..de85d885a 100644 --- a/packages/ci/src/lib/run-utils.ts +++ b/packages/ci/src/lib/run-utils.ts @@ -13,7 +13,6 @@ import { type Diff, createReportPath, interpolate, - logger, objectFromEntries, readJsonFile, removeUndefinedAndEmptyProps, @@ -31,6 +30,7 @@ import { } from './cli/index.js'; import { listChangedFiles, normalizeGitRef } from './git.js'; import { type SourceFileIssue, filterRelevantIssues } from './issues.js'; +import { logDebug, logInfo, logWarning } from './log.js'; import type { ConfigPatterns, GitBranch, @@ -122,7 +122,7 @@ function sanitizeSearchCommits( searchCommits < MIN_SEARCH_COMMITS || searchCommits > MAX_SEARCH_COMMITS) ) { - logger.warn( + logWarning( `The searchCommits option must be a boolean or an integer in range ${MIN_SEARCH_COMMITS} to ${MAX_SEARCH_COMMITS}, ignoring invalid value ${searchCommits}.`, ); return undefined; @@ -143,13 +143,13 @@ export async function runOnProject( const ctx = createCommandContext(settings, project); if (project) { - logger.info(`Running Code PushUp on monorepo project ${project.name}`); + logInfo(`Running Code PushUp on monorepo project ${project.name}`); } const config = settings.configPatterns ? configFromPatterns(settings.configPatterns, project) : await printPersistConfig(ctx); - logger.debug( + logDebug( settings.configPatterns ? `Parsed persist and upload configs from configPatterns option - ${JSON.stringify(config)}` : `Loaded persist and upload configs from print-config command - ${JSON.stringify(config)}`, @@ -162,7 +162,7 @@ export async function runOnProject( files: persistedFilesFromConfig(config, ctx), settings, }); - logger.debug(`Collected current report at ${currReport.files.json}`); + logDebug(`Collected current report at ${currReport.files.json}`); const noDiffOutput = { name: projectToName(project), @@ -173,7 +173,7 @@ export async function runOnProject( return noDiffOutput; } - logger.info( + logInfo( `PR/MR detected, preparing to compare base branch ${base.ref} to head ${head.ref}`, ); @@ -196,7 +196,7 @@ export async function compareReports( await prepareReportFilesToCompare(args); await runCompare(ctx, { hasFormats: hasDefaultPersistFormats(config) }); - logger.info('Compared reports and generated diff files'); + logInfo('Compared reports and generated diff files'); const newIssues = settings.detectNewIssues ? await findNewIssues(args) @@ -241,7 +241,7 @@ export async function prepareReportFilesToCompare( ), ); - logger.debug( + logDebug( [ 'Prepared', project && `"${project.name}" project's`, @@ -331,7 +331,7 @@ export async function collectPreviousReport( files: persistedFilesFromConfig(config, ctx), settings, }); - logger.debug(`Collected previous report at ${report.files.json}`); + logDebug(`Collected previous report at ${report.files.json}`); return report; }); } @@ -374,15 +374,15 @@ async function loadCachedBaseReportFromArtifacts( const reportPath = await api .downloadReportArtifact(project?.name) .catch((error: unknown) => { - logger.warn( + logWarning( `Error when downloading previous report artifact, skipping - ${stringifyError(error)}`, ); return null; }); - logger.info(`Previous report artifact ${reportPath ? 'found' : 'not found'}`); + logInfo(`Previous report artifact ${reportPath ? 'found' : 'not found'}`); if (reportPath) { - logger.debug(`Previous report artifact downloaded to ${reportPath}`); + logDebug(`Previous report artifact downloaded to ${reportPath}`); } return reportPath; @@ -416,17 +416,17 @@ async function loadCachedBaseReportFromPortal( }), }, }).catch((error: unknown) => { - logger.warn( + logWarning( `Error when downloading previous report from portal, skipping - ${stringifyError(error)}`, ); return null; }); - logger.info( + logInfo( `Previous report ${reportPath ? 'found' : 'not found'} in Code PushUp portal`, ); if (reportPath) { - logger.debug(`Previous report downloaded from portal to ${reportPath}`); + logDebug(`Previous report downloaded from portal to ${reportPath}`); } return reportPath; @@ -441,12 +441,12 @@ export async function runInBaseBranch( await git.fetch('origin', base.ref, ['--depth=1']); await git.checkout(['-f', base.sha]); - logger.info(`Switched to base branch ${base.ref}`); + logInfo(`Switched to base branch ${base.ref}`); const result = await fn(); await git.checkout(['-f', '-']); - logger.info('Switched back to PR/MR branch'); + logInfo('Switched back to PR/MR branch'); return result; } @@ -461,13 +461,13 @@ export async function checkPrintConfig( : 'Executing print-config'; try { const config = await printPersistConfig(ctx); - logger.debug( + logDebug( `${operation} verified code-pushup installed in base branch ${base.ref}`, ); return config; } catch (error) { - logger.debug(`Error from print-config - ${stringifyError(error)}`); - logger.info( + logDebug(`Error from print-config - ${stringifyError(error)}`); + logInfo( `${operation} failed, assuming code-pushup not installed in base branch ${base.ref} and skipping comparison`, ); return null; @@ -548,7 +548,7 @@ export async function findNewIssues( reportsDiff: JSON.parse(reportsDiff) as ReportsDiff, changedFiles, }); - logger.debug( + logDebug( `Found ${issues.length} relevant issues for ${ Object.keys(changedFiles).length } changed files`,