Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s
102 lines
2.6 KiB
TypeScript
102 lines
2.6 KiB
TypeScript
import { danger } from 'danger';
|
|
|
|
const ordinalSuffix = (number: number) => {
|
|
const v = number % 100;
|
|
if (v === 11 || v === 12 || v === 13) {
|
|
return number + 'th';
|
|
}
|
|
const suffixes: Record<number, string> = { 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 runCongratulate = async () => {
|
|
const pullRequest = danger.github.pr;
|
|
const userName = pullRequest.user.login;
|
|
const teamMembers = [
|
|
'ady-beraud',
|
|
'AMoreaux',
|
|
'Bonapara',
|
|
'bosiraphael',
|
|
'charlesBochet',
|
|
'cyborch',
|
|
'dependabot',
|
|
'Devessier',
|
|
'emilienchvt',
|
|
'etiennejouan',
|
|
'FelixMalfait',
|
|
'Freebios',
|
|
'gitstart-app',
|
|
'gitstart-twenty',
|
|
'guillim',
|
|
'ijreilly',
|
|
'lucasbordeau',
|
|
'magrinj',
|
|
'martmull',
|
|
'nimraahmed',
|
|
'prastoin',
|
|
'Samox',
|
|
'thaisguigon',
|
|
'thomtrp',
|
|
'Weiko',
|
|
];
|
|
|
|
if (teamMembers.includes(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` +
|
|
``;
|
|
|
|
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();
|
|
}
|