Create congratulations bot (#5404)

- Created congratulations bot :
<img width="939" alt="Screenshot 2024-05-14 at 12 47 13"
src="https://github.com/twentyhq/twenty/assets/102751374/5138515f-fe4d-4c6d-9c7a-0240accbfca9">

- Modified OG image

- Added png extension to OG image route

To be noted: The bot will not work until the new API route is not
deployed. Please check OG image with Cloudflare cache.

---------

Co-authored-by: Ady Beraud <a.beraud96@gmail.com>
This commit is contained in:
Ady Beraud
2024-05-21 23:56:25 +03:00
committed by GitHub
parent 3deda2f29a
commit 5ad59b5845
17 changed files with 277 additions and 73 deletions

View File

@ -0,0 +1,109 @@
import { danger } from 'danger';
const ordinalSuffix = (number) => {
const v = number % 100;
if (v === 11 || v === 12 || v === 13) {
return number + 'th';
}
const suffixes = { 1: 'st', 2: 'nd', 3: 'rd' };
return number + (suffixes[v % 10] || 'th');
};
const fetchContributorStats = async (username: string) => {
const apiUrl = `https://twenty.com/api/contributors/contributorStats/${username}`;
const response = await fetch(apiUrl);
const data = await response.json();
return data;
};
const fetchContributorImage = async (username: string) => {
const apiUrl = `https://twenty.com/api/contributors/${username}/og.png`;
await fetch(apiUrl);
};
const getTeamMembers = async () => {
const org = 'twentyhq';
const team_slug = 'core-team';
const response = await danger.github.api.teams.listMembersInOrg({
org,
team_slug,
});
return response.data.map((user) => user.login);
};
const runCongratulate = async () => {
const pullRequest = danger.github.pr;
const userName = pullRequest.user.login;
const staticExcludedUsers = [
'dependabot',
'cyborch',
'emilienchvt',
'Samox',
'charlesBochet',
'gitstart-app',
'thaisguigon',
'lucasbordeau',
'magrinj',
'Weiko',
'gitstart-twenty',
'bosiraphael',
'martmull',
'FelixMalfait',
'thomtrp',
'Bonapara',
'nimraahmed',
'ady-beraud',
];
const teamMembers = await getTeamMembers();
const excludedUsers = new Set([...staticExcludedUsers, ...teamMembers]);
if (excludedUsers.has(userName)) {
return;
}
const { data: pullRequests } =
await danger.github.api.rest.search.issuesAndPullRequests({
q: `is:pr author:${userName} is:closed repo:twentyhq/twenty`,
per_page: 2,
page: 1,
});
const isFirstPR = pullRequests.total_count === 1;
if (isFirstPR) {
return;
}
const stats = await fetchContributorStats(userName);
const contributorUrl = `https://twenty.com/contributors/${userName}`;
// Pre-fetch to trigger cloudflare cache
await fetchContributorImage(userName);
const message =
`Thanks @${userName} for your contribution!\n` +
`This marks your **${ordinalSuffix(
stats.mergedPRsCount,
)}** PR on the repo. ` +
`You're **top ${stats.rank}%** of all our contributors 🎉\n` +
`[See contributor page](${contributorUrl}) - ` +
`[Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=${contributorUrl}) - ` +
`[Share on Twitter](https://www.twitter.com/share?url=${contributorUrl})\n\n` +
`![Contributions](https://twenty.com/api/contributors/${userName}/og.png)`;
await danger.github.api.rest.issues.createComment({
owner: danger.github.thisPR.owner,
repo: danger.github.thisPR.repo,
issue_number: danger.github.thisPR.pull_number,
body: message,
});
};
if (danger.github && danger.github.pr.merged) {
runCongratulate();
}

View File

@ -4,6 +4,7 @@
"scripts": {
"nx": "NX_DEFAULT_PROJECT=twenty-front node ../../node_modules/nx/bin/nx.js",
"danger:ci": "danger ci --use-github-checks --failOnErrors",
"danger:congratulate": "danger ci --dangerfile ./congratulate-dangerfile.ts --use-github-checks --failOnErrors",
"release": "node release.js"
}
}