【GitLab】scaffdog + Docusaurus + GitLab Pagesでリリースドキュメントの生成・運用を楽にしてみました

この記事は、Advent Calendar 2022 / DevOps・インフラ・SRE「GitLab Advent Calendar 2022」の22日目の記事です。

はじめに

こんにちは、AI・IoT サービス開発部のがんがんこと岩丸です。

今年も技術記事を読むのが忙しい季節がやってきましたね。昨年はVue.js + TypeScript + Vuetifyに関する記事を執筆しました。今年はGitLabに関した記事を執筆いたしました。


今回はGitLab Pagesに関する記事です。 前回も GitLab に関する記事を執筆しており、前回の記事ではGitLab Runnerで AWS Lambda 用 ZIP 生成を行いました。もしお時間ある方は合わせてご覧ください。

https://tech-blog.optim.co.jp/entry/2022/09/12/100000


今回はscaffdog + Docusaurusで生成したドキュメントをGitLab Pagesでホスティングし、リリースドキュメントの作成・運用作業を効率化した内容をご紹介致します。

目次

やったこと

リリース手順書を markdown 形式で管理しており、リリースの度に「過去内容をコピー → バージョンタグなど必要箇所のみを更新する」という作業を行なっておりました。大体の作業手順は同じであり、毎回コピーして必要箇所を更新するのはとても面倒でした。 また、きちんと Git 管理されておらずドキュメントとして保守しにくい状態が続いていました。


そこでリリース手順書の markdown テンプレートをscaffdogで生成し、生成したリリース手順書をDocusaurusでドキュメント化しました。Docusaurus でドキュメント化した内容はビルドし、GitLab Pagesで表示できるようにしました。

scaffdog とは

scaffdogとはユーザ任意のテンプレートを作成し簡単にスキャフォールディングが行えるツールです。Ruby on Rails に馴染みがある方だとrails generate scaffoldコマンドが思い浮かぶかと思います。

本ツールの私的推しポイントは以下の 2 つです。

  • ユーザ任意のテンプレートが作成できること
  • 対話形式であること

運用現場では「この部分は自動化したいけど、この部分は状況次第で任意に可変したい」というケースが往々にしてあるかと思います。 私は過去に対話形式のリリース shell スクリプトを自作したこともあり、対話形式で柔軟に扱えるツールを模索してきました。scaffdogは私が本当に求めていたものでした(スカーフを巻いたわんちゃんも可愛くて good)。

github.com


scaffdogはReact.jsのボイラープレート作成の利用例をよく見かけます。今回のような使い方はあまり例がないので、scaffdogにフォーカスした記事は別途執筆致します。

Docusaurus とは

Docusaurusは React+TypeScript で実装可能な静的サイトジェネレーターです。Meta 社によって開発されています。

github.com

様々な静的サイトジェネレーターが世の中に存在していますが、他ツールと比べてシンプルに使える印象です。他ツールとの比較が公式ドキュメントにありますのでそちらも参照ください。

https://docusaurus.io/docs#comparison-with-other-tools

scaffdog + Docusaurus + GitLab Pages

Docusaurus 環境構築

Docusaurus の環境構築を行います。基本的には優秀な公式ドキュメントの通りに構築します。

docusaurus.io

# Installation (for JavaScript)
$ npx create-docusaurus@latest manual-example classic
# Installation (for TypeScript)
$ npx create-docusaurus@latest manual-example classic --typescript

対象ディレクトリに移動しyarn startで起動確認ができれば OK です。とても簡単ですね。

scaffdog でテンプレート作成

scaffdog の環境構築を行います。

# Installation
$ yarn add -D scaffdog

# Setup scaffdog (Auto)
$ yarn scaffdog init
# Setup scaffdog (Manual)
$ mkdir .scaffdog && echo "export default {\n  files: ['./*']\n};" > .scaffdog/config.js

続いてテンプレートの作成を行います。対話形式で名前、ディレクトリを設定するとデフォルトテンプレートが生成されます。

# NOTE: package.json に scaffdogコマンド追加済み
$ yarn scaffdog create manual
yarn run v1.22.19
$ scaffdog create manual
? Please select a root directory. /blog
? Please enter a output pattern. **/*

🐶 Created document ".scaffdog/manual.md"

✨  Done in 14.76s.

デフォルトテンプレートを以下のように変更します(※ ```の前\は執筆用です)。

<!-- .scaffdog/manual.md -->
---
name: "manual"
root: "./blog/"
output: "**/*"
ignore: []
questions:
  date: "リリース日を入力してください (例: 2022-12-25)."
  start_time: "開始時刻を入力してください (例: 22:00)."
  end_time: "終了時刻を入力してください (例: 22:00)."
  version: "リリース対象のバージョンを入力してください (例: 19.3.0)."
  version_old: "ロールバック対象のバージョンを入力してください (例: 19.2.0)."
  pilot: "リリース作業者を入力してください (例: OPTiM 太郎)."
  sub_pilot: "作業確認者を入力してください (例: OPTiM 小太郎)."
  isProductB:
    confirm: "ProductB ですか."
    initial: false
  isStop:
    confirm: "サーバーは停止しますか."
    initial: true
---

# `{{ inputs.date }}.md`

````markdown
---
slug: "{{ inputs.date }}-manual"
title: "[{{ if inputs.isProductB }}Product B{{ else }}Product A{{ end }}] {{ inputs.date }} {{ inputs.version }}"
authors:
- name: {{ inputs.pilot }}
  title: 作業者
- name: {{ inputs.sub_pilot }}
  title: 作業確認
  tags: [manual, {{if inputs.isProductB }}Product B{{ else }}Product A{{ end }}]
---

| 項目 | 内容 |
| :-: | :- |
| リリース日 | {{ inputs.date }} |                                
| 作業開始時刻 | {{ inputs.date | replace "-" "/" }} {{ inputs.start_time }} |
| 作業終了時刻 | {{ inputs.date | replace "-" "/" }} {{ inputs.end_time }} |
| リリース対象バージョン | {{ inputs.version }} |
| 異常系リリースバージョン | {{ inputs.version_old }}  |
| 作業担当者  | {{ inputs.pilot }} |
| 作業内容確認者 | {{ inputs.sub_pilot }} |
| サーバー停止の有無 | {{ if inputs.isStop }}停止{{ else }}無停止{{ end }} |

## ■ 事前作業

### □ 作業ディレクトリ用意

\```shell
mkdir work && cd work && export WORKDIR=$(pwd) && cd $WORKDIR
\```

### □ ECR イメージの確認

\```shell
cd $WORKDIR && git clone {script.git} --recursive && cd $WORKDIR/script
\```

\```shell
sh $WORKDIR/scripts/check_exists_ecr_image.sh {{ inputs.version }}
\```

### □ デプロイ
...
````

このテンプレートを用いて対話形式でマニュアルを生成します。以下のように回答すると/blog配下に2022-12-23.mdというマニュアルが生成されているかと思います。

$ yarn scaffdog generate manual
? Please select the output destination directory. ./blog/
? リリース日を入力してください (例: 2022-12-25). 2022-12-23
? 開始時刻を入力してください (例: 22:00). 18:00
? 終了時刻を入力してください (例: 22:00). 21:00
? リリース対象のバージョンを入力してください (例: 19.3.0). 19.3.0
? ロールバック対象のバージョンを入力してください (例: 19.2.0). 19.2.0
? リリース作業者を入力してください (例: OPTiM 太郎). OPTiM 太郎
? 作業確認者を入力してください (例: OPTiM 小太郎). OPTiM 小次郎
? ProductB ですか. No
? サーバーは停止しますか. No

🐶 Generated 1 file!

     ✔ blog/2022-12-23.md

✨  Done in 38.33s.

GitLab Runner 環境構築 + GitLab Pages 準備

GitLab Pages のHow it worksを参考に環境構築していきます。基本的に.gitlab-ci.ymlを作成し、ビルド生成物をpublicディレクトリにを配置すれば大丈夫です。

GitLab always deploys your website from a specific folder called public in your repository. When you create a new project in GitLab, a repository becomes available automatically.

# .gitlab-ci.yml
default:
  image: node:19-alpine

stages:
  - deploy

pages:
  stage: deploy
  script:
    - yarn install
    - yarn build --out-dir ./public
  artifacts:
    paths:
      - public
    expire_in: 1 mos

GitLab Pages の表示

GitLab Pages で以下のようなマニュアルが表示されていれば実験完了です。GitLab 上で差分管理・運用が完結するため、レビュー者の負担、作成・運用の負担がグッと減りますね。 感動した点として、クリップボードへのコピーが容易なことが挙げられます。これでコマンドのコピペミスもゼロにでき非常に助かります。

おわりに

今回は scaffdog + Docusaurus + GitLab Pages を用いてリリースドキュメントの作成・管理作業を効率化しました。今後も効率化できるところを効率化・自動化し、注力すべき箇所に注力できる環境を作っていきたいお気持ちです。


OPTiMでは運用改善やDevOpsに興味があるエンジニア、新卒からどんどんチャレンジしていきたいエンジニア学生を随時募集しております。少しでもご興味のある方はこちらも合わせてご覧ください。

www.optim.co.jp