Chrome拡張でマスタデータ管理ツールを作ったら開発に変化が起きた話（ツール公開しました）

# よくある運用

マスタデータの管理方法として多いのは、Excelなどの表計算ソフトを使ってデータを作成し、それをGitHubで管理しつつ、実際にDBなどへデプロイさせる方法かと思われます。

そしてこれを実現するにあたって、出来るだけエンジニアの負担を減らせるよう、データ作成者にGitクライアントの使い方やデプロイ方法をレクチャーします、が...

# マスタデータ管理ツールの誕生

ただ、そこで気になるのは、**結果的にデータ作成者の負担が増えてしまう**ことです。
大体の場合、表計算ソフト以外のツールも触ることになり、もう少し手軽にできないかと考えていました。

そこで今回は、Chrome拡張とSpreadsheetを用いて、**データ作成者が<font color="Red">Chromeだけで</font>データの作成から反映までできる**ツールを作成しました。

少し前から、Spreadsheetでデータを作成後にデプロイツール実行一つでデータを反映する、といった事例も出てきて、「ならこのデプロイツールをChrome拡張にすればさらに手軽になるのでは」という発想を元に誕生しています。
![ssbird.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253997/d40665dd-51be-ecdf-b6fd-3485b8bd6176.gif)
今回作成および公開したのは**[SSBird](https://github.com/yukiarrr/SSBird)**というツールです。
<a href="https://github.com/yukiarrr/SSBird"><img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253997/6e926855-e267-5c4e-1479-fcdb5a435423.jpeg" alt="ssbird github"></a>
https://github.com/yukiarrr/SSBird

SSBirdでは、DBへのデプロイなど各プロジェクトの環境に依存してしまう部分を除き、データを作成してGitHubにプッシュするまでの工程を負担します。
（プッシュ後に各PJのCI/CDでデプロイされる想定）

立ち位置としては、Spreadsheetに最適化されたGitクライアントです。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253997/a84b1d48-21e8-b3cd-c9a1-390905bd2295.jpeg" alt="simple role">
また、複数人での並行作業やCIでのデータチェックを考慮して、**シート同士のマージ機能**や**Pull Requestを作成する機能**も備えています。
（上記のgifでは、developシートにadd-dataシートの内容をマージ）
　
　
マスタデータの管理に関してはデファクトスタンダードになるようなものがなく、各プロジェクトが毎回独自でその仕組みを作っている印象が強いです。
なので、**その負担を出来るだけ減らす手段の一つになれれば**という思いから公開しました。

# マスタデータ管理ツールについて

今回作成したマスタデータ管理ツールの説明です。
もし先に導入してどんな変化が起きたのか知りたい方は[こちらから。](#何が変わったのか)

## 特徴

SSBirdの特徴で、作成の際に意識しているのは以下の5つです。

1. Chromeだけで完結
2. シート同士のマージ機能
3. 高速なシート操作
4. 導入が容易
5. 汎用性の高さと依存性の低さ

### 1. Chromeだけで完結

Git操作などを全てChrome拡張で補うため、データ作成者はChrome以外を触る必要がありません。
Spreadsheetでデータを作成して、その画面のままでChrome拡張から手軽にデータが反映できるため、とても高速な開発が可能になります。

### 2. シート同士のマージ機能

データの作成は、そのプロジェクトの規模が大きくなるほど複雑になり、複数人で作業することが多くなってきます。しかしその場合、表計算ソフトのような一つのデータを編集する仕組みだと、コンフリクトが発生しやすくなってしまいます。

そこで用意したのが、シート同士のマージ機能です。

この機能を使えば、一つのシートに別のシートのデータを追加・上書きできます。
チームでマージ先のシートを決めて、そこを直接編集しないようにルール付けしておけば、コンフリクトが起こりにくくなります。
（GitHub Flowに近いですね）

### 3. 高速なシート操作

Spreadsheetのシートを操作するAPIは何種類か存在しますが、その一つ一つをパフォーマンス検証しながら実装し、セル単位で操作対象を絞り込むことで、マージやcsv変換などシート操作にかかる時間を最小化しました。

これにより、出力するcsvが数MBにもなるシートへのマージも、数秒単位で完了するようになりました。
結果として「1. Chromeだけで完結」も相まって、**データ作成者が手軽かつ高速にデータ反映**ができるようになります。

### 4. 導入が容易

このツールはバックエンドとして必要な機能をGASでまかなっているため、導入の際にサーバーを立てる必要がありません。
また、表計算ソフトとしてはSpreadsheetを採用しているため、Googleアカウント一つあれば導入することができます。

### 5. 汎用性の高さと依存性の低さ

このツールはシート同士をマージしGitHubにプッシュしているにすぎません。
そのため、各プロジェクトごとでシート運用をカスタマイズできるという、汎用性の高さを持ち合わせています。

そしてそれは裏を返せば、SSBirdへの依存性が低く、他のツールへの代替も容易ということになり、「4. 導入が容易」も相まって、**導入のハードルが比較的低いもの**になっていると考えています。

## 導入方法

具体的な導入方法は、[README](https://github.com/yukiarrr/SSBird/blob/master/README.ja.md)に記述しているので、そちらをご覧ください（日本語版あります）。

## 使い方

ここでは、開発ブランチ名を「develop」と定め、このブランチにcsvがプッシュされるとCI/CDで開発環境にデータが反映されるものとします。

### 最も手軽にデータを反映する方法

最も手軽なのは、開発ブランチに相当するシートを直接編集する方法です。
後述しますが、Spreadsheet内のシート名がプッシュするブランチ名となるため、ここではdevelopシートを編集することになります。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253997/45bc8f55-ae21-d6d7-8979-9b5fcf896709.jpeg" alt="direct">
データ作成後、Spreadsheet上でSSBirdを開きます。
「Target Sheet」が対象となるシートなので、ここに「develop」を指定します。
この状態でApplyすると、developブランチが更新され、データが反映されます。

### シート同士をマージして反映する方法

上記の方法だと、developシートを直接編集するため、複数人データ作成者が存在すると、コンフリクトし互いに予期せぬデータになってしまう可能性があります。
そこで利用するのが、シート同士のマージ機能です。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253997/68f4bc80-ebed-3a3e-863d-e9f6be779561.jpeg" alt="merge">
マージの仕組みは後述しますが、「Target Sheet」の他にマージ用のシートを「Merge Sheets」に指定します。
なお、この「Merge Sheets」に関しては複数シート指定可能で、選択順にマージされていきます。

この状態でApplyすると、add-dataシートの内容がdevelopシートに追加・上書きされ、それがdevelopブランチにプッシュされます。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253997/0e3de513-4781-bc76-1560-1b5facd6dc96.jpeg" alt="merged">

### 複数のSpreadsheetのデータを反映する方法

ここまでの方法は、全てSpreadsheet一つに対しての処理でしたが、Spreadsheetの存在するDrive上でSSBirdを開くと、複数のSpreadsheetに対して処理できるようになります。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253997/572ae0a1-95f5-b780-21aa-f047810e1f52.jpeg" alt="drive">
このように、「Apply Spreadsheets」が選択可能になるので、ここへ反映したいSpreadsheetを選択します。
なお、「Target Sheet」などは上記の方法と同じ仕様で、選択したSpreadsheet全てに対して適応されます。

なお注意点として、Spreadsheet上ではないため「Target Sheet」などの候補が出ません。
使用者自身で入力する必要があります。

### Pull Requestを作る方法

データの量が多くなってくると、どうしてもヒューマンエラーによるデータの不整合が起こりがちとなってしまいます。
この対策としてよく挙げられるのが、**Pull Request上のCIによるデータチェック**です。

SSBirdでもそちらを考慮し、シートをマージする代わりにPull Requestを作成する機能が存在します。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253997/b67659c5-1ad0-d331-1a39-30a2afd27c04.jpeg" alt="create pull request">
普段通り「Target Sheet」と「Merge Sheets」を指定したあと、「Create Pull Request」にチェックを入れてからApplyします。
すると、通常であれば「Target Sheet」のシートが更新されプッシュされるはずが、シートには更新がかからず「Merge Sheets」の最後に選択したシート名のブランチがプッシュされPull Requestが作成されます。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253997/e839643e-92e8-14cf-d781-7fdd43aeb11f.jpeg" alt="pull request title">
このPRでの変更ファイルは、本来シートが更新されプッシュされるはずだったものになっています。
これにより、PRベースでの開発が可能となります。

なお注意点として、「Target Sheet」に指定したシートは更新されていないので、PRがマージされた際に、CLI版の方でSpreadsheet側を更新するようにしておくことをお勧めします。

## Spreadsheetでのルール

SSBirdではSpreadsheetを用いてデータを作成しますが、その際に意識していただくルールは3つあります。

1. Spreadsheet名がファイル名、シート名がブランチ名となる
2. コメントアウト
3. A列のセルとカラムを基準にマージ

### 1. Spreadsheet名がファイル名、シート名がブランチ名となる

Spreadsheet名がexampleならGitHub上ではexample.csvとなり、対象となるシート名がdevelopならcsvはdevelopブランチにプッシュされます。

### 2. コメントアウト

A列またはカラムが空白なセルは、マージ・csv変換どちらにおいても無視されます。
具体的には、
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253997/964201a5-6138-01b8-2690-47383fb72d6f.jpeg" alt="ignore cell">
こちらのシートがマージ・csv変換される際、黄色い部分以外はコメントとみなされ無視されます。
これを利用して、一時的にコメントアウトするためにA列のみを空にしたり、メモを残すことができます。

### 3. A列のセルとカラムを基準にマージ

A列のセル（A1,A2,A3...）が同じであれば同じデータとみなし上書き、違えば新しいデータとして最下位に追加されます。
データが上書きされる場合、カラムを基準として上書きするので、A列のカラム以外の順番が対象となるシートとマージ用のシートでバラバラでも問題ありません。

また、マージ用のシートに、対象となるシートにない新しいカラムがあれば、新しくカラムが追加されます。

## CLI版

SSBirdの機能をCI/CD上やJobで使いたい方のために、**[CLI版](https://github.com/yukiarrr/SSBird/cli/ssbird)**も用意しています。
CLI版にはChrome拡張にはない、GitHub側のcsvデータをSpreadsheetに反映する機能も有しています。

https://github.com/yukiarrr/SSBird/cli/ssbird

以下のコマンドでインストールできます。

```sh
go get -u github.com/yukiarrr/SSBird/cli/ssbird
```

インストール後に、CLI版はGoogleとの認証が必要になりますが、その手段としてOAuth 2.0とService Accountの2種類を用意しています。

なお、このCLI版に関しては現在開発中で、まだ機能が揃っていないのでご注意ください。

## 使われている技術

SSBirdでは、以下の3つの言語を利用しています。

- JavaScript
- Google Apps Script
- Go

具体的な説明は別でできればと思いますので、ここでは軽めに紹介します。

### JavaScript

クライアントサイド、つまりChrome拡張で利用します。
また、UIのドロップダウンの箇所には、[selectize.js](https://github.com/selectize/selectize.js/)を活用させていただいています。

### Google Apps Script

シートの操作を行っています。
具体的には、GASでシートを操作する箇所を記述して、それをWebアプリケーションとして公開し、クライアントサイドから呼び出しています。

### Go

Chrome拡張だけではGitの操作ができないので、[Native Messaging](https://developer.chrome.com/extensions/nativeMessaging)の機能を使って、バイナリ実行しています。
そのバイナリの中身をGoで記述しており、[go-git](https://github.com/go-git/go-git)を活用してGitを操作しています。

# 何が変わったのか

ここでは自身のプロジェクトでの出来事を事例として紹介します。
クライアントはUnityで、APIを介してサーバー側と通信を行うオーソドックスな構成として認識していただけると幸いです。

## 変化前

マスタデータ管理ツールの導入前、自身のプロジェクトではデータ作成者がExcelでデータを作成し、それをエンジニアが受け取ってDBなどにデプロイしていました。
ただ、この方法だと、

- エンジニアの負担が増え、開発が遅れる
- デプロイまで時間がかかり試行回数が減ってしまう
- 結果、データに不備が見つかりがちになる

といった問題が発生してしまいます。
これにより、データ量が膨らみそうな施策が検討され始めたタイミングで、マスタデータの作成フローが整備されることになりました。

とはいえ、このプロジェクトが新規だったこともあり、そこまで大きく時間を費やせるわけではありません。
そこで、自分が個人で制作していたSSBirdを候補の一つとして検証することになりました。

## 変化後

SSBirdは候補としての導入でしたが、結果は良好でした。

- データの作成から反映をChromeだけで行える
- 結果、Gitクライアントを使わずにGit管理できる
- エンジニアはプッシュ後のCI/CDを整備するだけで良く、またこれ自体はSSBirdを見送っても無駄にならない

こういった点などから評判が良く、時間に余裕がない新規案件などでは相性が良いように感じられました。
そして結果的にSSBirdが採用されることになりましたが、その後しばらくして、プロジェクト全体である変化が起き始めていました。

それが**「職種間の超越」**です。

これの要因として考えられるのが、「データの作成」と「データの反映」の壁がなくなったことです。
元々、データ作成者とエンジニアで役割が完全に別れていたものが、マスタデータのフロー整備によりゼロに近づき、またSSBirdの「データの作成から反映をChromeだけで行える」や「結果、Gitクライアントを使わずにGit管理できる」による**手軽さ**が、それをさらに加速させていたように思われます。

この結果、エンジニアもデータ作成に携わったり、データ作成者からも新しいシート運用を試行したりなど、プロジェクトの生産性が大きく向上したように感じています。

# まとめ

マスターデータ管理ツール「SSBird」について紹介しました。

このツールを導入しても、残念ながらマスタデータの管理にかかる負担をゼロにすることはできません。
とはいえ、減らすことはできるかと考えているので、マスタデータのフロー整備の際、選択肢の一つとなれれば嬉しいと思っています。

最後に、SSBirdは現在も開発中なので、興味があればGitHubの方をチェックしてみてください。
ありがとうございました！
<a href="https://github.com/yukiarrr/SSBird"><img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253997/6e926855-e267-5c4e-1479-fcdb5a435423.jpeg" alt="ssbird github"></a>
https://github.com/yukiarrr/SSBird