Reviewbot assists you in rapidly establishing a self-hosted code analysis and review service, supporting multiple languages and coding standards. It is particularly suitable for organizations with numerous private repositories.
All issues are reported during the Pull Request stage, either as Review Comments
or Github Annotations
, precisely pinpointing the relevant code lines.
-
Github Check Run (Annotations)
-
Github Pull Request Review Comments
This approach helps PR authors avoid searching for issues in lengthy console logs, significantly facilitating problem resolution.
- Why Reviewbot
- Installation
- Supported Linters
- Configuration
- Reviewbot Operational Flow
- How to add a new Linter
- Monitoring Detection Results
- Contributing
- License
Reviewbot is a self-hosted code analysis and review service supporting multiple languages and coding standards. It is particularly beneficial for organizations with numerous private repositories:
- Security - Recommended self-hosting for data security and control
- Improvement-Oriented - Detected issues are primarily reported in the form of Review Comments or Github Annotations, facilitating efficient problem resolution and code improvement
- Flexibility - Supports multiple languages and coding standards, with easy integration of new code inspection tools
- Observability - Supports alert notifications for timely awareness of detected issues
- Configurable - Supports configuration of linter execution commands, parameters, and environments, providing flexibility for complex scenarios
Reviewbot is developed using Golang, featuring simple logic and clear code, making it easy to understand and maintain.
Please refer to the getting started guide.
The following are internal usage practices at Qiniu, which may provide you with more inspiration:
- Deployed in a Kubernetes cluster
- Using this Dockerfile to build the Reviewbot image
Reviewbot adheres to a zero-configuration principle whenever possible, with fixed code logic for general repository inspections. However, some special requirements can be met through configuration.
Note: All configurable items are defined in the config/config.go
file. Please refer to this file for detailed configuration options.
The following are some common configuration scenarios:
Linters are generally executed using default commands, but we can adjust these commands. For example:
qbox/kodo:
linters:
staticcheck:
workDir: "src/qiniu.com/kodo"
This configuration means that for the staticcheck
inspection of the qbox/kodo
repository code, execution should occur in the src/qiniu.com/kodo
directory.
We can even configure more complex commands, such as:
qbox/kodo:
linters:
golangci-lint:
command:
- "/bin/sh"
- "-c"
- "--"
args:
- |
source env.sh
cp .golangci.yml src/qiniu.com/kodo/.golangci.yml
cd src/qiniu.com/kodo
export GO111MODULE=auto
go mod tidy
golangci-lint run --timeout=10m0s --allow-parallel-runners=true --print-issued-lines=false --out-format=line-number >> $ARTIFACT/lint.log 2>&1
This configuration indicates that for the golangci-lint
inspection of the qbox/kodo
repository code, execution occurs through custom commands and arguments.
The usage of command and args here is similar to that of Kubernetes Pod command and args. You can refer to Kubernetes Pod for more information.
The $ARTIFACT environment variable is noteworthy. This is a built-in variable in Reviewbot used to specify the output directory, facilitating the exclusion of irrelevant interference. Since Reviewbot ultimately only cares about the linters' output, and in this complex scenario, the shell script will output a lot of irrelevant information, we can use this environment variable to specify the output directory. This allows Reviewbot to parse only the files in this directory, resulting in more precise detection results.
We can also disable a specific linter check for a particular repository through configuration. For example:
qbox/net-gslb:
linters:
golangci-lint:
enable: false
This configuration means that the golangci-lint
check is disabled for the qbox/net-gslb
repository.
By default, Reviewbot clones the repository where the event occurs. However, in some scenarios, we might want to clone multiple repositories, and customizing the cloning path.
For example:
qbox/net-gslb:
refs:
- org: "qbox"
repo: "net-gslb"
pathAlias: "src/qiniu.com/net-gslb"
- org: "qbox"
repo: "kodo"
By default, Reviewbot uses locally installed linters for checks. However, in some scenarios, we might want to use Docker images to execute linters, such as:
- When the relevant linter is not installed locally
- When the target repository requires different versions of linters or dependencies
- When the target repository depends on many third-party libraries, which would be cumbersome to install locally
In these scenarios, we can configure Docker images to execute the linters. For example:
qbox/net-gslb:
linters:
golangci-lint:
dockerAsRunner:
image: "golangci/golangci-lint:v1.54.2"
This configuration means that for the golangci-lint
check of the qbox/net-gslb
repository code, the golangci/golangci-lint:v1.54.2
Docker image is used for execution.
Reviewbot also supports executing linters in a Kubernetes cluster. This is particularly useful in scenarios where multiple tasks are running concurrently, and local resources are insufficient.
Example configuration:
qiniu/reviewbot:
linters:
golangci-lint:
enable: true
kubernetesAsRunner:
image: "aslan-spock-register.qiniu.io/reviewbot/base:golangci-lint.1.61.0"
namespace: "reviewbot"
Reviewbot primarily operates as a GitHub Webhook service, accepting GitHub Events, executing various checks, and providing precise feedback on the corresponding code if issues are detected.
Github Event -> Reviewbot -> Execute Linter -> Provide Feedback
- Event received, determine if it's a Pull Request
- Retrieve code:
- Get the code affected by the PR
- Clone the main repository
- The main repository serves as a cache
- Checkout the PR and place it in a temporary directory
- Pull submodules
- If the repository uses submodule management, code is automatically pulled
- Enter Linter execution logic
- Filter linters
- By default, all supported linters apply to all repositories unless individually configured
- Individual configurations need to be explicitly specified in the configuration file
- Explicitly specified configurations override default configurations
- By default, all supported linters apply to all repositories unless individually configured
- Execute linter
- General logic
- Execute the corresponding command and obtain the output results
- Filter the output results, only obtaining the parts relevant to this PR
- Some linters focus on code
- Some linters focus on other aspects
- Provide feedback
- Some linters provide Code Comments, precise to the code line
- Some linters provide issue comments
- Filter linters
- Please select an Issue you want to address from the issues list.
- Of course, if there isn't one, you can first create an Issue describing the Linter you want to add
- Coding
- Based on the language or domain the linter focuses on, choose the appropriate code location
- The implementation logic for most linters is divided into three main parts:
- Execute the linter, generally by calling the relevant executable program
- Process the linter's output, focusing only on the output related to the current PR
- Provide feedback on the output related to the current PR, precise to the code line
- Deployment: If your linter is an external executable program, you'll need to add instructions on how to install this linter in the Dockerfile
- Documentation: To facilitate subsequent use and maintenance, we should add appropriate documentation here
Reviewbot supports notification of detection results through WeWork (企业微信) alerts. For specific implementation details, refer to here.
To enable this feature, simply set the environment variable WEWORK_WEBHOOK
when starting Reviewbot. This environment variable should point to the WeWork chat group's bot URL. When valid issues are detected, notifications will be sent automatically. For example:
If unexpected output is encountered, notifications will also be sent, like this:
For unexpected outputs, it usually means that the default execution configuration of the relevant linter does not support the current repository. In such cases, you need to explicitly specify the configuration through a configuration file based on the actual situation.
Your contributions to Reviewbot are essential for its long-term maintenance and improvement. Thanks for supporting Reviewbot!
If you find a bug while working with the Reviewbot, please open an issue on GitHub and let us know what went wrong. We will try to fix it as quickly as we can.
Reviewbot is released under the Apache 2.0 license. See the LICENSE file for details.