AsciiDoc をビルドして、GitHub Pages を使ってデプロイする GitHub Actions

# AsciiDoc をビルドして、GitHub Pages を使ってデプロイする GitHub Actions

## はじめに

設計仕様書を [AsciiDoc](https://asciidoc.org/) で記載するプロジェクトで、作成した文書を一括してビルド（HTML 化）、デプロイするための仕組みについての記事です。
つまり、以下のような流れになります。

1. 設計仕様書を AsciiDoc で記述する
1. AsciiDoc まとめてビルドする
1. ビルドした結果を [GitHub Pages](https://docs.github.com/ja/pages/getting-started-with-github-pages/about-github-pages) を使ってデプロイする    

2 と 3 を GitHub Actions で実現します。

## 文書管理の構成

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

```txt
[doc]
 ├ index.adoc # トップページ
 ├ header.adoc # トップページなどルートに置くファイル専用のヘッダファイル
 ├ [images]  # 画像ファイルを格納するフォルダ（全体共通）
 ├ [aaa]     # aaa 設計書群（.adoc）
 ├ [bbb]     # bbb 設計書群（.adoc）
 ├ [ccc]     # ccc 設計書群（.adoc）
 ├ Makefile  # HTML 変換用の Makefile
 └ [scripts] # Makefile で利用するスクリプトファイル群
     └ build-adoc.sh  # HTML 変換スクリプト
```

## GitHub のリポジトリ設定（１）

### Settings | Pages

#### GitHub Pages visibility
- 設定値：Private
Enterprise 契約であれば、そもそも Private 以外は設定変更できないようにしているのが普通。

#### Build and deployment
- 設定値：GitHub Actions

## GitHub Actions


```yaml:asciidoc_ghpages.yml
name: Build AsciiDoc with GitHub Pages
run-name: ${{ github.workflow }} (${{ github.ref_name }}) by @${{ github.actor }}

on:
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
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 job
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
    - name: Step summary
      run: |
        echo "|Properties|Value|" >> $GITHUB_STEP_SUMMARY
        echo "|---|---|" >> $GITHUB_STEP_SUMMARY
        echo "|GitHub Ref|\`${{ github.ref }}\`|" >> $GITHUB_STEP_SUMMARY
        echo "|Commit Hash|\`${{ github.sha }}\`|" >> $GITHUB_STEP_SUMMARY

    - name: Checkout
      uses: actions/checkout@v4

    - name: Setup Pages
      uses: actions/configure-pages@v5

    - name: Install asciidoctor
      run: sudo apt install -y asciidoctor

    - name: Install graphviz (Required for asciidoctor-diagram)
      run: sudo apt install graphviz

    - name: Install asciidoctor-diagram
      run: sudo gem install asciidoctor-diagram

    - name: Install rouge
      run: sudo gem install rouge

    - name: Show shell script attributes
      run: ls -l ./doc/scripts/build-adoc.sh

    - name: Make shell script executable
      run: chmod +x ./doc/scripts/build-adoc.sh

    - name: Build AsciiDoc
      run: cd doc && make html

    - name: Upload artifact
      uses: actions/upload-pages-artifact@v3
      with:
        path: _site

  # Deployment
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    timeout-minutes: 10
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

```

```text:Makefile
.PHONY: html
html: ## HTML を生成する。
	@./scripts/build-adoc.sh
```

```bash:build-adoc.sh
#!/bin/bash

# create output folder
echo ">> create output folder..."
rm -rf ../_site
mkdir -p ../_site

# copy images to output folder
echo ">> copy images to output folder if exists..."
test ! -d images || mkdir -p ../_site/images
test ! -d images || cp -n -l -r images/* ../_site/images/

# copy adoc to output folder
echo ">> copy adoc to output folder..."
find . -name "*.adoc" -type f | xargs -I {} cp --parents -v {} ../_site/

# build adoc
echo ">> build adoc ..."
asciidoctor '../_site/*.adoc' --backend=html5 -r asciidoctor-diagram -a source-highlighter=rouge -a rouge-style=monokai_sublime
asciidoctor '../_site/**/*.adoc' --backend=html5 -r asciidoctor-diagram -a source-highlighter=rouge -a rouge-style=monokai_sublime

# remove temporary adoc
echo ">> remove temporary adoc..."
rm -rf ../_site/*.adoc
find ../_site/ -name "*.adoc" -type f | xargs -I {} rm -r {}

echo ">> Done!"
echo ">> Here's converted files..."
ls -1 -R ../_site/
```


### 補足

#### make のインストールが含まれていない
make を使ってビルドをしていますが、make 自体はビルドイン Ubuntu 環境（ubuntu-latest）に含まれているので、インストールしていません。 

#### .sh に実行権限が無くてエラーになる
スクリプトファイルの実行権限が無かったので、`chmod +x` でつけるようにしました。

```txt
-rw-r--r-- 1 runner docker 1093 Aug  6 01:06 ./doc/scripts/build-adoc.sh
```

## 実行（１）

GitHub Actions で手動実行すると、build は成功するものの、deploy に失敗した。

```textxt:error
deploy
The deployment was rejected or didn't satisfy other protection rules.
```

次章で設定の見直しについて記載します。

## GitHub のリポジトリ設定（２）

デプロイが失敗しているため、設定を見直す。

### Settings | Environments

`github-pages` という設定があるので、それを開きます。

#### Deployment branches and tags

- 設定値：[任意](https://docs.github.com/ja/actions/managing-workflow-runs-and-deployments/managing-deployments/managing-environments-for-deployment#deployment-branches-and-tags)
デプロイが成功するように、適切な設定に変更する。
「No restriction」にでもすれば、確実に成功はするはず。

## 実行（２）

GitHub Actions で手動実行すると、今度は成功しました。
成果物は、下記で閲覧できます。

```txt
https://(ユーザー名).github.io/(リポジトリ名)/
```

なお、Private にしているため、このリンクを権限のない状態で開くと GitHub の認証画面に遷移します。

## Tips

`:outfilesuffix:` を以下のように使用すると、GitHub のプレビューでも、ビルドした HTML でも適切に拡張子が適用されて、リンクが機能するようになります。

```text:index.adoc
:lang: ja
:doctype: book
:toc: left
:toclevels: 3
:toc-title: 目次
:sectlinks:
:icons: font
:example-caption: 例
:table-caption: 表
:figure-caption: 図
ifdef::env-github,env-browser[:outfilesuffix: .adoc]
:docname: Hoge ドキュメント Index
:author: qt6hy
:revnumber: 1.0.0
:revdate: 2024/08/06

= Hoge ドキュメント Index

include::header.adoc[]

== Hoge 設計書一覧
* link:./aaa/README{outfilesuffix}[README]
* link:./bbb/basic_design{outfilesuffix}[基本設計]
* link:./ccc/detail_design{outfilesuffix}[詳細設計]


```