この記事はCraft Extensionから送信されました

✍🏼 作成日 2021年12月08日    💡 更新日 2022年02月28日
❗️ 注意:この記事が作成されてから既に 日が経過しています。情報の鮮度にご注意ください

本記事で説明されている一部のワークフローは廃止されました。新しいワークフローのロジックはこちらです:https://www.xheldon.com/tech/my-blog-ci-in-2022.html

2日間かけて、Craftでコンテンツを書き、自作のプラグインを使ってGithubリポジトリに同期し、Githubリポジトリが自動的にGithub Pagesをビルドするプロセスを簡単に実装しました。

リポジトリアドレス:https://github.com/craft-extension/craft-github-extension

ブログ更新フローの変更

以前のフロー

VSCodeで執筆 → x_blog_srcリポジトリにコミット → Gihutb Actionがトリガー → ビルド後にx_blogリポジトリにコミット → 成功

しかし、このプロセスにはいくつかの課題がありました:

  1. 記事を一気に書き上げるのではなく、断続的に執筆する場合、会社のPCで一部を書いた後、一旦Githubにコミットし、自宅のPCで続きを書く必要があります。この場合、コミットするたびにGithub Actionがトリガーされます。私の解決策は、コミットメッセージに特定のプレフィックスが含まれているかどうかで判断し、含まれていればビルド、含まれていなければそのコミットを無視するというものでしたが、やはり洗練されていません。

  2. 別の方法として、まず_draftディレクトリで執筆し、自由にコミットできるようにし、完成後に記事を_postディレクトリに移動するというものもあります。しかし、先ほど述べたように、依然として洗練されていません。

  3. さらに、Jekyllのconfigで未来の記事を表示しないように設定する方法もあります。つまり、未完成の記事のmetaに2099年などの日付を設定しておけば、Jekyllは未来の日付の記事をビルドしませんが、Github Actionは依然としてトリガーされ、ファイルが更新されます。これも洗練されていません。

  4. 時々、Craftの美しさ(見た目が良い)と便利さ(どこでも編集可能でマルチデバイス同期)に惹かれ、Craftで記事を書き、完成後にMarkdownとしてエクスポートし、手動で画像をx_blog-staticリポジトリにアップロードし、Markdownの画像参照リンクを修正し、その後MarkdownをGithubリポジトリにコミットするという非常に長いプロセスを取っていました。

現在のフロー

Craftで執筆 → x_blog_srcリポジトリにコミット → Gihutb Actionがトリガー → ビルド後にx_blogリポジトリにコミット → 成功

以前との違いは、最初からVSCodeで書くのではなく、直接Craftで書くようになったことです。以前の方法の4番目のように、Craftの美しさを享受しながら、Githubへの同期の手間を減らすことができます。画像(後述)を除けば、ドキュメントの同期は非常に完璧なソリューションです。そのため、今後はブログの更新頻度が上がるかもしれません(以前はプロセスが複雑すぎて執筆が遅れていました)。コンテンツにより集中できるようになり、素晴らしいです!

説明

使用上の設定は以下の通りです:

  1. 本プラグインは現在個人利用のみを想定しているため、一部の設定は個別にハードコードされています。例えば、ファイルのアップロード先は _posts ディレクトリのみに対応しています。ユーザーが増えた場合には、より汎用的な設計にするため時間をかける予定ですが、現状は個人利用のため簡易的な実装となっています。

  2. Github Personal Tokenが必要です。これはGithubのRest APIを介してMarkdownコンテンツを指定のGithubリポジトリに同期するために使用されます。

  3. Github APIはコンテンツをリポジトリに送信する際、ソースリポジトリと既存リポジトリのsha値を比較します。これらが完全に同一の場合、更新されたファイルにはcommit情報が表示されず、commit情報を確認すると0 files changesと表示されます。

  4. 記事の最初のブロックは必ず2列のテーブル形式で、Jekyllのmeta情報として扱われます。現在、pathを除く全ての内容がmeta情報として扱われています。

  5. 記事のtitleはブログ記事のtitleとして扱われるため、meta情報に記載する必要はありません。

  6. 2021年12月9日時点での検証では、Craftが提供するAPI craftBlockToMarkdown で出力されるMarkdownは、ドキュメント内のBlockquoteスタイル(Craft BlockではDecoration内のFocusと呼ばれる)を正しく出力できませんでした。公式ではこれをバグと認識しており、今後のバージョンで修正予定とのことです。カスタムMarkdownを生成したい場合は、自前でBlockを走査する必要があります。その他の機能については未検証です。

  7. 現在のプラグインの設定項目はあまりユーザーフレンドリーではありません。今後のアップデートで改善予定です。

  8. CraftのMarkdownレイアウトは比較的見栄えが良い設計です。例えばlistの下にparagraphやimageを埋め込んで、listの内容と整列させることが可能です。しかし標準のMarkdownではこのような記述がサポートされていないため、出力されるスタイルは見た目が劣化する場合があります。

  9. meta情報に複数行の情報(例えばtagsなど)を含める場合、-: で区切ることができます。例: -:テスト-:サーバー

  10. CraftのMarkdown APIでは common フォーマット(デフォルト、現在のプラグインでは設定不可)の使用を推奨します。bear フォーマットを使用すると、画像の前に ! が付かず、Githubがリンクとして認識してしまう可能性があります。

  11. Craftの「深度Markdownリンク」などの機能は標準Markdownの構文ではないため、本プラグインでのサポートは未検証です。

  12. 公式ドキュメントによると、Web版のstorageApiは暗号化されていないため、保存時にユーザーに注意を促す必要があります。詳細はこちらを参照してください。Mac版ではこの問題は発生しません。分析によると、Web版のstorageApiはSessionStorageに保存されていましたが、後で確認したところ、IndexedDB(plugindata-storageという名前のDB)に変更されていました(開発者プレビュー版なので変更が速いですね…)。Mac版では、ユーザーワークスペースを切り替えたためStorageも消えてしまい、フィードバックを送信しましたが、公式からの返信はまだありません :-(。

  13. Mac版のstorageApiには競合状態の問題があるため、プラグインを最初に読み込んだ直後にstorageApiでデータを読み取ろうとしても取得できません。そのため、私のプラグインでは、Macの場合は3秒遅延させてプラグインを初期化するように処理しています。Web版にはこの制限はありません。

  14. その他の設定サポートは現在進行中…

画像に関する問題

  1. Web版でもアプリ版でも、Craftにアップロードした画像は、Web版で表示時に要素を検査すると必ず.jpg形式で表示されます。しかし、CraftのMarkdown APIで生成した後、.png形式に変わっていましたというのは誤解で、画像の拡張子はアップロード時の形式に依存し、Craftが形式を変換することはありません。

  2. ドキュメントで要素を検査した際に表示される画像のURLドメインはres.craft.doであり、Githubリポジトリでソースファイルを確認したときもこのアドレスが表示されます。しかし、Githubで画像をプレビューする場合(つまりリポジトリのmdファイルを直接クリックして開いたとき)はhttps://camo.githubusercontent.comというアドレスになります。Githubがmd内の画像を自社サーバーに転送してくれると思いきや、実際はGithubがセキュリティ上の理由から、サードパーティの画像をレンダリングする際に一時的に転送しているだけです。

  3. サーバーサイドに依存しない場合、Craftにアップロードした画像をCraft API経由で取得しようとしても、フロントエンドのfetchなどでは取得できず、CORSエラーが発生します。そのため、記事をGithubにアップロードする際に記事内の画像を抽出して自分の画像ホスティング/COS/Githubリポジトリにアップロードしたい場合、純粋なフロントエンドでは実現できません。サーバーサイドで画像を取得して転送する必要があります。また、CraftのimageBlockの画像アドレスはAWSのS3にホストされており、腾讯云などの国内サーバーから取得しようとするとタイムアウトしたり遅くなったりする可能性があります。ただし、海外サーバーから国内にプッシュする場合は速度は問題ないようですので、AWSのサービスを使って画像を転送することをお勧めします(追記:現在はVercelを使用しています。詳細はこの記事を参照してください)。


ここに画像を1枚配置して、速度をテストします:

Image

その他

  1. テンプレート用のプラグインを開発予定で、アドレスはこちら:https://github.com/craft-extension/craft-template-extension

  2. すべてのプラグインはこのツールをベースに開発されています:https://github.com/craft-extension/craft-dev-toolkit 公式サンプルに加えて、UIにantdを使用するなどの設定を追加しました。今後ユーザーが増えれば、スキャフォールドによるプラグイン開発環境の生成など、さらに多くの設定を追加する予定です。

  3. その他のプラグインにご期待ください…

2022.01.24 更新

画像に関する問題について、Githubにバックアップせず(Craft内の画像がバックアップと同等と考え)、直接Tencent Cloud COSにアップロードする案を検討中です。ただし、Tencent Cloud COSはリクエストを送信する必要があり、使用するリクエストメソッドはrequestライブラリで、さらに署名などの情報を追加するためにラップされています。COSのソースコードを確認したところ、リクエストツールを設定可能であることがわかり、現在以下の2つの方法で目的を達成できます:

  1. COSが使用するrequestライブラリのメソッドをオーバーライドする。

  2. COS内のリクエストコードをオーバーライドする。

  3. ドキュメントに記載されているサンプルに従い、署名を構築してリクエストを行う。

明らかに、3番目の方法が最も簡単なので採用しました。

2022.02.28 更新

01.24の案は廃止しました。コストが高すぎます。最終的な解決策は、画像をGithubにアップロードせず、Vercelのサービスを介してTencent Cloudに転送・保存することです。これで画像の問題が解決し、Craftで記事を書くのがさらに楽しくなりました。

- EOF -
この記事の初出: この記事はCraft Extensionから送信されました - Xheldon Blog