Zenn / Qiitaに投稿する同じ記事を一元管理するGitHubリポジトリを作ってみた


# WHY

- QiitaとZenn2箇所に記事を2回投稿するのは面倒である
- スクリーンショットをローカルでmdに追加したときに、プラットフォームにコピペすると記事に反映されないのが嫌なのでその辺りの解決も同時にやりたかった

# DO

以下の先駆者様たちとやっていることはほぼ同じで基本的にはこちらに沿っていけば問題なくできるかと思います。

- [ot07様](https://zenn.dev/ot07/articles/zenn-qiita-article-centralized)
- [ジニア様](https://zenn.dev/shun1997/articles/zenn-qiita-integration-tools)

ただ、そのままでは不都合であったことがいくつかあったのとそれぞれの記事で解説がなかったことで少し難儀した部分もあったので以下で共有したいなと思います。
なお上記の記事を先に閲覧されていることを前提に以下はお話します。

## actionsの変更

ot07様の記事で紹介されているリポジトリの内の`action.yml`では`qiita-cli`のバージョンが`0.3.0`であった。
これはどうやらnodeのバージョンによっては`QiitaNotFoundError`という例外を発生させてしまうようなので最新または使用しているnodeのバージョンに合わせたものに変更しましょう。
(2024年1月8日現在。 当方のnodeのバージョンは18.16.0でqiita-cliのバージョンを1.3.1に変更しました)

変更箇所は以下。

```
runs:
  using: 'composite'
  steps:
    - uses: actions/setup-node@v3
      with:
        node-version: '18.16.0'
    - name: Install qiita-cli
      run: npm install -g @qiita/qiita-cli@v1.3.1 # ここ

```

## 記事執筆に関して必須項目について

こちらZenn CLI 及び Qiita CLIの仕様で各々必要事項の記載が対象のmdファイルにないとエラーになります。
Zennの記事をQiita用の記事に変換するのが仕様になるので例えばZenn側では

```md

---
title: hogehoge
emoji: 📝
type: tech
topics:
  - zenn
  - qiita
published: true
---

```

と言ったものが必須になりますがこれをQiita用に

```md
title: hogehoge
tags:
  - zenn
  - qiita
private: false
updated_at: '2024-01-08T03:21:19+09:00'
id: ab0cb9b2ac1adbeb2094
organization_url_name: null
slide: false
ignorePublish: false

```

と変更することをやっています。
Qiitaのほうがやや必要な情報が多いのが少しネック。


## 変換した記事データ(frontmatter)の中にslide属性を入れることについて

上記にもあった`slide`というパラメータはジニア様の記事で言及されていた`qiita-cli v0.5.0`で行われた破壊的な変更。
こちらはQiita側の記事に関わることでQiita記事のスライドモードを許可するか否かというフラグになります。
実はactionsが回った後既存の公開済みの記事が`qiita/public`配下へ入るのですが、厄介なことにqiita-cliのバージョンがv0.5.0以下だと`slide`パラメータなしの状態になり、その後バージョンを上げると以下の通りactionsで落ちます。

![](https://raw.githubusercontent.com/t-kibu/zenn-content-kibu/feature/zenncli-and-qiita/images/articles/20240108-zenncli_qiitacli/image.png)

実際に試される際にはqiita-cliのバージョンにお気をつけください。

## qiita/public配下について

`qiita/public`配下のmdファイルは削除してもQiitaの公開している記事には影響がありません(削除されない)。
ただし、内容を編集するとその内容は反映されます。

## スクリーンショットについて

vscodeを使用されている方はスクリーンショットや画像をmdファイル中に配置することができると思いますが、vscodeのバージョンが新しいと

`![](../images/articles/hogehoge/image.png)`

といったPathになってしまうと思います。
こちらはZenn CLIの仕様でNGとなってしまうので必ず

`![](https://raw.githubusercontent.com/t-kibu/zenn-content-kibu/feature/zenncli-and-qiita/images/articles/hogehoge/image.png)`

と変更しておきましょう。
(スクリーンショット添付の拡張機能がvscodeに統合される前はこんなことはなかったそうな)

## syncAndUpload.shについて

ジニア様の記事での一連の処理をコマンドを叩くだけでgitへのpushまで行ってくれてactionsを自動で回してくれて、結果記事の投稿の自動化になっているシェルスクリプトですがこちらはどうもactions実行時に`[skip ci] Updated by qiita-cli`というcommitを自動で発行するようで、これをpullせずにpushをしていまうとrejectedが起きてpushができなくなるという状態になってしまうことがままありました。

なので障害が起きたときの検証用も兼ねて以下の通りPathを指定して個別に記事の変換処理をできるようにしてみました。
といっても単純にコマンドにPathの入力を強制しているだけですが。
git push等は行わないようにしています。

```
#!/bin/bash

FILE=${1}

# ファイルのパスがarticles配下ではないまたはファイルが存在しない場合、処理をスキップ
if [[ ! $FILE =~ ^articles/ ]] || [[ ! -e $FILE ]]; then
    echo "Skip ztoq: $FILE"
    continue
fi

# .md拡張子を削除してファイル名を取得
FILENAME=$(basename $FILE .md)

# ファイル名と同じファイルがqiita/public配下に存在しない場合だけ、npx qiita newを実行
if [ ! -e "qiita/public/$FILENAME.md" ]; then
    echo "Create qiita/public/$FILENAME.md"
    cd ./qiita
    npx qiita new "$FILENAME"
    cd ../
fi

# ./node_modules/.bin/ts-node scripts/ztoq.ts "取得したファイルパス" qiita/public/"取得したファイル名.md"を実行
./node_modules/.bin/ts-node scripts/ztoq.ts "$FILE" "qiita/public/$FILENAME.md"
echo "Convert $FILE to qiita/public/$FILENAME.md"


```
# 終わり

やや難儀することがいくつかありましたが先駆者のお二人の記事とソースを見ながら今現在は正常に運用できています。
ただし、qiita-cli及びZenn CLIの仕様変更によっては動かなくなるのは必然なのでその辺りをきちんとキャッチアップしつつ、メンテしていく必要はあることを考えると結構手間ではあるかなと。
2つのプラットフォームで書かなくてもいいのでは？ ということかもしれませんね。

# 追記
qiita側はGithubのリポジトリ上から画像を取ってくるようになっているため、privateリポジトリだと画像が404で取れない模様。
管理するリポジトリはprivateにしておきたいので困ったもの......