したいこと、やったこと
Typescript
の型エラーが含まれるコードをGitHub
の保護ブランチにマージさせないように、GitHub Actions
を用いてtsc
に失敗したらチェックを落としたい。さらに、tsc
が検知した箇所にPRコメントで注釈して欲しい日がある。今回はreviewdogを使って、自動で注釈させるようにした。
reviewdog
が使われている既製のGitHub Action
に、eslint
のエラーを自動で注釈してくれるRun eslint with reviewdogが公開されているので、これと同様にTypeScript
のエラーも自動注釈できるんじゃなかろうかという考え。
実装したworkflow
前提
プロジェクトにnpmパッケージ
のtypescript
が導入されている。
yarn add -D typescript
実装したWorkflow
実装したWorkflowにおけるポイントは以下2点。
-
Github Action
のreviewdog/action-setup@v1を用いることで、Github Actions
上でreviewdog
を使えるようにしている。 -
Typecheck
ステップ。
name: Test
on: [pull_request]
jobs:
build:
name: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# ref: https://github.com/actions/setup-node#v2
- uses: actions/setup-node@v2
with:
node-version: "14"
# ref: https://github.com/reviewdog/reviewdog#github-action-reviewdogaction-setup
- uses: reviewdog/action-setup@v1
with:
reviewdog_version: latest
# ref: https://github.com/actions/cache/blob/main/examples.md#node---yarn
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install Dependencies
run: yarn --frozen-lockfile
# ref: https://github.com/reviewdog/reviewdog#available-pre-defined-errorformat
- name: Typecheck
run: tsc --pretty false --noEmit | reviewdog -f=tsc -reporter=github-pr-review -fail-on-error=true
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.github_token }}
それぞれのポイントについて
reviewdog/action-setup@v1
reviewdog/action-setup@v1でGitHub Actions
上にreviewdog
をインストールしている。reviewdog
は種々のチェックツールの出力に対応しており-list
オプションをつけて実行するとその一覧が見れる。これらチェックツールの出力を受け取り、その結果をGitHub
のPRにコメントをすることができる。
`reviewdog -list`した結果
❯❯❯ reviewdog -list
rdjson Reviewdog Diagnostic JSON Format (JSON of DiagnosticResult message) - https://github.com/reviewdog/reviewdog
rdjsonl Reviewdog Diagnostic JSONL Format (JSONL of Diagnostic message) - https://github.com/reviewdog/reviewdog
diff Unified Diff Format - https://en.wikipedia.org/wiki/Diff#Unified_format
checkstyle checkstyle XML format - http://checkstyle.sourceforge.net/
ansible-lint (ansible-lint -p playbook.yml) Checks playbooks for practices and behaviour that could potentially be improved - https://github.com/ansible/ansible-lint
brakeman (brakeman --quiet --format tabs) A static analysis security vulnerability scanner for Ruby on Rails applications- https://github.com/presidentbeef/brakeman
cargo-check (cargo check -q --message-format=short) Check a local package and all of its dependencies for errors - https://github.com/rust-lang/cargo
clippy (cargo clippy -q --message-format=short) A bunch of lints to catch common mistakes and improve your Rust code - https://github.com/rust-lang/rust-clippy
dotenv-linter Lightning-fast linter for .env files. Written in Rust - https://github.com/dotenv-linter/dotenv-linter
dotnet (dotnet build -clp:NoSummary -p:GenerateFullPaths=true --no-incremental --nologo -v q) .NET Core CLI - https://docs.microsoft.com/en-us/dotnet/core/tools/
eslint (eslint [-f stylish]) A fully pluggable tool for identifying and reporting on patterns in JavaScript - https://github.com/eslint/eslint
eslint-compact (eslint -f compact) A fully pluggable tool for identifying and reporting on patterns in JavaScript - https://github.com/eslint/eslint
fasterer Speed improvements suggester - https://github.com/DamirSvrtan/fasterer
go-consistent Source code analyzer that helps you to make your Go programs more consistent - https://github.com/quasilyte/go-consistent
golangci-lint (golangci-lint run --out-format=line-number) GolangCI-Lint is a linters aggregator. - https://github.com/golangci/golangci-lint
golint linter for Go source code - https://github.com/golang/lint
gosec (gosec -fmt=golint) Golang Security Checker - https://github.com/securego/gosec
govet Vet examines Go source code and reports suspicious problems - https://golang.org/cmd/vet/
haml-lint Tool for writing clean and consistent HAML - https://github.com/sds/haml-lint
hlint Linter for Haskell source code - https://github.com/ndmitchell/hlint
msbuild (msbuild /property:GenerateFullPaths=true /nologo /v:q) Microsoft Build Engine - https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild
pep8 Python style guide checker - https://pypi.python.org/pypi/pep8
phpstan (phpstan --error-format=raw) PHP Static Analysis Tool - discover bugs in your code without running it! - https://github.com/phpstan/phpstan
psalm (psalm --output-format=text) Psalm is a static analysis tool for finding errors in PHP - https://github.com/vimeo/psalm
puppet-lint Check that your Puppet manifests conform to the style guide - https://github.com/rodjek/puppet-lint
reek (reek --single-line) Code smell detector for Ruby - https://github.com/troessner/reek
rubocop A Ruby static code analyzer, based on the community Ruby style guide - https://github.com/rubocop-hq/rubocop
sbt the interactive build tool - http://www.scala-sbt.org/
sbt-scalastyle Scalastyle - SBT plugin - http://www.scalastyle.org/sbt.html
scalac Scala compiler - http://www.scala-lang.org/
scalastyle Scalastyle - Command line - http://www.scalastyle.org/command-line.html
slim-lint Tool to help keep your Slim files clean and readable - https://github.com/sds/slim-lint
sorbet A fast, powerful type checker designed for Ruby - https://github.com/sorbet/sorbet
standardjs (standard) JavaScript style guide, linter, and formatter - https://github.com/standard/standard
standardrb (standard) Ruby style guide, linter, and formatter - https://github.com/testdouble/standard
stylelint A mighty modern CSS linter - https://github.com/stylelint/stylelint
tsc TypeScript compiler - https://www.typescriptlang.org/
tslint An extensible linter for the TypeScript language - https://github.com/palantir/tslint
TypeCheckステップ
- name: Typecheck
run: tsc --pretty false --noEmit | reviewdog -f=tsc -reporter=github-pr-review -fail-on-error=true
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.github_token }}
TypeScript
のコンパイラであるtsc
は--pretty false
オプションをつけることでエラー出力が簡略化される。reviewdog
が受け付けるtsc
の出力は簡素化された方であるので、このオプションを付与したものをパイプ(|
)でreviewdog
に送る。
`tsc --pretty`の有無による違い
❯❯❯ tsc
src/components/IndexPage.tsx:3:7 - error TS2322: Type 'string' is not assignable to type 'number'.
3 const a: number = "hoge";
~
Found 1 error.
❯❯❯ tsc --pretty false
src/components/IndexPage.tsx(3,7): error TS2322: Type 'string' is not assignable to type 'number'.
reviewdog
には-f
オプションでどのチェックツールの出力が入力されているのか伝えている。ここで-reporter=github-pr-review
オプションと必要な環境変数をつけることで、自動でPRにコメントがされる。必要な環境変数は$REVIEWDOG_GITHUB_API_TOKEN
であり、GitHub Actions
のWorkflow
においては上記のような設定をすれば良い。
またreviewdog
に-fail-on-error=true
オプションをつけることで、エラーが入力されたらGitHub
のPRのチェックを失敗させるようにしている。
終わりに
最近の私は、たとえ一人で作るものでも、GitHub Actions
などを整えることを楽しんでやっています。我が我に出すPRにコメントなんざ付かないところ、botにでもコメントされると賑やかで良いものなんですよね。一人で作るプロジェクトこそあれチェックされる必要がないのに、却って、ロボットなり猫なりタコなりに自分の不注意を指摘してもらいたいというのは、なんか作るにあたって縛りプレイに面白みを感じる手合いだからだと思っています。