DEV Community

Petar Garžina
Petar Garžina

Posted on

5 tools to automate your development

Automating your development with Dependabot, Auto Assign, Merge Freeze, Husky and Scheduled reminders.

The idea of this post is to introduce some of the tools and integrations that made our development life easier.

Most of these are pretty straightforward to implement into your workflow but for the ones that have a couple of gotchas I might write an extended introductory version for that tool alone.

1. Dependabot

Automated dependency updates

Dependabot creates pull requests to keep your dependencies secure and up-to-date.

Dependabot is dead simple and their punchline clearly states what it does. We started using it a couple of years back, a bit before Github acquired it.

The main reason was that, at the time our current team took over the Front End division, there were a lot of outdated dependencies which we wanted to update and wanted to keep up to date. We found Dependabot, added it to our projects, and let it do its magic ever since.

Now it's natively a part of Github, so adding it is even easier than before. You can check out how to set up Dependabot, but in the end you'll end up with a dependabot.yml in your .github folder.
Ours looks like this:

version: 2
updates:
  - package-ecosystem: "npm" # See documentation for possible values
    directory: "/" # Location of package manifests
    schedule:
      interval: "daily"
    open-pull-requests-limit: 2
    commit-message:
       prefix: "BleedingEdge"
Enter fullscreen mode Exit fullscreen mode

The only thing that differs from the default settings is that we:

  • chose npm as our package-ecosystem
  • limited the number of open PRs to 2
  • added a prefix for the default Dependabots commit message (you'll see later why)

Four years back we had 3 frontend repos, now we have around 14 active ones. Manually keeping every dependency up to date would be extremely time consuming. Dependabot helps a lot, but it still takes time to review and merge all the PR's. We usually take a day, after our weekly release, to merge Dependabots pull requests.

Writing this got me wondering if we could set the bot to open PR's only on major, minor or patch versions and indeed the feature was requested in 2018 and got released a few months ago and now you can ignore SemVer updates of your choice. Check out GitHub's blog post for more.

2. Auto Assign

Add reviewers/assignees to pull requests when pull requests are opened.

So you opened a pull request, you need at least two approvals and you need to add reviewers to your pull request. Every single time.

Things are pretty obvious, let the bot do it.

Setting up is easy, go to probot.github.io/apps/auto-assign hit the Add to Github button and don't ever worry about manually adding reviewers!
Similar to Dependabot, you will end up with a auto_assing.yml file:

# Set to true to add reviewers to pull requests
addReviewers: true

# Set to true to add assignees to pull requests
addAssignees: false

# A list of reviewers to be added to pull requests (GitHub user name)
reviewers:
  - teammember1
  - teammember2
  - teammember3
  - ...


# A number of reviewers added to the pull request
# Set 0 to add all the reviewers (default: 0)
numberOfReviewers: 0

# A list of keywords to be skipped the process that add reviewers if pull requests include it
skipKeywords:
  - BleedingEdge

Enter fullscreen mode Exit fullscreen mode

We have nothing out of the ordinary here. We are utilizing the skipKeywords option with the BleedingEdge keyword that if you remember Dependabot prefixes to each of its pull requests. We handle the pull requests Dependabot opens a little bit differently and don't want to burden all the reviewers with them.

Once the Pull request is opened the bot kicks in and you see it in the timeline requesting reviews:
Auto assign bot

You can also try and use the default settings Github provides for Code Review Assignments. Just go to your team page, in the top right hit Settings and you'll find the Code review assignments tab. We tried it but it didn't work out for us.

3. Merge Freeze

The code freeze tool to block merging and deployments

The reason for adding merge freeze originated from a simple question:

Can you tell all the developers to stop merging since we are starting regression?

We could announce it in our team's channel in hopes that everyone reads the message in time. Or we could integrate a tool that allows the QA team to issue a command on Slack that freezes/unfreezes merging to the repository. Merge Freeze to the rescue.

Again, setting up, nothing too complex. What we did find Merge Freeze is missing is the ability to bulk freeze. It worked well when we needed to freeze a couple of repos. But once the number of our repositories increased to over 10, manually entering the command more than 10 times... you get it.

For this we used Slack Apps and AWS Lambda.

We created a custom Slack App for our workspace called Deployment, that has two Slash commands: /freeze_all and /unfreeze_all. Both commands have the Request URL set to our Lambda url, and pass the freeze value as a query parameter: ?freeze=true | false.

Using it on Slack looks like this:

Slack Freeze command

The Merge Freeze tool exposes an API endpoint for each repository you add to it, which you can use to freeze or unfreeze it. That makes the Lambda rather simple, it just makes a POST request to each of the endpoints provided by MergeFreeze.

const https = require('https');

exports.handler = async (event) => {

  const freezeValue = getFreezeValue(event);
  if (!freezeValue) {
    return {
      statusCode: 400,
      body: JSON.stringify('BOOM! You need to provide a freeze value as a query param, either true or false'),
    };
  }

  const userName = getUserName(event)

  const baseOptions = {
    hostname: 'mergefreeze.com',
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Content-Length': 0,
    },
  };

  const appOneOptions = {
    path: `/api/branches/your-organization/your-repo/main/?access_token=${process.env.ACCESS_TOKEN}&frozen=${freezeValue}&user_name=${userName}`,
    ...baseOptions,
  };
  ...
  /** Removed the rest of declaration to keep the preview short */


  await Promise.all([
    doRequest(appOneOptions),
    ...
    doRequest(appElevenOptions),
  ]);

  console.log("I'm done with all your promises!");

  // Text that gets return to Slack that is only visible to the person entering the command
  return {
    statusCode: 200,
    body: JSON.stringify('You have such power!!!'),
  };

  function doRequest(options) {
    return new Promise((resolve, reject) => {
      const req = https.request(options, (res) => {
        res.setEncoding('utf8');
        let responseBody = '';
        res.on('data', (chunk) => responseBody += chunk);
        res.on('end', () => resolve(responseBody));
      });

      req.on('error', (err) => reject(err));
      req.end();
    });
  }

  function getFreezeValue(event) {
    let freezeQueryString;
    let freeze;

    if (event && event.queryStringParameters && event.queryStringParameters.freeze) {
      freezeQueryString = event.queryStringParameters.freeze;
    }

    if (freezeQueryString === 'true' || freezeQueryString === 'false') {
        freeze = freezeQueryString;
    }

    return freeze;
  }

  function getUserName(event) {
    const bodyQueryParams = new URLSearchParams(event.body);
    return bodyQueryParams.get('user_name') || 'Web API';     
  }
};
Enter fullscreen mode Exit fullscreen mode

After entering the command, MergeFreeze lists all the repos that got frozen or unfrozen and you get a confirmation message from Slack, making your work day a bit better!

Much Power

After the regression is done, everything is pushed to Production and is smoke tested, the lead QA issues the unfreeze_all command and life goes on.

4. Husky

Modern native Git hooks made easy

We use Jira as our work management tool so we have to prepend the ticket ID to our branch names and commit messages in order to utilize both the Development panel when viewing an issue and VSCodes extension GitLens:

Jira ticket Development panel:
Jira Development Panel

This means that each time you create a branch you have to remember to include the Jira issue ID, eg: task-ND-123-add-authentication. That alone was not a big deal as it quickly became a habit. But what was a PIA was prepending it to every commit message. The 1st automation round was just setting up the git prepare-commit-message hook on your local machine, but as the team grew larger we needed a better solution which Husky provided!

Husky in combination with jira-prepare-commit-msg is what worked for us:

...
  "private": true,
  "husky": {
    "hooks": {
      "prepare-commit-msg": "jira-prepare-commit-msg"
    }
  },
  "jira-prepare-commit-msg": {
    "messagePattern": "$J $M",
    "jiraTicketPattern": "(\\w+-\\w+-\\d+)"
  },
  "dependencies": {
...
  "devDependencies": {
    "husky": "^4.3.8",
    "jira-prepare-commit-msg": "^1.5.2",
...
Enter fullscreen mode Exit fullscreen mode

The JIRA ticket ID is taken from a git branch name. Now you could just write commit -m "Fixing a typo" and you would get a commit message looking like task-ND-123-Fixing a typo.

In case you did not name your branch correctly eg: missing Jira ticket ID you would get an error:

my-application git:(main) ✗ git commit -m "Add authentication methods"
husky > prepare-commit-msg (node v14.15.0)
JIRA prepare commit msg > start
JIRA prepare commit msg > Error: The JIRA ticket ID not found
JIRA prepare commit msg > done
Enter fullscreen mode Exit fullscreen mode

This came in nicely as everything was set up in package.json and a new developer would do npm i and she/he is pretty much set, no need to manually configure hooks.

But the Jira Ticket ID in the commit message in combination with GitLens is what really made this super useful.

GitLens with Git blame annotations:
Visual Studio Code and GitLens

There were a lot of times where we had to, for various reasons, open up and read the Jira issue associated with the code change. Having the ticket ID at each mouse click throughout the codebase saved us a lot of time. (opening it in the browser is easy as well, just take the Jira ID and add it after .../browse/ + ND-123 e.g., https://your-organization.atlassian.net/browse/ND-123)

GitLens is a cool tool which I personally use on a daily basis. It helps you to visualize code authorship at a glance via Git blame annotations and code lens. You can also very easily navigate back in history to see past commits which is useful as well.

5. Scheduled reminders for Pull Requests

Scheduled reminders help teams focus on the most important review requests

This is something we added not too long ago, just a bit after we moved to Micro Frontend Architecture. One of the reasons for adding it was that the number of repositories increased from 4 to 14 so having a dedicated channel for open pull requests made sense. Prior to this we would post a link of the PR in our team's main channel, or would hope people would see it in their email. This way we moved the noise to a dedicated channel, and the devs know the team will get automatically notified.

GitHub Scheduled Reminders

We get notifications on every working day each full hour from 8-16. It ignores approved pull requests (in our case when 2+ ppl approved it) and we also have ignore terms for BleedingEdge so it ignores pull requests opened by Dependabot.

Setting up scheduled reminders is straightforward and you can find the github docs here. This is how it looks like once its up, in our case it posts messages in a private frontend-pull-requests channel:

FrontEnd Pull Requests

...

There are a lot of improvements that we could include on top of what we have, like creating branches directly from Jira would ease up on having to remember the naming convention. Or maybe we could have chosen a merge freeze tool that has bulk freeze built in. But usually we had limited time for investigation, or it was good enough at that time, and later on we just tried to improve the process instead of replacing the tool.
If you have any suggestions, please do post them in the discussion below!


Feel free to connect 👋

Twitter | Instagram | LinkedIn

Discussion (7)

Collapse
mikenikles profile image
Mike Nikles

Also remember to automate your development environment with gitpod.io so you never have to check out any of your code locally or change branches or stash changes etc.

Collapse
pgarzina profile image
Petar Garžina Author

thanks for the tip, I'll give it a try.

Collapse
luc1ja profile image
luc1ja

this is very helpful, thanks!

Collapse
peterwitham profile image
Peter Witham

Wonderful list, I was not aware of some of these and now intend to try them out. I do like the idea of the freeze and automated dependency updates. Thanks.

Collapse
pgarzina profile image
Petar Garžina Author

Thanks, appreciate the comment. The need for merge freeze depends on the project, team and how the deployment is done, but dependency updates I turn on on every project, even its only my small home project :)

Collapse
3ankur profile image
Ankur V

Very nice.
Thanks

Collapse
robertholovka profile image
RobertHolovka

Great post, keep up the good work.