##このサイトについて
このサイトについて
はじめまして。このサイトの最初の投稿です。
記念すべき1本目なので、このポートフォリオサイトがどういう仕組みで動いているのか、そしてなぜこの構成にしたのかを紹介します。
GitHubを丸ごとCMSにする
このサイトの一番の特徴は、管理画面を持たないことです。
記事も制作物も、すべてこのportfolioリポジトリのGitHub Issuesとして書いています。今読んでいるこの投稿も、実体は1つのIssueです。
- Issueのタイトル → 記事タイトル
- Issue本文 → Markdown本文
- ラベル → カテゴリ(
type:)・タグ(tag:)・公開状態(status:) - 作成日時・更新日時 → 投稿日・更新日
さらに、本文の先頭にHTMLコメントを1つ埋め込んで、descriptionやサムネイル画像などMarkdownで表現しづらいメタ情報もそこに含めています。ビルド時にこのコメントだけ抜き出してパースし、本文からは取り除いてから表示する、という形です。
普段からコードを書く延長で、Issueを立てるだけで記事が書ける。ブラウザでもGitHub CLIでもスマホアプリでも投稿できる。専用の管理画面を作らなくていい。この身軽さがやりたかったことです。
ビルドとデプロイの流れ
裏側の仕組みはシンプルです。
Issueが作成・編集されたり、ラベルが変わったりすると、GitHub Actionsが起動します。GraphQL経由で公開状態のIssueをすべて取得し、Astroで静的サイトとしてビルドして、GitHub Pagesに自動デプロイする、という流れです。
ラベルにはstatus:draft / status:published / status:archivedのような公開状態を持たせていて、status:publishedが付いたタイミングで初めてサイトに反映されます。逆に外せば、サイトから消えます。
Issueの取得からAstroのページに載るまでの間には、もう少し細かい工程があります。
status:ラベルが変化した時点で、まずzodスキーマによるバリデーションが走ります。ステータスやタイプのラベルが重複していないか、必須のメタ情報が揃っているかをCI上でチェックし、問題があればstatus:draftに戻してデプロイを止めます- バリデーションを通過したら、AstroののカスタムローダーとしてIssue一覧を取得し、記事データに変換します
- 本文中の画像はGitHubの添付リンクのままだと消える可能性があるため、ビルド時にダウンロードして
public配下に保存し直しています。使われなくなった画像はcleanAssetsスクリプトで定期的に掃除しています
かなり地味な工程の積み重ねですが、これのおかげで「ラベルを貼るだけで安全に公開できる」という体験が成り立っています。
使っている技術
- Astro — 静的サイトジェネレーター。表示速度を重視
- TypeScript
- Vanilla CSS — フレームワークに頼らず素のCSSで組んでいます
- GitHub Actions / GitHub Pages — ビルドと公開
- GitHub GraphQL API — Issueの取得
サーバーもデータベースも持たない、完全に静的なサイトです。
これから
コア機能の実装は完了したので、Beta版リリースへ向けサイトのデザインを主に整えていきます。また、タグの検索や表示の機能を追加しサイトを完成させ、継続的な記事執筆や制作物の更新を行っていきます。。