🌟

MakefileでZennの記事を生成、執筆、デプロイを楽にする

2021/05/08に公開

MakefileでZennの記事を生成、執筆、デプロイを楽にする

こんにちは、前回の記事でVirtual-zennと名付けたmakeだけで記事を自動生成し、執筆からデプロイまでできるスクリプトについて軽くご紹介しました。

https://zenn.dev/_kazuya/articles/7814d63a424a4363cd11

今回は、技術的な話をしてみたいと思います。

シンプルにMakefileを使ってみる

まず、以前から私はlocal環境の中でzenn-cliを使っていましたが、nodeのコマンドを打つ労力を削減するため、Makefileを追加しました。
これはとても単純で手軽だと思います。
初めは以下のように記述しました。

Makefile
.PHONY: main
main: editor

.PHONY: book
book: editor-book

.PHONY: ls
ls: check

.PHONY: upload
upload:
	git add $(shell pwd)/articles/ 
	git commit -m "MAKEFILE: auto upload articles" 
	git push origin HEAD

.PHONY: create
create:
	npx zenn new:article

.PHONY: check
check:
	npx zenn list:articles
	npx zenn list:books

.PHONY: create-book
create-book:  create-book

.PHONY: edit-book
edit-book: edit-book

.PHONY: create-book
create-book:
	npx zenn new:book

.PHONY: upload-book
upload-book:
	git add $(shell pwd)/books/ 
	git commit -m "VIRTUALZENN: auto upload books" 
	git push origin HEAD

.PHONY: editor
editor:
	open http://localhost:8001 
	npx zenn new:article ; npx zenn preview & ; vim articles

.PHONY: edit
edit:
	open http://localhost:8002 
	npx zenn preview & ; vim articles

.PHONY: editor-book
editor-book:
	open http://localhost:8003
	npx zenn new:book ; npx zenn preview & ; vim books

.PHONY: edit-book
edit-book:
	open http://localhost:8004 
	npx zenn preview & ; vim books

このようなMakefileを皆さんのzenn-cliの執筆環境にそのまま設置して遊んでみてください。

とても簡単に複数の処理を単純化できます。
これらの処理によってファイルやオブジェクトが生成されるわけではないので、.PHONYをつけるようにしましょう。

〜Dockerを用いた環境構築自動化編〜

使用したOS、ツール、ライブラリ一覧

開発環境

  • macOS BigSur
  • Docker
  • zsh

コンテナ環境

  • node
  • ZennEditor
  • python3
  • shellcheck
  • Grunt
  • vim

環境構築

環境構築にはDockerを使います、
Dockerは、コンテナ仮想化を用いてアプリケーションを開発・配置・実行するためのオープンソースソフトウェアあるいはオープンプラットフォームである。 Dockerはコンテナ仮想化を用いたOSレベルの仮想化によりアプリケーションを開発・実行環境から隔離し、アプリケーションの素早い提供を可能にする[1]

とあるように、執筆環境を綺麗に保つことができるのでDockerを使った環境構築は良いと思います。
zenn-cliはまだまだベータ版なので、今後のことを考えても、メリットは大きいと思います。

流れ

  • Dockerfileを記述
  • dotfilesを準備する
  • Makefileを記述する

Dockerfileを記述

Dockerfile
From node
ENV LANG="ja_JP.UTF-8" LANGUAGE="ja_JP:ja" LC_ALL="ja_JP.UTF-8"

WORKDIR /virtual-zenn

RUN apt-get update \
      && apt-get -y install \
        vim \
        python3-pip \
        zsh \
        shellcheck \
      && git init \
      && git remote add origin https://github.com/Iovesophy/virtual-zenn.git \
      && git pull origin master \
      && npm init --yes \
      && npm install -g grunt-cli \
      && npm install \
        grunt \
        grunt-zshlint \
        zenn-cli \
      && npx zenn init

WORKDIR /virtual-zenn/dotfiles

RUN pip3 install --upgrade pip \
      && pip3 install vim-vint \
      && npm install -g grunt-cli \
      && npm install \
        grunt \
        grunt-zshlint

RUN ./test.sh

WORKDIR /virtual-zenn

Dockerfileで各種使用したいライブラリなどをあらかじめ設定することができます。
今回はzenn.devが提供しているZenn CLIがNode.js製なので、nodeのコンテナを使用します。

Zenn CLIの導入手順に関しては公式の記事を参考にしてください。

https://zenn.dev/zenn/articles/install-zenn-cli

また、virtual-zennという名前で今回の設定ファイル等を公開しているので、参考にしてください。

https://github.com/Iovesophy/virtual-zenn

ENV LANG="ja_JP.UTF-8" LANGUAGE="ja_JP:ja" LC_ALL="ja_JP.UTF-8"

この設定はvimを開いた時に日本語が文字化けするのを防ぐために設定しています。

        shellcheck \

このshellcheckはshellscriptのエラーチェックをするためにインストールしています。
とてもいいツールなので紹介しておきます。
次を参考にしてみてください。
https://github.com/koalaman/shellcheck

      && npm install -g grunt-cli \
      && npm install \
        grunt \
        grunt-zshlint \

この部分はGruntを使ってzsh等のdotfilesがきちんと設定されているかをチェックするために使用します。
Gruntを使った.zshrcのエラーチェックに関しては以下を参考にしてください。
https://github.com/pine/grunt-zshlint

dotfilesを設定する

コンテナ内部のシェルを使うことも想定して、各種必要なdotfilesも設定します。
dotfilesの最低限の設定等を自動で設定するスクリプトも以前書いたのでそれを利用します。
これは、好みがあると思うので、それぞれ実現したい環境によって構築すると良いと思います。

参考までにdotfilesの自動設定スクリプトを置いているリポジトリのリンクを貼っておきます。
https://github.com/Iovesophy/dotfiles

Makefileを使ってコンテナ起動等を楽にする

最後にMakefileを定義して、環境構築に必要なdockerのコマンドやnodeのコマンド等をシンプルにします。

Makefile
NAME := virtual-zenn

.PHONY: main
main: docker-build docker-run-vim

.PHONY: book
book: docker-build docker-run-vim-book

.PHONY: create
create: docker-build docker-run-create

.PHONY: edit
edit: docker-build docker-run-edit

.PHONY: ls
ls: docker-build docker-run-check

.PHONY: reset
reset: docker-run-rm

.PHONY: update
update:
	git pull origin master

.PHONY: upload
upload:
	mv $(shell pwd)/articles/stage/* $(shell pwd)/articles/ ; git add $(shell pwd)/articles/ ; git commit -m "VIRTUALZENN: auto upload articles" ; git push origin HEAD

.PHONY: docker-build
docker-build:
	docker build -t $(NAME) .

.PHONY: docker-run-rm
docker-run-rm:
	docker run --rm $(NAME)

.PHONY: docker-run-create
docker-run-create:
	docker run -v $(shell pwd)/articles/stage:/virtual-zenn/articles -it $(NAME) zsh -c "npx zenn new:article"

.PHONY: docker-run-check
docker-run-check:
	docker run -v $(shell pwd)/articles:/virtual-zenn/articles -it $(NAME) zsh -c "npx zenn list:articles"
	docker run -v $(shell pwd)/articles/stage:/virtual-zenn/articles -it $(NAME) zsh -c "npx zenn list:articles"
	docker run -v $(shell pwd)/articles:/virtual-zenn/articles -it $(NAME) zsh -c "npx zenn list:books"
	docker run -v $(shell pwd)/articles/stage:/virtual-zenn/articles -it $(NAME) zsh -c "npx zenn list:books"


.PHONY: create-book
create-book: docker-build docker-run-create-book

.PHONY: edit-book
edit-book: docker-build docker-run-edit-book

.PHONY: docker-run-create-book
docker-run-create-book:
	docker run -v $(shell pwd)/books/stage:/virtual-zenn/books -it $(NAME) zsh -c "npx zenn new:book"

.PHONY: upload-book
upload-book:
	mv $(shell pwd)/books/stage/* $(shell pwd)/books/ ; git add $(shell pwd)/books/ ; git commit -m "VIRTUALZENN: auto upload books" ; git push origin HEAD

.PHONY: docker-run-vim
docker-run-vim:
	open http://localhost:8001 ; docker run -p 8001:8000 -v $(shell pwd)/articles/stage:/virtual-zenn/articles -it $(NAME) zsh -c "npx zenn new:article ; npx zenn preview & ; vim articles"

.PHONY: docker-run-edit
docker-run-edit:
	open http://localhost:8002 ; docker run -p 8002:8000 -v $(shell pwd)/articles/stage:/virtual-zenn/articles -it $(NAME) zsh -c "npx zenn preview & ; vim articles"

.PHONY: docker-run-vim-book
docker-run-vim-book:
	open http://localhost:8003 ; docker run -p 8003:8000 -v $(shell pwd)/books/stage:/virtual-zenn/books -it $(NAME) zsh -c "npx zenn new:book ; npx zenn preview & ; vim books"

.PHONY: docker-run-edit-book
docker-run-edit-book:
	open http://localhost:8004 ; docker run -p 8004:8000 -v $(shell pwd)/books/stage:/virtual-zenn/books -it $(NAME) zsh -c "npx zenn preview & ; vim books"

私はよくvimを使うのでmakeをすると環境構築が始まり、zenn-cliをインストール、zennの記事を自動生成、プレビューを起動、vimを立ち上げる、という流れで自動化しています。

vimではなくて、お気に入りのエディターを使う場合も基本的な流れは同じなので、open等のコマンドやエディターのコマンド等で自動化ができると思います。

zenn-cliはナレッジを貯めることそのものをかっこよくしてくれて、ユーザの自由度が高い、可能性の秘めたツールだと思います。

どのようにナレッジを貯めて行くか、ということにはこれからもこだわるようにして、今回のvirtual-zennに関しても少しずつ改善を続けて行きたいと思います。

最後に

今回のvirtual-zennは私の執筆環境の一例です、これが正解でもないし、現状に満足してはならないと私自身思っております。
これからもZennとともに自らのナレッジベースのあり方を考え続けていきたいと思います。
一応、今回の設定ファイル等はvirtual-zennとしてMITライセンスで公開しています、フォーク等自由にしていただいて構いません。

こうした方がもっとかっこいいとか、これはナンセンスだ等ありましたら、コメント等いただけると幸いです。

おまけ

前回使用方法に関しての記事をあげた後にshellcheckエラーがでて使用できないことがありました。
この経験を踏まえてCI/CDを導入しました。

今回はGitHub Actionsを使用します。
次のようなディレクトリ構成にしておく必要があります。

 virtual-zenn
 └─.github
    └── workflows
        └── docker.yml

yamlファイルで実行したいワークフローを記述します。
今回は毎日一回チェックしてエラーが出ていないか確認します。

docker.yml
name: CI to Docker Hub
on:
    schedule:
        - cron:  '30 14 * * *' # 23 o'clock,30 min everyday

jobs:
    build:
        runs-on: ubuntu-latest
        steps:
            - name: Check Out Repo
              uses: actions/checkout@v2
            - name: Login to Docker Hub
              uses: docker/login-action@v1
              with:
                  username: ${{ secrets.DOCKER_HUB_USERNAME }}
                  password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
            - name: Set up Docker Buildx
              id: buildx
              uses: docker/setup-buildx-action@v1
            - name: Build and push
              id: docker_build
              uses: docker/build-push-action@v2
              with:
                    context: ./
                    file: ./Dockerfile
                    push: true
                    tags: ${{ secrets.DOCKER_HUB_USERNAME }}/simplewhale:latest
            - name: Image digest
              run: echo ${{ steps.docker_build.outputs.digest }}

            - name: Line Notify on Failure
              uses: snow-actions/line-notify@v1.0.0
              if: failure()
              with:
                access_token: ${{ secrets.LINE_KEY_NAME }}
                message: virtual-zenn failed build

このsecretsはGithubやDockerhub上での設定が必要です。
まず、Docker Hubにアクセスします。

https://hub.docker.com/

サインインができたら、次に右上にあるアイコンをクリックし、メニューを表示、以下の項目をクリックします。

次に、Security→New Access Tokenの順にクリック。

Tokenが表示されるので、適当にtitleなどを入力し、Copyしてウインドウを閉じます。

次にGithubにアクセスします。

https://github.com/

Setting→Secret→New repository secretをクリックしてそれぞれ先程のTokenやDocker Hubのユーザー名を設定します。


buildが失敗したらLINEに通知をします。@SnowCaitさんのアクションを使っています、便利です。
LINEに通知する方法は次を参考にしてください。

https://qiita.com/SnowCait/items/fa38222b616e56be1a84
https://github.com/snow-actions/line-notify

以上で設定は完了です。
これで毎日自動でActionが実行されます。

脚注
  1. 「Docker」ウィキペディア https://ja.wikipedia.org/wiki/Docker ↩︎

GitHubで編集を提案

Discussion