📔

Bitbucket Pipelines と reviewdog と textlint を使って文章校正チェックを自動化

2021/07/05に公開

TL;DR

Bitbucket Pipelines[1], reviewdog[2] を用いることで、textlint[3] の結果をプルリクエスト時に表示できました。

何ができるの?

Bitbucket で管理されている日本語ドキュメントリポジトリにおいて、文章校正ツール textlint の指摘結果を自動的に PR 時にレポートしてくれます 🎉

プルリクエスト画面
実際の PR ページ でも確認できます(公開リポジトリで試していますが、指摘表示を見るためには Bitbucket ログインが必要になります)。

まずは使って確かめてみる

最初は、固定のルールで文章校正した結果を Bitbucket で表示してみましょう。
もし既に textlint を利用してローカルで確認しているような方は、この節を読み飛ばしてください。

まず対象のリポジトリのトップディレクトリに .textlintrc ファイルを作成、追加します。

.textlintrc
{
    "rules": {
        "preset-ja-technical-writing": true
    }
}

.textlintrc ファイルには、textlint 実行時の設定を記述します。json 形式でどのようなルールを適用するか、そしてそれらのルールの詳細設定を記述できます。興味のある方は、別途 textlint 公式サイトのドキュメントなどを確認してみてください。
ここでは、技術文書向けのプリセットとして配布されている preset-ja-technical-writing を指定しています。実行されるルールは、preset-ja-technical-writing のルール一覧で確認できます。

続いて、Bitbucket Pipelines の設定を bitbucket-pipelines.yml に記述し、追加します。

bitbucket-pipelines.yml
pipelines:
  default:
    - step:
        name: Reviewdog-textlint
        image: cslroot/textlint-reviewdog-bitbucket
        script:
          - /textlint-reviewdog-bitbucket.sh .

ここでは、別途作成済みの Docker イメージを用いて、コンテナ上で textlint を実行しています。チェック対象のファイルのあるディレクトリとして、実行時のリポジトリのトップディレクトリを指定しています。textlint-reviewdog-bitbucket.sh はコンテナ上に用意している実行用のスクリプトです。このスクリプトは textlint を実行し、その結果を reviewdog に与え、Bitbucket の Code Insights 機能へ渡す処理が入っています。

これらの 2 つのファイルを git 管理に追加して、該当リポジトリ内の .md ファイルに適当な編集を加えてプルリクエストすると、最初に述べたように textlint のチェック結果が該当行に表示されます。やったね 🎊

発展的な使い方

特定ディレクトリを対象にする

上述の使い方ではトップディレクトリを対象としていましたが、実際にはリポジトリ内の特定のディレクトリを指定することが多いでしょう。
その場合は、pipeline の設定で、対象ディレクトリを指定できます。

ここでは、doc ディレクトリ配下の *.md ファイルを対象にしてみましょう。

bitbucket-pipelines.yml
pipelines:
  default:
    - step:
        name: Reviewdog-textlint
        image: cslroot/textlint-reviewdog-bitbucket
        script:
          - /textlint-reviewdog-bitbucket.sh "./doc/*.md"  # ここを変えました

ここで指定したディレクトリやファイルは、 textlint へそのまま渡されます。glob 形式(例: **/*.md など)も使うことができます。

独自のルールを使う場合

これまでの例では、固定プリセットのルールを使って textlint を実行していましたが、実用的には、作成するドキュメントに応じたルールの調整が必要になります。

textlint ルールのインストールと.textlintrc の編集

ローカルにある、.textlintrc ファイルに記載された textlint ルールを適用する方法を確認します。ここでは、参考記事 と同じルールを適用してみます。

まずは、ローカル環境に、npm を使って、textlint と利用するプリセットルールをインストールします。

npm install --save-dev textlint textlint-rule-preset-ja-technical-writing textlint-rule-preset-ja-spacing

すると、package.json, package-lock.json が作成されます。それぞれ、インストールしたバッケージ名やパッケージのバージョンが記録されたファイルになります。
これらのファイルをリポジトリ管理に追加します。なお、同時に作成される node_modules ディレクトリは Bitbucket pipelines での実行には不要ですので、.gitignore に登録しておくと良いでしょう。

続けて、.textlintrc を編集し(なければ作成します)、以下の内容をペーストしてください[4]

.textlintrc
{
  "plugins": {
    "@textlint/markdown": {
      "extensions": [".md"]
    }
  },
  "rules": {
    "preset-ja-technical-writing": {
      "no-exclamation-question-mark": {
        "allowFullWidthExclamation": true,
        "allowFullWidthQuestion": true
      },
      "no-doubled-joshi": {
        "strict": false,
        "allow": ["か"] // 助詞のうち「か」は複数回の出現を許す(e.g.: するかどうか)
      }
    },
    "preset-ja-spacing": {
      "ja-space-between-half-and-full-width": {
        "space": "always",
        "exceptPunctuation": true
      },
      "ja-space-around-code": {
        "before": true,
        "after": true
      }
    },
    "ja-technical-writing/ja-no-mixed-period": {
      "allowPeriodMarks": [":"],
      "allowEmojiAtEnd": true
    },
    "ja-technical-writing/sentence-length": false //100文字数制限の無効化
  }
}

Pipelines の編集

bitbucket-pipelines.yml を編集して、npm ci で、pipeline 環境で独自ルール用パッケージがインストールされるようにしておきます。

bitbucket-pipelines.yml
pipelines:
  default:
    - step:
        name: Reviewdog-textlint
        image: cslroot/textlint-reviewdog-bitbucket
        script:
          - npm ci
          - /textlint-reviewdog-bitbucket.sh "**/*.md"

以上の変更を加えることで、リポジトリごとに設定したルールで、textlint を実行できます。

やったこと

ここからは、構築に当たり、調査実施したことの記録です。

  • Docker イメージの作成
  • Pipelines の編集

Bitbucket Pipelines 上での実行にあたっては、 pipeline 上で各種ツールをインストールして直接実行する方法と、ツールインストール済み Docker イメージを用いる方法が考えられます。
前者の場合 reviewdog のサンプルのように golang の利用可能なイメージを指定する必要があります。
今回のように textlint(npm) と組合せて実行する場合は、さらに nodejs 実行環境も含まれた Docker イメージが必要になります。

今回は後者の方法として、golang, nodejs, textlint, reveiwdog インストール済みの Docker イメージを作成することにしました。

Docker イメージの作成

Docker ファイルで、次の環境を整えます。

  • reviewdog 実行環境
  • textlint 実行環境

textlint の環境を整えるため、npm と、reveiewdog のために golang の環境が必要となります。
ここでは、golang 用の Docker イメージをベースに、次のような Docker ファイルを作成しました。

Dockerfile
FROM golang:latest
MAINTAINER rootx <cslroot+github@gmail.com>

RUN apt-get update
RUN apt-get install -y curl

# nodejs
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
RUN apt-get install -y nodejs

# textlint
RUN npm install -g textlint
RUN npm install -g textlint-rule-preset-ja-technical-writing

# reviewdog install to default: ./bin/
RUN curl -sfL https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh | sh -s 2>&1

WORKDIR /work
COPY ./.textlintrc .
COPY ./textlint-reviewdog-bitbucket.sh /

golang:latest イメージをベースとして、golang 実行環境が入った状態でスタートします。

最初に nodejs をインストールします。nodejs は、いくつかインストール方法があるようですが、今回は比較的新しいバージョンをインストールするため PPA(personal package archive) を利用したインストール方法を採用しています。

そして、npm を用いて、textlint 本体をインストールします。また、お試しですぐに使えるよう固定のプリセットルールをインストールしています。textlint は、textlint 本体と、各種ルール用パッケージが同一環境へ配置されるようにしています(例: textlint 本体を -g でインストールした場合は、ルールも -g でインストールする必要があるようです)。

reviewdog は公式のインストール方法にしたがって curl を用いてインストールしています。

最後に、textlint / reviewdog 実行用のスクリプト textlint-reviewdog-bitbucket.sh を用意して、Bitbucket の結果表示できるように備えます。

ここで、実行しているスクリプト textlint-reviewdog-bitbucket.sh は以下のとおりです。処理は、tsuyoshicho/action-textlint tsuyoshicho/action-textlintscript.sh を参考にさせていたきました。実施内容としては、textlint の checkstyle 形式の出力を変数に保持し、reviewdog の --reporterbitbucket-code-report を指定して実行しています。
また、各人のリポジトリ内の package.json (or package-lock.json ) を使えるように textlint を npx コマンドで実行しています。

textlint-reviewdog-bitbucket.sh
#!/bin/bash
set -e

target=$1

textlint_exit_val="0"
reviewdog_exit_val="0"

textlint_check_output=$(npx textlint -f checkstyle "${target}" --config .textlintrc 2>&1) \
                      || textlint_exit_val="$?"
echo "${textlint_check_output}"
echo "${textlint_exit_val}"

echo "${textlint_check_output}" | reviewdog \
        -f=checkstyle \
        -name=textlint \
        -reporter=bitbucket-code-report \
        -filter-mode=nofilter \
        -fail-on-error=false \
        -level=error \
         || reviewdog_exit_val="$?"

作成した Dockerfile を github リポジトリに登録し、Dockerhub の github 連携機能を用いて自動的にビルドされるようにして完了です。
作成した Docker リポジトリは、こちらです。

ビルドされた Docker イメージはこちらになります。

Pipeline の構築

Bitbucket pipelines の設定は、Web 上でも編集できますが、直接記載しました。
利用するイメージを image: で指定します。イメージ名は、Dockerhub などで公開されている場合は、ユーザ名/Dockerイメージ名 という形式で指定できます。
script: で、リポジトリ上のパッケージを適用するため、npm ci の呼び出しと、textlint 実行用スクリプトの呼び出しを記載しました。

bitbucket-pipelines.yml
pipelines:
  default:
    - step:
        name: Reviewdog-textlint
        image: cslroot/textlint-reviewdog-bitbucket
        script:
          - npm ci
          - /textlint-reviewdog-bitbucket.sh "**/*.md"

まとめ

Bitbucket Pipelinse や reviewdog 、Docker イメージ作成など未経験でしたが、なんとか Bitbucket Pipeliens / Code Insights 機能を活用し、 textlint の実行結果を reviewdog を使って表示できるようになりました。

今後の課題

  • Sphinx 対応
  • プルリクエスト時にのみ実行させたほうが良い?

参考文献

脚注
  1. Github Actions の Bitbucket 版という認識です。Docker イメージも使えます。無料アカウントの場合は、50 分/月まで利用可能。 ↩︎

  2. CI システム上で動かして、各種 lineter の結果を GitHub Checks や Bitbucket Code Insights といったサービス形式にして、コードの Diff 表示にレポートしてくれるツール。 ↩︎

  3. 日本語ドキュメントの linter。nodejs 製。類似ツールとして RedPen なども有名。 ↩︎

  4. zenn-cli + reviewdog + textlint + GitHub Actions で執筆体験を最高にする.textlintrc をそのまま利用させていただきました。ただし、ja-space-between-half-and-full-width のキーのみ json 形式として不正と思われたので、修正しています。 ↩︎

Discussion