こんにちは、全力開発部の @konoka-iori です。

今回も、「全力開発ブログの作り方」シリーズの記事です。

このシリーズでは、

  • メンバーがどのようにして全力開発ブログに記事を投稿しているか
  • 記事を投稿するにあたって、守るべきルールやコーディング規約にはどんなものがあるのか
  • 全力開発ブログのリポジトリの構成や運用方法はどのようなものか
  • 全力開発ブログのカスタマイズについて

など、全力開発ブログの裏側についてご紹介いたします。

今回の記事では、全力開発ブログでのリポジトリの運用方法についてご紹介します。

以前の記事では、WordPressからHugoに移行した経緯や、textlintとMarkdownlintの導入についてご紹介しました。ぜひこちらもご覧ください。

WordPressからHugoに移行してみた - 全力開発ブログ

全力開発ブログの作り方:textlintとMarkdownlintで品質を維持する - 全力開発ブログ

リポジトリの構成

全力開発ブログのリポジトリは、GitHubでホスティングされています。

当初、リポジトリをpublicにすることを検討していましたが、シャイなメンバーにも気軽にコントリビュートしてもらえるように、privateリポジトリで運用することにしました。

そのため、全力開発部のメンバー以外はリポジトリにアクセスすることができませんが、この記事で公開できる範囲のことは全力でお伝えしていこうと思います。

全力開発ブログのリポジトリは、以下の2つのリポジトリに分かれています

  1. サイト本体のリポジトリ(Hugoでサイトが構築され、Cloudflare Pagesにデプロイされるもの)
  2. 記事のリポジトリ(メンバーが記事を投稿するためのもの)

サイト本体のリポジトリと記事のリポジトリを分けることで、管理を簡単かつより安全にしています。

サイト本体のリポジトリはサイトのカスタマイズやデプロイに特化し、記事のリポジトリは執筆や記事のレビューに特化しています。

メンバーはサイト本体のカスタマイズは行わないので、記事のリポジトリだけを操作すればよい設計にすることで、誤ってサイトに影響を与えるコミットをすることを防ぎます。

サイト本体のリポジトリ

サイト本体のリポジトリは、一般的なHugoのリポジトリと同じように構成されています。

このリポジトリを使って、サイトのカスタマイズやデプロイを行っています。

ざっくりまとめると、以下のような構成になっています。

blog.zenryoku.dev
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
.
├── .devcontainer         # Dev Containerの設定
│   └── devcontainer.json
├── blog.zenryoku.dev     # Hugoのサイト本体
│   ├── assets           # CSSなどのリソース
│   ├── content          # 記事データ
│   ├── hugo.yaml        # Hugoの設定ファイル
│   ├── layouts          # テンプレートファイル
│   ├── node_modules     # Font Awesomeの依存関係など
│   ├── static           # フォントなどの静的ファイル
│   └── themes           # テーマファイル
├── .gitmodules           # テーマをサブモジュールとして管理
├── posts_sync.bash       # 記事のリポジトリとサイト本体のリポジトリを同期するスクリプト
├── public_delete.bash    # publicディレクトリをお掃除するスクリプト
└── README.md

開発環境

.devcontainer/devcontainer.json には、

  • Hugoの開発環境
  • Node package managerによるFont Awesomeの依存関係
  • VS Codeの設定 などを記述しています。

Dev Containerにおいては、以下のように featuresghcr.io/devcontainers/features/hugo:1 を記述するだけで良い感じにHugoの開発環境を構築してくれるので非常に便利です。

Hugoのバージョンは 公式のリポジトリ を確認して数字のみを記入します。

./.devcontainer/devcontainer.json
1
2
3
4
5
6
7
{
"features": {
  "ghcr.io/devcontainers/features/hugo:1": {
    "version": "0.139.2" // このように書くことでHugoのバージョンを指定できる。
    }
  },
}

記事の同期

posts_sync.bash を使って、後述する記事のリポジトリ(のmainブランチをcloneしたもの)と、サイト本体の posts/ ディレクトリを同期しています。 中身はこんな感じで、rsync で記事のリポジトリ(SOURCE_DIR)とサイト本体のリポジトリ(TARGET_DIR)を同期するだけのシンプルなスクリプトです。

posts_sync.bash
1
2
3
4
#!/bin/bash
SOURCE_DIR="../Contents-of-blog.Zenryoku.dev/posts"
TARGET_DIR="blog.zenryoku.dev/content/posts"
rsync -av --delete "$SOURCE_DIR/" "$TARGET_DIR/"

デプロイとブランチの保護

このリポジトリのmainブランチにコミットすることで自動的にCloudflare Pagesにデプロイされます。

つまり、mainブランチに誤って開発中のものをプッシュしてしまった場合はそれがそのまま本番環境に適用されてしまいます。

そこで、GitHubの Rulesets を使ってmainブランチに保護をかけています。

直接プッシュの事故を防止したいだけですので、とくに難しい設定はしていません。 以下のような設定を行っています。

  • mainブランチへの直接プッシュを禁止する
  • マージ前のプルリクエストを必須にする
  • プルリクエストのステータスチェック(デプロイが成功しているか)を必須にする
  • プルリクエストのレビューを必須にする

記事のリポジトリ

記事のリポジトリは、全力開発部のメンバーが記事を投稿・管理するためのリポジトリです。

以下のような構成になっています。

Contents-of-blog.Zenryoku.dev
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.
├── .devcontainer/                        # Dev Containerの設定
│   └── devcontainer.json
├── .github/
│   ├── .markdownlint.json               # MarkdownLintの設定ファイル
│   ├── CODEOWNERS                       # 記事の執筆担当者などを記載
│   ├── ISSUE_TEMPLATE/
│   │   ├── delete_post_proposal.yml    # 記事削除申請のテンプレート
│   │   ├── edit_post_proposal.yml      # 既存記事の編集申請のテンプレート
│   │   ├── new_post_proposal.yml       # 新規記事の提案のテンプレート
│   │   ├── textlint.yml                # textlintに関する質問や要望についてのテンプレート
│   │   └── question.yml                # 書き方や作業フロー、ルールについての質問のテンプレート
│   ├── pull_request_template.md         # 記事レビュー申請のテンプレート
│   └── workflows/
│       └── auto_check.yml               # PR時にいろいろ自動チェックするGitHub Actions
├── .vscode/
│   └── shortcode.code-snippets          # Hugoのショートコードのスニペット
├── docs/
│   ├── CONTRIBUTING.md                  # 環境構築手順などを記載
│   ├── README.md
│   ├── 執筆にあたって.md                # 執筆に役立つ情報を記載
│   └── 記事採用基準.md                  # 記事を投稿するための基準
├── posts/                                # 記事データ
├── .textlintrc                           # textlintの設定
├── LICENSE
└── package.json                          # textlintの動作に必要なパッケージ

開発(執筆)環境

こちらの .devcontainer/devcontainer.json には、

  • Node package managerによるtextlintの依存関係
  • VS Codeの設定
  • 執筆に便利な拡張機能(Markdownlint、文字数カウンター、draw.io、Markdown All in Oneなど)

などを記述しています。

textlintやMarkdownlintの導入経緯や採用しているルールセットなどは以下の記事をご覧ください。

全力開発ブログの作り方:textlintとMarkdownlintで品質を維持する - 全力開発ブログ

執筆フローやレビュー工程については後日別記事でご紹介します。

ブランチの保護

記事リポジトリのmainブランチが、サイト本体のリポジトリの posts_sync.bash で同期されるため、mainブランチには記事のデータを直接プッシュしてしまうと、執筆中の記事がうっかりサイト本体のリポジトリに記事が同期されてしまう可能性があります。

そのため、記事リポジトリのmainブランチにも保護をかけています。

  • mainブランチへの直接プッシュを禁止する
  • マージ前のプルリクエストを必須にする
  • プルリクエストのステータスチェック(textlintやMarkdownlintのチェック)を必須にする
  • プルリクエストのレビューを必須にする(主にCODEOWNERSに記載されたメンバーがレビューを行う)
  • プルリクエストのマージを許可するのは、リポジトリの管理者のみ

CODEOWNERSの運用

GitHubには CODEOWNERS という機能があり、Rulesetと組み合わせることでリポジトリ内のファイルやディレクトリに対して、特定のユーザーまたはチームを指定してレビューを必須にできます。

全力開発ブログでは、記事の執筆者および編集者を CODEOWNERS に記載して管理しています。

たとえば、 この記事の場合 は執筆者が @Rustumi-Hinata で、編集者は @konoka-iori ですので、以下のように記載されています。

.github/CODEOWNERS
1
posts/win11-setup-wifi-delete/* @Rustumi-Hinata @konoka-iori

このようにすることで、後に記事の内容を変更するプルリクエストを作成した際、自動で記事の執筆者や編集者にレビューを依頼できます。

また、GitHub上でファイルを確認するときに所有者が表示されるので、記事の執筆者や編集者が誰なのかをすぐに確認できるのも地味に便利です。

課題

全力開発ブログのリポジトリの運用方法についてご紹介しましたが、まだまだ課題があります。

記事の同期が手動で煩雑

記事のリポジトリとサイト本体のリポジトリの同期を自動化するスクリプトが、手動で実行する必要があります。

これをGitHub Actionsなどで自動化することで、記事のリポジトリにコミットがあった際に自動でサイト本体のリポジトリへ反映されるようにしたいです。

また、現在VS Codeのワークスペース機能を使ってサイト本体のリポジトリと記事のリポジトリを(半ば強引に)同時に開いているのですが、フローが煩雑でトラブルの元になっていたこともあったため、別の方法を模索したいと考えています。

Note

記事のリポジトリがpublicであれば、記事のリポジトリをサブモジュールとして追加すれば同期を自動化できるかもしれませんが、現状privateリポジトリで運用しているため、この方法は使えません。

前に一度試したらCloudflare側で「サブモジュールがprivateでクローンできないよ~」などというエラーが出たのでいったん断念しました。

ドキュメント類の更新が追いついていない

記事の執筆にあたって役立つ情報や、記事の採用基準などのドキュメントはWordPress時代のものがベースになっています。 移行と同時に内容を更新したものもありますが、一部古い情報が残っています。

また、移行してからも常にメンバーからのフィードバックや気づき、新しく得た知見などを元に環境を継続的かつ頻繁に改善しています。

改善に伴って大きな変更もいくつか発生しており(ご迷惑をおかけしております)、その都度メンバーには変更内容と対応方法を共有しているもののナレッジの整理やドキュメント化が追いついていない状況です。

CODEOWNERSの運用が手動

CODEOWNERSは、現状すべて手動で運用されており、記事の追加等の変更があった際には都度CODEOWNERSに追記する必要があります。

CODEOWNERSの更新はプルリクエストがあった際にレビュー担当者が行っていますが、これを自動化してレビュアーの負担を減らしたいと考えています。

これもGitHub Actionsを使って自動化できそうだと考えていますが、現状具体的な解決策はまだ決まっていません。

まとめ

人手がほしい!

課題や「ここをこうしたい」という要望などなど、取り組みたいことが山積みですが、まったく追いついていないのが実情です。

日々、全力開発を積み重ねて、この全力開発ブログの運用もより良いものにしていきたいですね。

変更点や新しい取り組みなどは、適宜記事にするつもりです。

この全力開発ブログが誰かの参考になっていれば幸いです。