Zenn と Qiita の記事を GitHub でまとめて管理する方法

![zenn-qiita-cli-20231010.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1612505/f3e27920-c224-c5f5-adf1-c0b94d5be81b.jpeg)


## 概要

Qiita CLI の正式版[^1]が公開され、GitHub で Qiita の記事を管理することができるようになりました 🙌 これにより、Zenn と Qiita の記事を同一のリポジトリ内で管理することもできるようになったため、今回は **Zenn と Qiita それぞれの CLI の設定方法と GitHub で記事を管理する方法**について解説させていただきます。

Zenn CLI の設定方法[^2]と Qiita CLI の設定方法[^3]はそれぞれの公式ドキュメントを確認すれば設定可能です。両方とも設定済みの方は、「4. Makefile の作成・運用方法」まで読み飛ばしてください。

**この記事を読んでわかること**

- Zenn CLI と Qiita CLI の設定方法
- 同一の GitHub リポジトリ内で記事を管理する方法

**対象読者**

- CLI 経由で自分の書いた記事を管理したい人
- Zenn と Qiita 両方を利用していて記事の管理が面倒だと感じている人

**前提知識・実行環境**

この記事を読むに当たって下記の知識・実行環境を必要とします。

- Git・GitHub の基本的な知識・使用方法
- Makefile の基本的な知識
- `node`, `npm`, `make` コマンドが実行可能な環境
- Zenn, Qiita それぞれのアカウントが作成済みであること

---

## 1. Zenn と Qiita 管理用の GitHub リポジトリの準備

最初に記事を管理するための GitHub リポジトリを準備します。
方法はなんでも構いませんが、リモートリポジトリと同期させておいて下さい。

今回はリポジトリ名を `tech-blog` とします。

```shell
git clone https://github.com/(ユーザー名)/tech-blog
```

---

## 2. Zenn CLI の設定方法

Zenn 公式から公開されている Zenn CLI の設定方法[^1]と GitHub リポジトリで Zenn の記事を管理する方法[^4]と同様の手順を済ませます。

### 2.1. Zenn CLI のインストール

作成したリポジトリに移動して、`npm` コマンドで Zenn CLI をインストールします。
その後、`npx` コマンドで Zenn の記事を管理する環境を整えます。

```shell
# package.json の生成
npm init --yes

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

# Zenn CLI のバージョン確認
npx zenn -v

# Zenn 専用のディレクトリ生成
npx zenn init
```

`articles` ディレクトリがプロジェクトのルートに生成されていれば Zenn CLI の準備は完了です。次に GitHub リポジトリと Zenn のサービスを紐づけます。

### 2.2. Zenn と GitHub の連携

Zenn と GitHub リポジトリを連携させることで、指定したブランチにプッシュやプルリクエストがあった場合に自動で記事の変更内容が Zenn に反映されるようになります。

Zenn 公式のドキュメント[^4]を参考にして GitHub リポジトリとの連携を行います。公式ドキュメントにわかりやすく記載されているためこの工程の解説は省略させていただきます 🙇‍♂️

ここまでの工程が完了したら、Zenn 単体で GitHub から記事の管理が行える状態になります。
続いて Qiita CLI でも同様の作業を行っていきます。

---

## 3. Qiita CLI の設定方法

Qiita CLI の公式リポジトリ記載の README [^3]を参考にして設定を行っていきます。

### 3.1. Qiita CLI のインストール

Zenn CLI 設定の過程で package.json の作成は済ませてあるので、CLI をインストールします。
その後、`npx` コマンドで Qiita の記事を管理する環境を整えます。

```shell
# Qiita CLI のインストール
npm install @qiita/qiita-cli --save-dev

# Qiita CLI のバージョン確認
npx qiita version

# Qiita 専用のディレクトリ生成
npx qiita init
```

`public` ディレクトリや `publish.yml` が生成されていれば OK です。
次に Qiita の記事を操作するためのトークンの準備を行います。

### 3.2. Qiita のトークン発行・連携

Qiita 公式のドキュメント[^5]を参考に Qiita のアクセストークンを発行して連携を行います。

[Qiita のアクセストークン発行画面](https://qiita.com/settings/tokens/new)にログインした状態でアクセスして下さい。

トークンの権限に `read_qiita` と `write_qiita` の 2 種類を選択したトークンを発行します。

トークンをコピーして安全な場所に保管してください。

続けて下記のコマンドで、Qiita アカウントと連携を行います。

```shell
npx qiita login
```

コマンド実行直後にトークンの入力を求められるので、先程発行した Qiita トークンを入力して Enter キーを押します。Qiita トークンを発行したアカウントのユーザー名が表示されれば完了です。

### 3.3. Qiita と GitHub の連携

Zenn と同じく、Qiita の場合も指定のブランチにコミットがあった場合に自動で変更内容が反映させることができます。

まず、GitHub にログインした状態で `https://github.com/(ユーザー名)/(リポジトリ名)/settings/secrets/actions` にアクセスして下さい。この画面で `QIITA_TOKEN` の名前で先程発行した Qiita のアクセストークンを保存します。

変更を保存して、コミット・プッシュを行えば準備完了です。

#### 【補足】記事を公開するブランチ名を変更する

Qiita の場合、記事を管理するブランチがデフォルトで `main` または `master` となっています。
`npx qiita init` 実行時に生成された `publish.yml` ファイルのブランチ名を変更することで、好きなブランチで記事の管理をできるようになります。

Zenn CLI と併用して管理する場合はブランチ名を揃えておくと管理しやすいです。
ちなみに筆者はいずれも `main` ブランチで管理しています。

```yml:publish.yml
# Please set 'QIITA_TOKEN' secret to your repository
name: Publish articles

on:
  push:
    branches:
      - main   # ここでブランチ名を変更！
      - master
  workflow_dispatch:

permissions:
  contents: write

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: false

jobs:
  publish_articles:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: increments/qiita-cli/actions/publish@v1
        with:
          qiita-token: ${{ secrets.QIITA_TOKEN }}
          root: "."
```

ここまで完了すれば、Zenn と Qiita それぞれの CLI で定められているコマンドを利用して記事の管理を行えます。

記事執筆のたびに毎回別々のコマンドを実行するのは面倒なので Makefile を使って執筆・公開の作業コストを軽減します。

---

## 4. Makefile の作成・運用方法

Zenn CLI の場合は `npx zenn --help`、Qiita CLI の場合は `npx qiita help` で確認できるコマンドから執筆時にまとめて作業するコマンドを Makefile を使ってまとめて実行できるようにします。

プロジェクトのルートに下記の Makefile を作成します。

```shell:Makefile
# CLI のバージョン確認
.PHONY: version
version:
　　@echo "Zenn  CLI: v$$(npx zenn -v)" && echo "Qiita CLI: v$$(npx qiita version)"

# CLI のアップデート
.PHONY: update
update:
　　npm install zenn-cli@latest && npm install @qiita/qiita-cli@latest

# GitHub リポジトリと Qiita の記事の同期
.PHONY: pull
pull:
　　git pull && make npx qiita pull

# 新規記事の作成
.PHONY: new
new:
　　npx zenn new:article && npx qiita new

# CLI のヘルプ表示
.PHONY: help
help:
　　@echo "Zenn help =================================" && \
　　npx zenn --help && \
　　echo "\nQiita help ===============================\n" && \
　　npx qiita help
```

### Makefile を使った記事管理の流れ

先程の Makefile を使って記事を公開するまでの流れは下記のようになります。

1. `make pull` を実行して、GitHub リモートリポジトリと Qiita のリモート記事を同期させる
2. 記事公開用ブランチから記事執筆用のブランチを切り出す
3. `make new` を実行して、記事の下書きを作成する
4. Zenn, Qiita でそれぞれ執筆する
5. Zenn, Qiita の Markdown の差分を確認して修正する
6. コミット・プッシュする
7. 記事公開用ブランチに対してプルリクエストを出してマージする

Zenn CLI と Qiita CLI それぞれの専用コマンドを実行しなくても `make new` コマンドと Git コマンドを実行すれば簡単に簡単に管理できるようになりました 🙌

わざわざ記事執筆用のブランチを切り出してプルリクエストを出さなくても記事公開用のブランチに直接コミット・プッシュすれば公開はできます。筆者は誤って記事を公開してしまわないようにブランチを切り出すことにしました。

あとは Zenn の公式ドキュメント[^6]と Qiita の公式リポジトリの README[^3] に記載されているルールに従って記事を書くだけです。

---

## 5. Zenn と Qiita を同時に運用するときの課題

これまで説明してきた運用方法だと面倒な点が 3 箇所あります。

### 記事の二重管理をする必要がある

ほとんどコピペで済ませられるものの、Zenn と Qiita で記事の書き方が異なる箇所があるため別のファイルで記事の管理をする必要があります。
Zenn と Qiita いずれかの記事を書いてあとから他方のフォーマットに変換するプログラムを作れば改善されるかもしれません。

### Zenn と Qiita それぞれの専用 Markdown の書き換えをする必要がある

Zenn の Markdown 記法[^7]と Qiita の Markdown 記法[^8]は基本的に一般的に知られる Markdown 記法に対応していますが、それぞれに独自の記法が定められています。

例えばバナーテキストのような表現の場合、Zenn には 2 種類のバナーテキストが用意されており、Qiita は 3 種類あります。それぞれ書き方も異なるため、Zenn 用に書いた記事をそのままコピペして Qiita の記事にするような運用はできません。

```markdown:Zenn のバナーテキストの記述形式
:::message
メッセージをここに
:::

:::message alert
警告メッセージをここに
:::
```

```markdown:Qiita のバナーテキストの記述形式
:::note info
インフォメーション
info は省略可能です。
:::

:::note warn
警告
○○ に注意してください。
:::

:::note alert
より強い警告
○○ しないでください。
:::
```

`npx zenn preview`, `npx qiita preview` コマンドでそれぞれの記事のプレビューをローカル環境で確認することができるので...

- 表記の異なる部分は視覚的に確認して手直しする
- それぞれの独自の Markdown 記法を使用しない

のいずれかが良いかもしれません。

### Qiita CLI では画像アップロードができない

Zenn CLI の場合、Zenn 公式のドキュメント[^9]にあるようにプロジェクトのルートの `images` ディレクトリにアップロードしたい画像を設置しておけば、ローカル環境のパスの指定によって画像を使用することができます。

記事執筆時では Qiita CLI に同様の機能がないため、画像を使用している場合は...

- Zenn の記事で Web 上に公開された画像のアドレスをコピペして Qiita の記事に反映後、再びコミット・プッシュ
- GitHub リポジトリを公開して、GitHub の画像のアドレスを使用して、再びコミット・プッシュ
- Zenn の画像アップロード機能を使用せずに画像を管理する

など対応する必要があります。

---

最後まで読んでくださりありがとうございました 🙏
Zenn と Qiita それぞれの記事を同一のリポジトリで管理できるのはかなり便利ですね。

今回の運用方法の課題点は、独自の Markdown 記法を変換するプログラムを作成すれば解決できるかもしれません。時間ができたら作ってみようと思います 💪

[^1]: [自分のエディタで記事投稿ができる、Qiita CLI の正式版を公開しました！](https://blog.qiita.com/release-qiita-cli-general/)
[^2]: [Zenn CLI をインストールする](https://zenn.dev/zenn/articles/install-zenn-cli)
[^3]: [GitHub increments/qiita-cli](https://github.com/increments/qiita-cli)
[^4]: [GitHub リポジトリで Zenn のコンテンツを管理する](https://zenn.dev/zenn/articles/connect-to-github)
[^5]: [Qiita の記事を GitHub リポジトリで管理する方法](https://qiita.com/Qiita/items/32c79014509987541130)
[^6]: [Zenn CLI で記事・本を管理する方法](https://zenn.dev/zenn/articles/zenn-cli-guide)
[^7]: [Zenn の Markdown 記法一覧](https://zenn.dev/zenn/articles/markdown-guide#%E6%B3%A8%E9%87%88)
[^8]: [Markdown 記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
[^9]: [GitHub リポジトリ連携で画像をアップロードする方法](https://zenn.dev/zenn/articles/deploy-github-images)