CI | Status |
---|---|
Travis CI | |
CircleCI | |
drone.io | |
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 any output of lint tools and post them as a comment if the file and line are in diff of patches to review.
reviewdog also supports run in local environment to filter output of lint tools by diff.
Automatic code review (sample PR)
Local run
Get the binary release (recommended way)
or
go get -u github.com/haya14busa/reviewdog/cmd/reviewdog
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 more complex output. 'errorformat' can handle more complex output like multi-line error message.
By this 'errorformat' feature, reviewdog can support any tools output with ease.
But, you don't have to write 'errorformat' in many cases. reviewdog supports pre-defined errorformat for major compiler 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
reviewdog also accepts checkstyle XML format as well. If the linter supports checkstyle format as a report format, you can us -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" -ci="circle-ci"
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>" -ci="circle-ci"
[experimental]
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 intergration with ease.
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 -ci=droneio -conf=./.reviewdog.yml
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>
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 local environment.
reviewdog can intergrate with CI service and post review comments to report results automatically as well!
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.
reviewdog requires GitHub Personal API Access token as an environment variable
(REVIEWDOG_GITHUB_API_TOKEN
) to post comments to GitHub or GitHub Enterprise.
Go to https://github.com/settings/tokens and generate new API token.
Check repo
for private repositories or public_repo
for public repositories.
Export the token environment variable by secure way, depending on CI services.
For GitHub Enterprise, please set API endpoint by environment variable.
export GITHUB_API="https://example.githubenterprise.com/api/v3"
Name | Pull Request from the same repository | Pull Request from forked repository |
---|---|---|
Travis CI | ⭕ | ❌ |
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 repository, most CI services restrict secret environment variable for security reason, to avoid leak of secret data with malicious Pull Request. (Travis CI, CircleCI)
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.8
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 -ci=travis
Examples
Store GitHub API token in Environment variables - CircleCI
Circle CI do not build by pull-request hook by default, so please turn on "Only build pull requests" in Advanced option in Circle CI (changelog).
Pull Requests from fork repo cannot set 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 have an option to enable it. Unsafe fork PR builds
I thinks it's not a big problem if GitHub API token has limited scope (e.g. only public_repo
),
but if you enables Unsafe fork PR builds
to run reviewdog for fork PR, please use it at your own risk.
circle.yml sample
machine:
environment:
REVIEWDOG_VERSION: 0.9.8
dependencies:
override:
- curl -fSL https://github.com/haya14busa/reviewdog/releases/download/$REVIEWDOG_VERSION/reviewdog_linux_amd64 -o reviewdog && chmod +x ./reviewdog
test:
override:
- >-
go tool vet -all -shadowstrict . 2>&1 | ./reviewdog -f=govet -ci="circle-ci"
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_GITHUB_API_TOKEN: <your token>
.drone.yaml example
build:
lint:
image: golang
environment:
- 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 -ci=droneio
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 document carefully http://readme.drone.io/usage/secrets/ not to expose secret data unexpectedly.
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) |
REVIEWDOG_GITHUB_API_TOKEN |
GitHub Personal API Access token |
$ export CI_PULL_REQUEST=14
$ export CI_REPO_OWNER=haya14busa
$ export CI_REPO_NAME=reviewdog
$ export CI_COMMIT=$(git rev-parse HEAD)
$ export REVIEWDOG_GITHUB_API_TOKEN="<your token>"
$ golint ./... | reviewdog -f=golint -ci=common
$ export CI_PULL_REQUEST=${ghprbPullId}
$ export CI_REPO_OWNER=haya14busa
$ export CI_REPO_NAME=reviewdog
$ export CI_COMMIT=${ghprbActualCommit}
$ export REVIEWDOG_GITHUB_API_TOKEN="<your token>"
$ export REVIEWDOG_INSECURE_SKIP_VERIFY=true # set this as you need
$ reviewdog -ci=common -conf=.reviewdog.yml
haya14busa (https://github.com/haya14busa)