Skip to content

Commit

Permalink
feat(ci): move in code for posting comment, generalized to any provider
Browse files Browse the repository at this point in the history
  • Loading branch information
matejchalk committed Oct 15, 2024
1 parent d81b3ac commit b61d674
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 28 deletions.
47 changes: 47 additions & 0 deletions packages/ci/src/lib/comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import fs from 'node:fs/promises';
import type { Logger, ProviderAPIClient } from './models';

export async function commentOnPR(
mdPath: string,
api: ProviderAPIClient,
logger: Logger,
): Promise<number> {
const markdown = await fs.readFile(mdPath, 'utf8');
const identifier = `<!-- generated by code-pushup/github-action -->`;
const body = truncateBody(
`${markdown}\n\n${identifier}\n`,
api.maxCommentChars,
logger,
);

const comments = await api.listComments();
logger.debug(`Fetched ${comments.length} comments for pull request`);

const prevComment = comments.find(comment =>
comment.body.includes(identifier),
);
logger.debug(
prevComment
? `Found previous comment ${prevComment.id} from Code PushUp`
: 'Previous Code PushUp comment not found',
);

if (prevComment) {
const updatedComment = await api.updateComment(prevComment.id, body);
logger.debug(`Updated body of comment ${updatedComment.url}`);
return updatedComment.id;
}

const createdComment = await api.createComment(body);
logger.debug(`Created new comment ${createdComment.url}`);
return createdComment.id;
}

function truncateBody(body: string, max: number, logger: Logger): string {
const truncateWarning = '...*[Comment body truncated]*';
if (body.length > max) {
logger.warn(`Comment body is too long. Truncating to ${max} characters.`);
return body.slice(0, max - truncateWarning.length) + truncateWarning;
}
return body;
}
13 changes: 10 additions & 3 deletions packages/ci/src/lib/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,17 @@ export type GitRefs = {
};

export type ProviderAPIClient = {
maxCommentChars: number;
downloadReportArtifact: () => Promise<string>;
fetchComments: () => Promise<{ id: number; body: string }[]>;
updateComment: (id: number, body: string) => Promise<void>;
createComment: (body: string) => Promise<void>;
listComments: () => Promise<Comment[]>;
updateComment: (id: number, body: string) => Promise<Comment>;
createComment: (body: string) => Promise<Comment>;
};

export type Comment = {
id: number;
body: string;
url: string;
};

export type GitBranch = {
Expand Down
81 changes: 56 additions & 25 deletions packages/ci/src/lib/monorepo/list-projects.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { glob } from 'glob';
import { join } from 'node:path';
import type { Settings } from '../models';
import type { Logger, Settings } from '../models';
import { detectMonorepoTool } from './detect-tool';
import { getToolHandler } from './handlers';
import { listPackages } from './packages';
import type { MonorepoHandlerOptions, ProjectConfig } from './tools';

// eslint-disable-next-line max-lines-per-function
export async function listMonorepoProjects(
settings: Settings,
): Promise<ProjectConfig[]> {
Expand Down Expand Up @@ -41,33 +40,19 @@ export async function listMonorepoProjects(
}

if (settings.projects) {
const directories = await glob(
settings.projects.map(path => path.replace(/\/$/, '/')),
{ cwd: options.cwd },
);
logger.info(
`Found ${
directories.length
} project folders matching "${settings.projects.join(
', ',
)}" from configuration`,
);
logger.debug(`Projects: ${directories.join(', ')}`);
return directories.toSorted().map(directory => ({
name: directory,
return listProjectsByGlobs({
patterns: settings.projects,
cwd: options.cwd,
bin: settings.bin,
directory: join(options.cwd, directory),
}));
logger,
});
}

const packages = await listPackages(options.cwd);
logger.info(`Found ${packages.length} NPM packages in repository`);
logger.debug(`Projects: ${packages.map(({ name }) => name).join(', ')}`);
return packages.map(({ name, directory }) => ({
name,
return listProjectsByNpmPackages({
cwd: options.cwd,
bin: settings.bin,
directory,
}));
logger,
});
}

function createMonorepoHandlerOptions(
Expand All @@ -88,3 +73,49 @@ function createMonorepoHandlerOptions(
}),
};
}

async function listProjectsByGlobs(args: {
patterns: string[];
cwd: string;
bin: string;
logger: Logger;
}): Promise<ProjectConfig[]> {
const { patterns, cwd, bin, logger } = args;

const directories = await glob(
patterns.map(path => path.replace(/\/$/, '/')),
{ cwd },
);

logger.info(
`Found ${directories.length} project folders matching "${patterns.join(
', ',
)}" from configuration`,
);
logger.debug(`Projects: ${directories.join(', ')}`);

return directories.toSorted().map(directory => ({
name: directory,
bin,
directory: join(cwd, directory),
}));
}

async function listProjectsByNpmPackages(args: {
cwd: string;
bin: string;
logger: Logger;
}): Promise<ProjectConfig[]> {
const { cwd, bin, logger } = args;

const packages = await listPackages(cwd);

logger.info(`Found ${packages.length} NPM packages in repository`);
logger.debug(`Projects: ${packages.map(({ name }) => name).join(', ')}`);

return packages.map(({ name, directory }) => ({
name,
bin,
directory,
}));
}

0 comments on commit b61d674

Please sign in to comment.