axios-axios/bin/RepoBot.js
Jay ef3711d1b3
feat: implement prettier and fix all issues (#7385)
* feat: implement prettier and fix all issues

* fix: failing tests

* fix: implement feedback from codel, ai etc

* chore: dont throw in trim function

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix: incorrect fix

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-02-14 16:59:48 +02:00

135 lines
3.2 KiB
JavaScript

import GithubAPI from './GithubAPI.js';
import api from './api.js';
import Handlebars from 'handlebars';
import fs from 'fs/promises';
import { colorize } from './helpers/colorize.js';
import { getReleaseInfo } from './contributors.js';
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const NOTIFY_PR_TEMPLATE = path.resolve(__dirname, '../templates/pr_published.hbs');
const normalizeTag = (tag) => (tag ? 'v' + tag.replace(/^v/, '') : '');
const GITHUB_BOT_LOGIN = 'github-actions[bot]';
const skipCollaboratorPRs = true;
class RepoBot {
constructor(options) {
const { owner, repo, templates } = options || {};
this.templates = {
published: NOTIFY_PR_TEMPLATE,
...templates,
};
this.github = api || new GithubAPI(owner, repo);
this.owner = this.github.owner;
this.repo = this.github.repo;
}
async addComment(targetId, message) {
return this.github.createComment(targetId, message);
}
async notifyPRPublished(id, tag) {
let pr;
try {
pr = await this.github.getPR(id);
} catch (err) {
if (err.response?.status === 404) {
throw new Error(`PR #${id} not found (404)`);
}
throw err;
}
tag = normalizeTag(tag);
const {
merged,
labels,
user: { login, type },
} = pr;
const isBot = type === 'Bot';
if (!merged) {
return false;
}
await this.github.appendLabels(id, [tag]);
if (
isBot ||
labels.find(({ name }) => name === 'automated pr') ||
(skipCollaboratorPRs && (await this.github.isCollaborator(login)))
) {
return false;
}
const comments = await this.github.getComments(id, { desc: true });
const comment = comments.find(
({ body, user }) => user.login === GITHUB_BOT_LOGIN && body.indexOf('published in') >= 0
);
if (comment) {
console.log(colorize()`Release comment [${comment.html_url}] already exists in #${pr.id}`);
return false;
}
const author = await this.github.getUser(login);
author.isBot = isBot;
const message = await this.constructor.renderTemplate(this.templates.published, {
id,
author,
release: {
tag,
url: `https://github.com/${this.owner}/${this.repo}/releases/tag/${tag}`,
},
});
return await this.addComment(id, message);
}
async notifyPublishedPRs(tag) {
tag = normalizeTag(tag);
const release = await getReleaseInfo(tag);
if (!release) {
throw Error(colorize()`Can't get release info for ${tag}`);
}
const { merges } = release;
console.log(colorize()`Found ${merges.length} PRs in ${tag}:`);
let i = 0;
for (const pr of merges) {
try {
console.log(colorize()`${i++}) Notify PR #${pr.id}`);
const result = await this.notifyPRPublished(pr.id, tag);
console.log('✔️', result ? 'Label, comment' : 'Label');
} catch (err) {
console.warn(colorize('green', 'red')`❌ Failed notify PR ${pr.id}: ${err.message}`);
}
}
}
static async renderTemplate(template, data) {
return Handlebars.compile(String(await fs.readFile(template)))(data);
}
}
export default RepoBot;