textlint + Reviewdog + GitLab CI でアドベントカレンダーの校正をした話
これは、Qiita Advent Calendar 2021 GitLabの15日目の記事です。
はじめに
こんにちは、フォルシアにて、旅行会社向けの web アプリケーションを開発しています、エンジニアの高橋です。普段のアプリ開発の業務のほかに技術広報も兼任しており、弊社で開催しているアドベントカレンダーの運営もお手伝いしています。
フォルシアではもともと、社内のイベントとしてアドベントカレンダーを始めましたが、2018 年からは弊社ブログ(FORCIA CUBE)にて外部の方向けに記事を公開しています。 社内のみで記事を公開していた頃は、誰かが多少締め切りをすぎても「かまへんかまへん」と言えますが、外部に公開するとなるとそうはいきません。25 日間落とすことなく記事を上げ続けるために、執筆者へのフォローや締め切り管理、ブログへのアップロードを組織的に行う必要がありました。
外部公開を始めた初年度は esa というドキュメントツールのみで記事や進捗を管理していましたが、どの記事がいつ公開なのか、レビューが終わっているのかどうかなどを一覧で見ることができず、管理がなかなか大変でした。 そこで 2020 年より、社内ですでに使用していたコードのホスティングサービスである GitLab を利用して記事を管理するようにしました。GitLab の issue 機能を使い 1 issue = 1 記事に対応させて管理するようにしたことで、かんばんボードを使って記事の進捗を管理することができるようになり、大変便利でした。以下の図のように、カラムやラベルを付けて記事を管理しています。記事自体も issue に直接記載する形式にしました。
issue の利用により進捗の管理が容易になった点はよかったのですが、その年のアドベントカレンダー運営の振り返りでは以下のような課題も上がりました。
- レビューがやや難しい
- せっかくなので、GitLab の CI 機能をもっと活用したい
そこで今年のアドベントカレンダーでは、 GitLab の MR 機能(マージリクエスト。GitHub の Pull Request に相当する機能)を利用してみることにしました。
MR であれば
- 行単位でレビューが書けるため、指摘箇所がわかりやすい
- 編集履歴を残すことができる
- CI を活用しやすい
といった利点があります。 さらに、せっかく CI を使えるようになったので以前からやってみたいと思っていた誤字脱字の指摘、文章の構成の自動化にとりくんでみました! その内容を本記事で紹介させてください。
できたもの
投稿された記事を校正し、MR にレビューコメントをしてくれる「赤ペン博士 bot」を作りました。
使用したライブラリの説明
textlint
textlintは「linter」と言われるツールの一種で、記述されたプログラムや文章がルールに沿って書かれているかをチェックしてくれます。多くの linter がプログラミング言語を対象としてツールであるのに対して、textlint は自然言語を対象にしているため、文章の校正に利用できます。
textlint で適用するルールは様々なプラグインから自分で取捨選択でき、例えば以下のような項目をチェックできます。
- 文末が「。」で終わっているかどうか
- 日本語の誤用がされていないかどうか
- 必要な箇所にスペースが入れられているかどうか
textlint の導入によりこれまで人力で指摘・修正していた文章の誤りを自動で検知することができるようになります。
Reviewdog
Reviewdogは様々な linter と組み合わせて、GitHub や GitLab などのコードホスティングサービスに linter が指摘した内容をレビューコメントとして投稿してくれるツールです。これにより、GitLab に push された記事に対して、textlint を適用した結果を該当箇所にコメントできます。
余談ですが、ロゴが可愛いのも特徴です。
GitLab CI
GitLab CIは GitLab が公式に提供している Continuous Integration(CI)ツールで、GitLab 上に push されたコードに対して、トリガーや実行内容を設定して処理を行うことができます。一般的なプロジェクトではテストやデプロイを自動化するために使われることが多いですが、今回は校正を自動化するために利用しました。
Reviewdog が MR にコメントするには GitLab でアクセストークンを発行する必要がありますが、Reviewdog 用の GitLab アカウントを新規で作成し、プライベートアクセストークンを発行することで実現しました。プロジェクト単位でアクセストークンを発行することもできますが、その場合アイコンを設定できないためレビューがややたんぱくになってしまうのが難点です。
上記のツールを組み合わせ、以下のような仕組みを作成しました。
MR が作成されたり更新されると自動で GitLab の CI が起動し、CI の中では文章に対して textlint で校正をかけ、その結果を Reviewdog が MR へのコメントとして通知してくれます。
各種設定について
次に、ツールを動かす設定をご紹介します。
package.json の設定
textlint は npm を使って導入できます。package.json を未作成のプロジェクトの場合、プロジェクトのルートディレクトリで
npm init -y
npm install --save-dev textlint
とすることで、package.json の作成と textlint のインストールが行われます。textlint の拡張パッケージ(後述)についても同様に npm からインストールできます。
gitlab-ci.yml の設定
.gitlab-ci.yml
ファイルをリポジトリに作成し、GitLab 側の設定をいくつかすることで CI 機能を使うことができます。もう少し詳しく知りたいという方は、よければ以下の記事をご覧ください。
GitLab CI/CD 導入の手引き(FORCIA CUBE)
CI では使用するライブラリのインストールと、 textlint, Reviewdog の実行をしています。また、Reviewdog 実行用の API アクセストークンのキーは CI 設定の Variables に登録してあります。
image: alpine # CIで使用するdockerイメージの指定 reviewdog: allow_failure: true # CIに失敗してもMRをMerge可能なようにする設定 script: - apk add --update git - apk add --update npm - npm install # package.jsonに登録したtextlintのインストール # reviewdogのinstall # bin/ 以下に実行ファイルがインストールされます - wget -O - -q https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh | sh -s # textlintとreviewdogの実行 # *.md ファイルを対象にlinterを実行しています - npx textlint -f checkstyle *.md | bin/reviewdog -f=checkstyle -name="textlint" -reporter=gitlab-mr-discussion
textlint のプラグイン
textlint には様々なプラグインがあり、自分の好みのルールを追加することができます。今回利用したのは以下のプラグインになります。
- textlint-rule-preset-ja-spacing
- 日本語におけるスペースの使い方のルール
- textlint-rule-preset-ja-technical-writing
- 日本語による技術文書向けのルール
- 技術書向けなのでブログにはふさわしくないルールも多く、適宜取捨選択して利用しています
- textlint-rule-preset-jtf-style
- 日本語用の標準的な textlint のルール郡
- textlint-rule-prh
- 文章の表記ゆれを検出するためのルール
- 自分で辞書を作成して、検出対象を決めることができる
これらのプラグインの細かなルールは .textlintrc.js
にて設定することができます。 今回は以下のような設定で利用しています。
module.exports = { plugins: { "@textlint/markdown": { extensions: [".md"], // マークダウン用の拡張 }, }, rules: { // textlint-rule-prhの設定 prh: { rulePaths: ["./prh.yml"], }, // textlint-rule-preset-jtf-styleの設定 "preset-jtf-style": { "1.2.1.句点(。)と読点(、)": false, // 文中のピリオドとカンマを許容 "1.1.3.箇条書き": false, // 箇条書きの文末に句点(。)以外を許可 "2.1.8.算用数字": false, // 算用数字以外も許容する。1桁は全角でも入力できるように。 "2.2.1.ひらがなと漢字の使い分け": true, // ひらがなにしたほうが良い漢字をサジェスト "4.1.3.ピリオド(.)、カンマ(,)": false, // 文中のピリオドとカンマを許容 "4.3.1.丸かっこ()": false, // 半角丸括弧を許容 "4.3.2.大かっこ[]": false, // 半角大括弧を許容 }, // textlint-rule-preset-ja-technical-writingの設定 "preset-ja-technical-writing": { "no-exclamation-question-mark": { allowFullWidthExclamation: true, allowFullWidthQuestion: true, }, "no-doubled-joshi": { strict: false, allow: ["か", "が", "に"], // これらの助詞は同一文中に多く登場しても許容 }, }, // textlint-rule-preset-ja-spacingの設定 "preset-ja-spacing": { "ja-space-around-code": { before: true, after: true, }, }, "ja-technical-writing/ja-no-mixed-period": { allowPeriodMarks: [":"], }, "ja-technical-writing/max-ten": { max: 5 }, // 文中の「、」の数は5個まで "ja-technical-writing/sentence-length": false, // 文の長さは指定なし "ja-technical-writing/ja-no-weak-phrase": false, // 弱い表現を許容 "ja-technical-writing/max-comma": false, // カンマの数は指定なし "ja-spacing/ja-space-around-code": false, // インラインコードの前後にスペースを入れなくてもよい }, };
phr.yml の設定
前述した textlint のプラグインの一種である textlint-rule-prh
を用いることで、表現の揺れを統一することができます。phr.yml
に以下のようなルールを登録して、ライブラリ名の揺れなどを統一しました。
version: 1 rules: - expected: Docker pattern: docker specs: - from: docker to: Docker - expected: Ansible pattern: ansible - expected: Ansistrano pattern: ansistrano - expected: Kubernetes pattern: kubernetes - expected: React pattern: react - expected: Redux pattern: redux - expected: Next.js patterns: - next.js - Nextjs
以下のように揺れを指摘してくれます。
おわりに
今回の仕組みを導入したことにより、人力で指摘するのはハードルが高い内容も自動でレビューできるようになり、運営チームの負担を減らしつつ記事の質を高めることができるようになったと思います。
また個人的に嬉しかったこととしては、記事を書いてくださる方達も赤ペン博士によるレビューを面白がってくださったことです。煙たがられるかなとも思っていたので、楽しんでいただけたようで作った甲斐がありました。
それでは残りの記事もお楽しみに!
高橋優樹
サウナがはかどる季節になりました。
フォルシアではフォルシアに興味をお持ちいただけた方に、社員との面談のご案内をしています。
採用応募の方、まずはカジュアルにお話をしてみたいという方は、お気軽に下記よりご連絡ください。
※ 弊社社員に対する営業行為などはお断りしております。ご希望に沿えない場合がございますので予めご了承ください。