HonKitで生成された静的サイトをGitHub Actionsを使ってGitHub Pagesにデプロイする

# HonKit

開発用のドキュメントExcelなのつらいわーと思い、Markdownで書いたドキュメントを静的サイトとして出力できる[VitePress](https://vitepress.dev/)のようなものを探していて、見つけたのが[HonKit](https://github.com/honkit/honkit)でした。

ちなみに↓HonKitのドキュメントもHonKitで作成されているので、どういう見た目で作成されるかの参考になります。

https://honkit.netlify.app/

ドキュメントをPDFとして出力することも可能です（私の環境ではうまくいかなかったので、Chromeの印刷プレビューからPDF生成しています:sweat:）。

シンプルですが最低限必要な機能はあり、カスタマイズもできそうです。
ドキュメントの脱Excel、かつGit管理したいというので使ってみることにしました。

```sh
# HonKitのインストール
npm install honkit --save-dev
# bookの作成
npx honkit init
```

`package.json`の`scripts`に`honkit`コマンドを追加して、

```json:package.json
{
  "scripts": {
    "serve": "honkit serve",
    "build": "honkit build"
  }
}
```

`npm run ...`で表示確認ができるようになります。:smile:

```sh
# プレビュー表示
npm run serve
# 静的サイトのビルド（デフォルトでは_bookディレクトリ以下に生成される）
npm run build
```

![screenshot_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961694/272c5918-9a4b-610d-a549-089dd340d758.jpeg)


# GitHub Pages

せっかく静的サイトとして出力してくれるのだから、他の開発メンバーもインターネットからアクセスできるようにしたら便利。

というわけで、[GitHub Pages](https://docs.github.com/ja/pages/getting-started-with-github-pages/about-github-pages)を使い、`HonKit`で生成された静的サイトを開発メンバー向けに公開してみることにしました。

https://docs.github.com/ja/pages/getting-started-with-github-pages/about-github-pages

リポジトリの`Settings > Pages`から設定ができます。

`GitHub Enterprise Cloud`を使用している場合はアクセス制御が可能です。社内向けのドキュメントだとアクセス制御できるのが嬉しい:relaxed:

> プライベートで公開されたサイトは、サイトの公開元のリポジトリの読み取りアクセスを持っている人だけがアクセスできます。 
[GitHub Pages サイトの可視性を変更する](https://docs.github.com/ja/enterprise-cloud@latest/pages/getting-started-with-github-pages/changing-the-visibility-of-your-github-pages-site)

GitHub Pagesの公開用として特定のリポジトリと、`/`（ルート）か`/docs`のフォルダを指定することもできますが[^1]、今回は`GitHub Actions`を使ってビルド → デプロイが自動で実行されるようにしてみます。

[^1]: 例えば`master`ブランチの`/docs`を公開用と指定した場合、`master`にpushされた際に`/docs`の静的サイトがGitHub Pagesとして公開されます。設定方法の詳細は「[GitHub Pages サイトの公開元を設定する > ブランチからの公開](https://docs.github.com/ja/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#publishing-from-a-branch)」へ

# GitHub Actions

`Settings > Pages > Build and deployment`のSourceで`GitHub Actions`を選択します。

![screenshot_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961694/1dfce07f-9401-3ef6-ec25-a130e7df3b40.jpeg)


`Jekyll`を使ったワークフローと`static HTML`のワークフローを提案してくれるので、今回は[static HTMLのスターターワークフロー](https://github.com/actions/starter-workflows/blob/main/pages/static.yml)をベースに[参考サイトのワークフロー](https://developer.mamezou-tech.com/blogs/2022/09/08/github-pages-new-deploy-method/)を参考にさせていただきつつ、cacheを利用し、`HonKit`のビルド → `GitHub Pages`へのデプロイを行うワークフローを作成しました。

## 作成したワークフロー

今回作成したワークフローは以下になります。

masterブランチへのプッシュ（または手動でアクション実行）で起動します。

```yaml:build.yml
# HonKitのビルドとGitHub Pagesへのデプロイを行う
name: build HonKit and deploy Pages

# ワークフローのトリガーイベント：
on:
  # masterブランチへのpush
  push:
    branches: ["master"]

  # Actionsタブから手動実行
  workflow_dispatch:

# GitHub Pagesへのデプロイを可能にするGITHUB_TOKENの権限をセット
permissions:
  contents: read
  pages: write
  id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  # ビルド
  build:
    # ランナー
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Setup Pages
        uses: actions/configure-pages@v3
      # Node.jsのセットアップ
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version-file: 'package.json'
          cache: 'npm'
      # パッケージのインストール
      - name: Install dependencies
        run: npm ci
      # HonKitのビルド
      - name: build HonKit
        run: npm run build
      # .htmlに空白が多いのでフォーマット
      - name: format
        # 以下コマンドでprettierが起動するようにpackage.jsonで設定しています
        run: npm run format
      # アーティファクトのアップロード
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v1
        with:
          # _book/以下をアップロード
          path: '_book/'

  # デプロイ
  deploy:
    needs: build
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v2
```
### `actions/setup-node@v3`の設定について

使用しているアクションの内、[actions/setup-node@v3](https://github.com/actions/setup-node)について簡単に説明します。

#### Nodeのバージョン指定

今回は`package.json`を用いて`Node`のバージョンを指定しています。

```yaml:build.yml抜粋
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          # Nodeバージョン指定
          node-version-file: 'package.json'
          cache: 'npm'
```
`node-version-file: 'package.json'`とした場合、アクションは最初に`volta.node`を検索し、なければ`engines.node`を検索します。

https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md#node-version-file

余談ですが、以前あるフロントエンド開発で、`package.json`でNodeのバージョンを指定しなかったばかりに、開発者間のローカル環境で挙動が違う！ということがあったので、`volta.node`か`engines.node`でNodeのバージョンを指定したいと思うようになりました:sweat_smile:

```json:package.json
{
  "engines": {
    "node": "18.15.0"
  },
  "volta": {
    "node": "18.15.0"
  }
}
```
<details><summary>Voltaって何？</summary>

[Volta](https://volta.sh/)はJavaScript コマンドライン ツールを簡単に管理してくれます。

自分が使う時は、先述のようにプロジェクトでNodeのバージョンを固定したい場合に使用しています。

以下記事が分かりやすかったので、気になった方はぜひ。

- 「[Node.jsのバージョン管理にVoltaを推したい](https://zenn.dev/taichifukumoto/articles/how-to-use-volta)」

</details>

#### cacheを使用する

`cache: 'npm'`と指定すると、依存関係のキャッシュと復元を行います。
デフォルトではキャッシュ機能がオフなので、指定する必要があります。

```yaml:build.yml抜粋
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version-file: 'package.json'
          # 依存関係のキャッシュと復元を行う
          cache: 'npm'
```

https://github.com/actions/setup-node#caching-global-packages-data

ちなみにこのアクションでは **`node_modules`をキャッシュしていない** のでそこは要注意です。

`actions/setup-node@v3`の内部では[actions/cache](https://github.com/actions/cache)というアクションが内部で使用されているということなので、そのドキュメントで`Node - npm`の項目を確認すると、どうやら`npm config get cache`で出力されるパスにある[npmのキャッシュ](https://docs.npmjs.com/cli/v9/commands/npm-cache)を使用しているようです。

https://github.com/actions/cache/blob/main/examples.md#node---npm

また、`actions/cache`のドキュメントでは`node_modules`をキャッシュすることはおすすめしない、とあったので、今回は`node_modules`はキャッシュしていません。


## ワークフローの完了

リポジトリトップの`Environments`に`GitHub Pages`のデプロイ履歴へ遷移するリンクが追加されます。

![screenshot_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961694/19cff096-3687-cef2-514b-9ccb0e52c5e0.jpeg)

各ジョブの詳細からは、各ステップで出力された結果を確認することも可能になります（エラー時には特に重宝します）。
![screencapture-github-ambl-gr-ky-group-web-docs-actions-runs-5110590276-jobs-9186643453-2023-05-29-19_19_27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/961694/a5cb4680-4adf-c6ad-a9a1-fa34eef59ff3.jpeg)

こうして、`https://xxxxx.pages.github.io`から`HonKit`で作成したドキュメントを閲覧することができます:hugging:

今回はシンプルなワークフローでしたが、もっと`GitHub Actions`を使いこなしたいなあと思う今日このです（LaravelプロジェクトをEC2にデプロイできるようにしたい）。