Blog
`congratulate-dangerfile.ts` in Twenty, the #1 open-source CRM.

`congratulate-dangerfile.ts` in Twenty, the #1 open-source CRM.

In this article, we will review congratulate-dangerfile.ts in Twenty, the #1 open-source CRM. We will look at:

  1. What is danger?

  2. Running congratulate-dangerfile in a Github worflow.

  3. runCongratulate function

What is danger?

At line 1 in twenty/packages/twenty-utils/congratulate-dangerfile.ts, you will find the following import

import { danger } from 'danger';

Danger runs after your CI, automating your team’s conventions surrounding code review.

This provides another logical step in your process, through which Danger can help lint your rote tasks in daily code review.

You can use Danger to codify your team’s norms, leaving humans to think about harder problems.

Danger JS works with GitHub, BitBucket Server, BitBucket Cloud for code review.

For example?

You can:

  • Enforce CHANGELOGs

  • Enforce links to Trello/JIRA in PR/MR bodies

  • Enforce using descriptive labels

  • Look out for common anti-patterns

  • Highlight interesting build artifacts

  • Give warnings when specific files change

Danger provides the glue to let you build out the rules specific to your team’s culture, offering useful metadata and a comprehensive plugin system to share common issues.

Running congratulate-dangerfile in a Github workflow

When I searched for congratulate-danger in twenty codebase I found the following results

Script in package.json

You will find the following code in twenty/packages/twenty-utils/package.json

{
  "name": "twenty-utils",
  "private": true,
  "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"
  }
}

Here danger:congratulate is a script that executes this congratulate-dangerfile.ts as shown below:

"danger:congratulate": "danger ci --dangerfile ./congratulate-dangerfile.ts --use-github-checks --failOnErrors",

Job in wokflow

You will find the following code in twenty/.github/workflows/ci-utils.yaml

  congratulate:
    timeout-minutes: 3
    runs-on: ubuntu-latest
    if: github.event.action == 'closed' && github.event.pull_request.merged == true
    steps:
      - uses: actions/checkout@v4
      - name: Install dependencies
        uses: ./.github/workflows/actions/yarn-install
      - name: Run congratulate-dangerfile.js
        run: cd packages/twenty-utils && npx nx danger:congratulate
        env:
          DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Here this job has the name — “Run congratulate-dangerfile.js”

View Runs

This runs the following command

 cd packages/twenty-utils && npx nx danger:congratulate

This is basically calling the script that we just described above.

It is important to have the env defined as shown below as part of this job.

 env:
          DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}

runCongratulate function

runCongratulate function code can be found in twenty/packages/twenty-utils/congratulate-dangerfile.ts

This function mainly does two things:

  1. isFirstPR check

  2. create comment  

isFirstPr check

You will find the following code for the isFirstPR check:

  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;
  }

This above code is checking the pull request based on the user name and you can get the username using the following code:

  const userName = pullRequest.user.login;

createComment

You will find the following code for the createComment.

 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,
  });

What this code does is, it leaves a comment as show below:

About me

Hey, my name is Ramu Narasinga. I study codebase architecture in large open-source projects.

Email: ramu.narasinga@gmail.com

Build Shadcn CLI from scratch.

References:

  1. https://github.com/twentyhq/twenty/blob/main/packages/twenty-utils/congratulate-dangerfile.ts

  2. https://github.com/twentyhq/twenty/blob/3c5595e4ff48c49b257031c985bf6b0c40b09ca1/packages/twenty-utils/congratulate-dangerfile.ts#L1

  3. https://www.npmjs.com/package/danger

  4. https://github.com/search?q=repo%3Atwentyhq%2Ftwenty+congratulate-danger&type=code

  5. https://github.com/twentyhq/twenty/blob/3c5595e4ff48c49b257031c985bf6b0c40b09ca1/.github/workflows/ci-utils.yaml#L44

  6. https://github.com/twentyhq/twenty/blob/3c5595e4ff48c49b257031c985bf6b0c40b09ca1/packages/twenty-utils/package.json#L7

  7. https://github.com/twentyhq/twenty/blob/3c5595e4ff48c49b257031c985bf6b0c40b09ca1/packages/twenty-utils/congratulate-dangerfile.ts#L1

  8. https://github.com/twentyhq/twenty/pull/12882