oohira / reviewdog

:dog: Automated code review tool integrated with any code analysis tools regardless programing language

Home Page:https://medium.com/@haya14busa/reviewdog-a-code-review-dog-who-keeps-your-codebase-healthy-d957c471938b#.8xctbaw5u

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

reviewdog - A code review dog who keeps your codebase healthy

Gitter LICENSE Go Report Card GoDoc releases

reviewdog logo

CI Status
Travis CI Travis Build Status
CircleCI CircleCI
drone.io drone.io Build Status
codecov codecov

"reviewdog" provides a way to post review comments to code hosting service, such as GitHub, automatically by integrating with any linter tools with ease. It uses an output of lint tools and posts them as a comment if findings are in diff of patches to review.

reviewdog also supports run in the local environment to filter an output of lint tools by diff.

design doc

github-pr-check sample comment in pull-request commit status sample-comment.png

Local run

reviewdog-local-demo.gif

Installation

Get the binary release (recommended way)

or

go get -u github.com/haya14busa/reviewdog/cmd/reviewdog

Usage

'errorformat'

reviewdog accepts any compiler or linter result from stdin and parses it with scan-f like 'errorformat', which is the port of Vim's errorformat feature.

For example, if the result format is {file}:{line number}:{column number}: {message}, errorformat should be %f:%l:%c: %m and you can pass it as -efm arguments.

$ golint ./...
comment_iowriter.go:11:6: exported type CommentWriter should have comment or be unexported
$ golint ./... | reviewdog -efm="%f:%l:%c: %m" -diff="git diff master"
name description
%f file name
%l line number
%c column number
%m error message
%% the single '%' character
... ...

Please see haya14busa/errorformat and :h errorformat if you want to deal with a more complex output. 'errorformat' can handle more complex output like a multi-line error message.

By this 'errorformat' feature, reviewdog can support any tools output with ease.

Available pre-defined 'errorformat'

But, you don't have to write 'errorformat' in many cases. reviewdog supports pre-defined errorformat for major compilers or linter tools.

You can find available errorformat name by reviewdog -list and you can use it with -f={name}.

$ reviewdog -list
golint          linter for Go source code                                       - https://github.com/golang/lint
govet           Vet examines Go source code and reports suspicious problems     - https://golang.org/cmd/vet/
sbt             the interactive build tool                                      - http://www.scala-sbt.org/
...
$ golint ./... | reviewdog -f=golint -diff="git diff master"

You can add supported pre-defined 'errorformat' by contributing to haya14busa/errorformat

checkstyle format

reviewdog also accepts checkstyle XML format as well. If the linter supports checkstyle format as a report format, you can use -f=checkstyle instead of using 'errorformat'.

# Local
$ eslint -f checkstyle . | reviewdog -f=checkstyle -diff="git diff"

# CI (overwrite tool name which is shown in review comment by -name arg)
$ eslint -f checkstyle . | reviewdog -f=checkstyle -name="eslint" -reporter=github-pr-check

Also, if you want to pass other Json/XML/etc... format to reviewdog, you can write a converter.

$ <linter> | <convert-to-checkstyle> | reviewdog -f=checkstyle -name="<linter>" -reporter=github-pr-check

Project Configuration Based Run

reviewdog can also be controlled via the .reviewdog.yml configuration file instead of "-f" or "-efm" arguments.

With .reviewdog.yml, you can run the same commands both CI service and local environment including editor integration with ease.

.reviewdog.yml

runner:
  <tool-name>:
    cmd: <command> # (required)
    errorformat: # (optional if there is supporeted format for <tool-name>. see reviewdog -list)
      - <list of errorformat>
    name: <tool-name> # (optional. you can overwrite <tool-name> defined by runner key)

  # examples
  golint:
    cmd: golint ./...
    errorformat:
      - "%f:%l:%c: %m"
  govet:
    cmd: go tool vet -all -shadowstrict .
$ reviewdog -diff="git diff master"
project/run_test.go:61:28: [golint] error strings should not end with punctuation
project/run.go:57:18: [errcheck]        defer os.Setenv(name, os.Getenv(name))
project/run.go:58:12: [errcheck]        os.Setenv(name, "")
# You can use -conf to specify config file path.
$ reviewdog -conf=./.reviewdog.yml -reporter=github-pr-check

Output format for project config based run is one of following formats.

  • <file>: [<tool name>] <message>
  • <file>:<lnum>: [<tool name>] <message>
  • <file>:<lnum>:<col>: [<tool name>] <message>

Run locally

reviewdog can find new introduced warnings or error by filtering linter results using diff. You can pass diff command as -diff arg, like -diff="git diff", -diff="git diff master", etc... when you use reviewdog in a local environment.

Working with GitHub and CI services

reviewdog can integrate with CI service and post review comments to report results automatically as well!

Supported code hosting (or code review) service

At the time of writing, reviewdog supports GitHub and GitHub Enterprise as a code hosting service for posting comments.

It may support Gerrit, Bitbucket, or other services later.

Reporter: GitHub Checks (-reporter=github-pr-check)

[experimental]

github-pr-check sample

github-pr-review reporter reports results as GitHub Checks. Since GitHub Checks API is only for GitHub Apps, reviewdog CLI send a request to reviewdog GitHub App server and the server post results as GitHub Checks.

  1. Install reviewdog Apps. https://github.com/apps/reviewdog
  2. Set REVIEWDOG_TOKEN or run reviewdog CLI in trusted CI providers.
  • Get token from https://reviewdog.app/gh/{owner}/{repo-name}.
  • $ export REVIEWDOG_TOKEN="xxxxx"
  1. $ reviewdog -conf=.reviewdog.yml -reporter=github-pr-check

Note: Token not required if you run reviewdog in Travis or AppVeyor.

Caution:

As described above, github-pr-check reporter is depending on reviewdog GitHub App server. The server is running with haya14busa's pocket money for now and I may break things, so I cannot ensure that the server is running 24h and 365 days.

github-pr-check reporter is better than github-pr-review reporter in general because it provides more rich feature and has less scope, but please bear in mind the above caution and please use it on your own risk.

You can use github-pr-review reporter if you don't want to depend on reviewdog server.

Reporter: GitHub PullRequest review comment (-reporter=github-pr-review)

sample-comment.png

github-pr-review reporter reports results as GitHub PullRequest review comments using GitHub Personal API Access Token.

  1. Get GitHub Personal API Access token
  1. Export the token environment variable
  • export REVIEWDOG_GITHUB_API_TOKEN="xxxxx"
  1. $ reviewdog -conf=.reviewdog.yml -reporter=github-pr-review
$ export GITHUB_API="https://example.githubenterprise.com/api/v3/"
$ export REVIEWDOG_INSECURE_SKIP_VERIFY=true # set this as you need

For GitHub Enterprise, set API endpoint by environment variable.

$ export GITHUB_API="https://example.githubenterprise.com/api/v3/"
$ export REVIEWDOG_INSECURE_SKIP_VERIFY=true # set this as you need

Supported CI services and security of secret environment variable

Name Pull Request from the same repository Pull Request from forked repositories
Travis CI ❌ (⭕ for -reporter=github-pr-check)
CircleCI ❌ (but possible with insecure way)
drone.io (OSS) v0.4
common (Your managed CI server like Jenkins)

reviewdog can run in CI services which supports Pull Request build and secret environment variable feature for security reason.

But, for the Pull Request from forked repositories, most CI services restrict secret environment variable for security reason, to avoid the leak of secret data with malicious Pull Request. (Travis CI, CircleCI)

Travis CI

Travis CI (-reporter=github-pr-check)

If you use -reporter=github-pr-check in Travis CI, you don't need to set REVIEWDOG_TOKEN.

Example:

env:
  global:
    - REVIEWDOG_VERSION=0.9.9

install:
  - mkdir -p ~/bin/ && export export PATH="~/bin/:$PATH"
  - curl -fSL https://github.com/haya14busa/reviewdog/releases/download/$REVIEWDOG_VERSION/reviewdog_linux_amd64 -o ~/bin/reviewdog && chmod +x ~/bin/reviewdog

script:
  - reviewdog -conf=.reviewdog.yml -reporter=github-pr-check
Travis CI (-reporter=github-pr-review)

Store GitHub API token by travis encryption keys.

$ gem install travis
$ travis encrypt REVIEWDOG_GITHUB_API_TOKEN=<your token> --add env.global

Example:

env:
  global:
    - secure: xxxxxxxxxxxxx
    - REVIEWDOG_VERSION=0.9.9

install:
  - mkdir -p ~/bin/ && export export PATH="~/bin/:$PATH"
  - curl -fSL https://github.com/haya14busa/reviewdog/releases/download/$REVIEWDOG_VERSION/reviewdog_linux_amd64 -o ~/bin/reviewdog && chmod +x ~/bin/reviewdog

script:
  - >-
    golint ./... | reviewdog -f=golint -reporter=github-pr-review

Examples

Circle CI

Store GitHub API token as REVIEWDOG_TOKEN or REVIEWDOG_GITHUB_API_TOKEN in Environment variables - CircleCI

Pull Requests from fork repo cannot set an environment variable for security reason. However, if you want to run fork PR builds for private repositories or want to run reviewdog for forked PR to OSS project, CircleCI has an option to enable it. Unsafe fork PR builds

If you use -reporter=github-pr-check and only set REVIEWDOG_TOKEN, it's safer because it has the small limited scope. As for REVIEWDOG_GITHUB_API_TOKEN, it has a bit larger scope at least even if you only set the scope repo:public.

Please use it at your own risk.

circle.yml sample

version: 2
jobs:
  build:
    docker:
      - image: golang:latest
        environment:
          REVIEWDOG_VERSION: 0.9.9
    steps:
      - checkout
      - run: curl -fSL https://github.com/haya14busa/reviewdog/releases/download/$REVIEWDOG_VERSION/reviewdog_linux_amd64 -o reviewdog && chmod +x ./reviewdog
      - run: go vet ./... 2>&1 | ./reviewdog -f=govet -reporter=github-pr-check
      # or
      - run: go vet ./... 2>&1 | ./reviewdog -f=govet -reporter=github-pr-review

drone.io

Store GitHub API token in environment variable. Secrets · Drone

Install 'drone' cli command http://readme.drone.io/devs/cli/ and setup configuration.

echo '.drone.sec.yaml' >> .gitignore

.drone.sec.yaml

environment:
  REVIEWDOG_TOKEN: <your token>
  # OR
  REVIEWDOG_GITHUB_API_TOKEN: <your token>

.drone.yaml example

build:
  lint:
    image: golang
    environment:
      - REVIEWDOG_TOKEN=$$REVIEWDOG_TOKEN
      # Or
      - REVIEWDOG_GITHUB_API_TOKEN=$$REVIEWDOG_GITHUB_API_TOKEN
    commands:
      - go get github.com/haya14busa/reviewdog/cmd/reviewdog
      - |
        go tool vet -all -shadowstrict . 2>&1 | reviewdog -f=govet -reporter=github-pr-check
      # Or
      - |
        go tool vet -all -shadowstrict . 2>&1 | reviewdog -f=govet -reporter=github-pr-review
    when:
      event: pull_request

Finally, run drone secure to encrypt the .drone.sec.yaml file and generate a .drone.sec file

$ drone secure --repo {github-user-name}/{repo-name} --in .drone.sec.yaml

drone.io supports encrypted environment variable for fork Pull Request build in secure way, but you have to read the document carefully http://readme.drone.io/usage/secrets/ not to expose secret data unexpectedly.

Common (Jenkins, local, etc...)

You can use reviewdog to post review comments anywhere with following environment variables.

name description
CI_PULL_REQUEST Pull Request number (e.g. 14)
CI_COMMIT SHA1 for the current build
CI_REPO_OWNER repository owner (e.g. "haya14busa" for https://github.com/haya14busa/reviewdog)
CI_REPO_NAME repository name (e.g. "reviewdog" for https://github.com/haya14busa/reviewdog)
CI_BRANCH [optional] branch of the commit
$ export CI_PULL_REQUEST=14
$ export CI_REPO_OWNER=haya14busa
$ export CI_REPO_NAME=reviewdog
$ export CI_COMMIT=$(git rev-parse HEAD)
$ REVIEWDOG_TOKEN="<your token>" golint ./... | reviewdog -f=golint -target=github-pr-check
Or
$ REVIEWDOG_GITHUB_API_TOKEN="<your token>" golint ./... | reviewdog -f=golint -target=github-pr-review
Jenkins with Github pull request builder plugin
$ export CI_PULL_REQUEST=${ghprbPullId}
$ export CI_REPO_OWNER=haya14busa
$ export CI_REPO_NAME=reviewdog
$ export CI_COMMIT=${ghprbActualCommit}
$ export REVIEWDOG_INSECURE_SKIP_VERIFY=true # set this as you need
$ REVIEWDOG_TOKEN="<your token>" reviewdog -conf=.reviewdog.yml -reporter=github-pr-check
# Or
$ REVIEWDOG_GITHUB_API_TOKEN="<your token>" reviewdog -conf=.reviewdog.yml -reporter=github-pr-review

🐦 Author

haya14busa (https://github.com/haya14busa)

About

:dog: Automated code review tool integrated with any code analysis tools regardless programing language

https://medium.com/@haya14busa/reviewdog-a-code-review-dog-who-keeps-your-codebase-healthy-d957c471938b#.8xctbaw5u

License:MIT License


Languages

Language:Go 99.5%Language:Shell 0.5%