💻

Zenn のコンテンツを textlint で校正しつつ GitHub で管理する

2021/03/15に公開

Zenn はじめました。
記念すべき第 1 回目の記事は Zenn での執筆活動を円滑にするための環境構築のお話です。
ローカル環境であれこれ触ったりネット上の記事を徘徊して、個人的に以下の点が良いと思ったので移行することに決めました。

  • GitHub + CLI ベースでの滑らかなコンテンツ執筆体験
  • Markdown サポートでロックインの心配がなさそう
  • クラスメソッド社の買収によるサービス継続の安心感

https://classmethod.jp/news/20210201-zenn/

今回やったことは、「Zenn のコンテンツを textlint で校正しつつ GitHub で管理すること」です。
アーリーアダプターの人からは何番煎じのお話だと言われそうですが、個人的なメモということで情報をまとめてみます。

セットアップ

公式ドキュメントと GitHub Issue が充実していて最初のセットアップは特にハマることなく簡単に済みました。
GitHub リポジトリと Zenn CLI で執筆する環境を構築するためには、基本的には以下の記事通りに進めて構築できます。

https://zenn.dev/zenn/articles/connect-to-github
https://zenn.dev/zenn/articles/install-zenn-cli

作業の概要としては以下のような感じです。

# GitHub リポジトリの作成(GitHub CLI なら以下)
gh repo create blog-zenn --private

# リポジトリの初期化
npm init --yes

# CLI のインストール
npm install zenn-cli

# 雛形のセットアップ
npx zenn init

# ブラウザでローカルプレビュー
npx zenn preview

カスタマイズ

Makefile によるコマンド化

常用しそうなコマンドはすぐ叩けるようにショートカットコマンドを定義します。
alias でも何でも良さそうですが、個人的に慣れている Makefile で構築します。

help

コマンドが増えてくるとターゲット名を忘れそうなので、
未来の自分のためにまずは以下を参考に help を作成します。
https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html

Makefile
.PHONY: help
help:
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
.DEFAULT_GOAL := help

preview

ローカルサーバを立てる preview はよく使いそうなのでターゲットを定義します。
ポート番号が衝突したときを想定して PORT 変数を定義して configurable にします。

Makefile
PORT ?= 8000

.PHONY: preview
preview: ## preview contents
	npx zenn preview \
		--port $(PORT)

article

slug に作成時の日付を prefix として入れたかったので記事作成コマンドの article もターゲットを定義しました。
オプション引数については個人的に決まっているものについてはハードコードしてます。

Makefile
.PHONY: article
article: ## add new article
ifndef SLUG
	$(error Usage: make article SLUG=type-your-slug)
endif
	npx zenn new:article \
		--slug $(YYYYMMDD)-$(SLUG) \
		--type tech \
		--emoji 💻 \
		--published true

zsh の補完処理と組み合わせることで、体験が良くなりました。

(2021/03 現在、Zenn CLI って補完機能無いのだっけ...。)

textlint による校正

OSS の開発って基本一人でやることが多くて Pull Request 立てても当然誰もレビューしてくれなくて寂しい気持ちを紛らわすため、reviewdogを飼うことにしました。
日本語の文章校正ツールをローカル環境で VSCode から動かすために textlint を導入します。
以下を参考にしました。
https://qiita.com/takasp/items/22f7f72b691fda30aea2

また、以下を参考に表記ゆれの修正も併せて行います。
Node.js 製の文章校正ツールである prh を導入します。
https://qiita.com/munieru_jp/items/83c2c44fcadb177d2806

インストール

# ツール群のインストール
npm install -D \
    textlint \
    textlint-rule-preset-ja-spacing \
    textlint-rule-preset-ja-technical-writing \
    textlint-rule-spellcheck-tech-word \
    textlint-rule-prh

# VSCode 拡張のインストール
code --install-extension taichi.vscode-textlint

設定ファイル

.textlintrc
{
  "filters": {},
  "rules": {
    "preset-ja-spacing": {
      "ja-space-between-half-and-full-width": {
        "space": "always"
      }
    },
    "preset-ja-technical-writing": true,
    "spellcheck-tech-word": true,
    "prh": {
      "rulePaths": [
        "./prh.yml"
      ]
    },
  }
}

prh の設定例は以下の通りです。
こちらで語彙を登録しておくと、VSCode 上のコマンドパレットから、
> textlint: Fix all auto-fixable Problems
を実行すると自動で修正してくれて便利です。

version
rules:
  - expected: Google
    specs:
      - from: google
        to: Google

reviewdogとGitHub Actionsでtextlintチェック

以下を参考に GitHub Actions を書きました。
https://knsh14.github.io/posts/textlint-reviewdog/)

reviewdog の README にインストール方法はいくつか記載がありましたが、GitHub Actions では curl のワンライナーを選択しました。
https://github.com/reviewdog/reviewdog

リリースバージョンは現時点で最新の v0.11.0 を指定しました。
以下のコマンドで textlint の出力が得られます。

npx textlint -f checkstyle articles/**/*.md

あとはこれをパイプして reviewdog に食わせるだけです。
実挙動の検証のために、意図的にエラーを吐く箇所を作成して reviewdog が検出してくれるかを、
実際に Pull Request 作成して確認しました。

.github/actions/reviewdog.yml
name: reviewdog
on:
  pull_request:
    branches:
      - main
jobs:
  textlint:
    name: runner / textlint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          submodules: true
      # https://knsh14.github.io/posts/textlint-reviewdog/
      # https://zenn.dev/serima/articles/4dac7baf0b9377b0b58b
      - name: install reviewdog
        run: |
          curl -sfL https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh | sh -s  v0.11.0
      - name: lint articles
        env:
          REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          npx textlint -f checkstyle articles/**/*.md | ./bin/reviewdog -f=checkstyle -name=textlint -reporter=github-pr-review

後々気づきましたがこの辺の詳細をラップした action としてtsuyoshicho/action-textlint@v1 があるのでそれを使うとより簡単です。
以下の記事で使い方が書いてありました。
https://zenn.dev/serima/articles/4dac7baf0b9377b0b58b

その他参考文献

https://zenn.dev/zenn/articles/markdown-guide

Discussion