Every developer strives to improve the speed and quality of coding, as well as formalizing processes and standards. Automation can help streamline these processes significantly, especially when it comes to reviewing pull requests—one of the most tiresome tasks in software development. When creating new functionality, many side nuances can arise: typos, new code could break something in the rest of the code base, unused resources may appear after refactoring, etc.
The good news is that it’s possible to automate most of these things. In this article, we will take a closer look at pull request automation and explore beyond a set of commands that can automate any project, and focus on a set of tools that you can customize to your needs.
In software development, creating pull requests is a crucial part of the collaborative coding process. In a nutshell, a pull request is a request made by a developer to merge their changes into the main branch of a codebase. Pull requests typically contain a summary of the changes made and any relevant details, such as new features or bug fixes. They also include a comparison of the differences between the modified code and the original code. A well-composed pull request has a distinctive set of characteristics, which you can find below.
It's quite difficult to check very large pull requests, especially when you don't fully understand the context of the task. As the number of changes in the pull request increases, it gets harder to maintain focus and keep everything in mind, so the pull request must be limited in size.
No one wants to check minor errors or bugs that can be easily analyzed by off-the-shelf tools. In Android, we can write our own code review rules and use ready-made ones, customize the style of writing code and check how it is supported, etc. These errors need to be highlighted in the pull request, and new errors can be identified and addressed through the automated static code analysis process..
For quality control purposes, we need to be able to see who worked on which tickets and exactly what was done. A good strategy to ensure quality control is to fail a ticket if the pull request has no description, and add the ticket number and its title in the header. Ideally, screenshots should also be included to make the changes visible.
When running tests to check the code, and changes in the code "break" the tests, then obviously, such a pull request is not yet ready for review. It should be made impossible to merge such code.
When reviewing a pull request, it should be made very easy to track the sequence of the author’s actions when they create atomic commits by adding clear messages to them.
If you have a large project with several teams working on it, code should be divided into areas of responsibility. If you make changes in a neighboring team's repository, it should be impossible to merge them without the approval of that team.
Before submitting a pull request for review, the author should make sure that they haven’t forgotten anything and have completed all the necessary preparatory steps. For this purpose, a list with checkboxes, where the author can mark the actions they have performed, is crucial. Then the reviewer will see that the pull request is ready for review.
Now that you are familiar with the key pull request guidelines, let’s consider automation tools that are definitely worth checking.
Danger helps automate routine tasks in the CI process. It is easy to customize and has many plugins that work with popular tools. You can also write your own if you need to. For example, here's a set of ready-made plugins for review. Danger can also be integrated into GitHub Actions, and the results can be sent to a pull request using a bot.
For example, let's solve a few of the problems we described above:
If using Danger/Ruby, the two main files you need are Gemfile and Dangerfile.
In the Gemfile, you add the danger plugins that you plan to use, for example, danger-junit, danger-android_lint, etc.
It will look something like this:
In the Dangerfile, you write a script using Ruby DSL, utilizing the Danger plugins that you specified in the Gemfile.
With a few lines in the Dangerfile, we can check if the pull request is not too large and if it has a description.
To check the test results, install the JUnit Danger plugin. It parses reports of unit test execution. You can format them as you like and put them in your pull request.
This project has several modules, so it requires the creation of a directory traversal pattern and using the parse & report methods:
In fact, this is the most basic configuration, and the plugin itself is capable of much more.
We can also configure Android Lint, which will analyze the code and display the results.
This is what the result will look like:
Again, this was done with minimal configuration:
The idea is the same—we use Lint, which puts the results of its observations into a folder, which we then parse and display the results using Danger.
We can easily integrate Danger with GitHub Actions to create a similar workflow:
Before starting with Danger, you will need to run the ./gradlew test and ./gradlew runChecksForDanger commands. The former generates unit test reports, and the latter generates linter reports. They are needed for Danger to parse them and display the results on the screen.
It’s also essential to add a token so that the bot can display the results of Danger's work in your pull request.
In order to make commit messages easy to read, adhering to the Conventional Commits specification is recommended. The Conventional Commits specification is a simple guideline for crafting commit messages, designed to facilitate a clear and structured commit history. It offers a lightweight set of rules that enable the development of automated tools built upon it.
This convention seamlessly aligns with SemVer (Semantic Versioning) by outlining the features, fixes, and breaking changes conveyed within commit messages. By adhering to this specification, it becomes easier to automate processes and build tools that can analyze and extract information from commit histories.
The idea is that each commit should contain the type of commit, the scopes it belongs to, and a brief description. It also defines the formatting requirements for such messages for readability. If you, like me, use IntelliJ IDEA or Android Studio, the good news is that there is a ready-made plugin that will highlight errors in the structure and formatting of commit messages.
It also has a handy Wizard where you simply enter values into the input fields and it formats the code for you.
This is a critical part of the pull request process where you can customize rules for different branches in your git repository. Particularly important are the settings related to pull requests. This allows you to create a set of rules that will prohibit code from being merged into crucial repository branches until it meets all predefined requirements.
If you have a fairly large project and several teams are working on it at the same time, it is likely that each of them has their own area of responsibility. Therefore, to ensure that the review is done by the people who are responsible for the component that changes are made to, setting up Code Owners is recommended. This is a file that contains users or groups of users who are responsible for certain parts of the system. Also, in branch protection rules, you can set mandatory code review by Code Owners:
We can set, for example, 2 mandatory approvals and tick the box next to Require review from Code Owners.
Before reviewing a pull request, authors should first check it themselves. To do this, you need to make a list of preparatory actions that everyone who creates a pull request should perform. You can find many examples of such checklists on Google. You need to choose what is important to you and your project. Here's a list from a demo project, for example:
The template for such a checklist is written with Markdown. Here is an example:
You can install an application from the marketplace that will check whether all the checkboxes are checked and display the status of checklist completion. If all conditions are not met, it will change its color from green to gray:
As soon as all the conditions from the checklist are met, the button will turn green:
In fact, it doesn't have to be a checklist. Often, question-and-answer or mixed format templates are used:
Don’t hesitate to use the pull request automation tips listed above to enhance your productivity and speed up your software development process. You will be able to easily identify and fix errors, ensuring that code changes meet your standards and best practices. With that, your team can save valuable time and focus on other important tasks, while maintaining the quality of your code.
In this article, we explored the importance of automating pull request reviews for developers, and provided tips on how to do it in the most efficient way. Firstly, it can provide a more objective evaluation of the code, avoiding any potential biases that may arise during manual reviews. Secondly, it can reduce the risk of errors and inconsistencies in the codebase, ensuring that high-quality code is produced. Thirdly, automated reviews can detect common code errors and provide feedback to developers, improving the overall code quality. With all this in mind, you should be able to make the most out of pull request automation.