GitHubを用いたチーム開発【量子ソフトウェア勉強会 GW】

# はじめに
[量子ソフトウェア研究拠点](https://qsrh.jp/)主催の[量子ソフトウェア勉強会](https://qsrh.jp/seminar/)で初めてチーム開発をおこなった。
普段はソフトウェア開発とは縁遠い物理系の学生としては、住む場所も立場も異なる人たちと[GitHub](https://github.com/)でコードを共有しながらライブラリを開発したことは不思議な体験だったため、その備忘録として記録を残すことにする。
開発したものは、量子計算ライブラリの量子回路インスタンスを相互変換するライブラリ 「[naniwa](https://github.com/q-group-work/naniwa)」として公開している。
~~開発したライブラリについての記事も後日公開する。~~
(2022/5/18 更新)　開発したライブラリについての[記事](https://qiita.com/FumiKobayashi/items/d3e01a7b28dcec23c2b2)も公開しました！

# チームの概要と開発目標
この記事では素人の自分がチーム開発をしてみた備忘録のようなものなので、
チーム開発についての形式ばったものは紹介しない。（というより著者が素人なのでできない。。。）
チム開発のいろはを学びたい場合は、[他の記事](https://qiita.com/biz-nakashima001/items/f53b73c79fa53f60b7a5)や[書籍](https://www.amazon.co.jp/%E3%83%81%E3%83%BC%E3%83%A0%E9%96%8B%E7%99%BA%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-%E5%85%B1%E5%90%8C%E4%BD%9C%E6%A5%AD%E3%82%92%E5%86%86%E6%BB%91%E3%81%AB%E8%A1%8C%E3%81%86%E3%83%84%E3%83%BC%E3%83%AB%E3%83%BB%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89-WEB-PRESS-plus/dp/4774164283)を参考にしてほしい。

今回のチーム開発では、「汎用的なクラウド量子計算ライブラリ開発」をテーマに行った。
メンバー構成は、主催者側のグループリーダー1人と社会人の方数名と学生2人(全員初対面)で、GitHubを用いたチーム開発の経験者は半数。 
開発期間は、2021年11月から2022年3月までの4ヶ月半程度、2週間に一度、4時間ずつZoomを接続しながら黙々と作業するスタイルで行った。

初回のミーティングでは、どのようなライブラリを作るかを具体的に決めるために、
それぞれのメンバーがやりたいことや、[qiskit](https://qiskit.org/)や[qulacs](https://github.com/qulacs/qulacs)などの量子計算ライブラリを触ってみて、"ほしい！"と思った機能を挙げていった。
さまざまなアイデアが出たが([おまけ](#おまけ)参照)、最終的には「異なる量子計算ライブラリの量子回路インスタンスを相互変換するライブラリ」を作ることになった。
今回のグループワークは時間的制約があったため、既存のサービスをちゃんと調査するというよりも、とりあえず作ってみようという感じで製作に取り掛かった[^1]。

[^1]:本当はちゃんとサーベイしてから取り掛かった方がいい。
今回の開発でも、当初目標としていたものが既に他のグループにより取り掛かられていたので、途中で方針転換した。

# 開発環境
量子計算ライブラリはpythonで利用できるものが大半なので、pythonライブラリを作ることにした。
参加者のほとんどがM1 macユーザという珍しい(?)状況であったため、qulacsやqiskitの環境構築に苦労したメンバーもいた(僕も)ので、何か対策が必要かも？
僕の開発環境は以下、（pythonはvenvで仮想環境を構築して使用）

|      |バージョン|
|:--   |--:    |
|PC|MacBook Air(M1, 2020)|
|OS    | macOS Monterey 12.1|
|python|3.9.10|
|エディター|Visual Studio Code 1.66.0|




# Gitについて
Gitとは、フリーでオープンソースの分散型バージョン管理システムである[^2]。
[^2]:[gitの公式HP](http://git-scm.com/)より
ここでは、今回のグループワークでの使い方について簡単に説明する。
Gitの詳細な使い方は[サル先生のGit入門](https://backlog.com/ja/git-tutorial/)や[Pro Git](http://git-scm.com/book/ja/v2)の日本語版を読んでいただきたい。

今回のグループワークでは半数のメンバーが初めてのチーム開発であったため、`rebase`などは基本的には使わず、`clone`や`checkout`などの基本的なコマンドのみを使用した。

Gitの基本構造は以下の図のようになっている。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609832/28191650-6675-8e2e-27f0-68024aab829a.png" width="80%">



#### レポジトリのクローン
まずはvenvで仮想環境を構築してから、そのディレクトリにGitHubから`clone`した。
最後の2行の`clone`の仕方は各環境に応じてする。
アドレスはGitHubにあるリポジトリのページ上の緑色の`Code`をクリックするとコピーできる。

```bash
$ mkdir QS_group
$ cd QS_group
$ git clone git@github.com:q-group-work/qulacs.git
# or
$ git clone https://github.com/qulacs/qulacs.git
```

#### 個人用ブランチの作成
次に、`clone`したリポジトリからチェックアウトして、`branch`で自分用のブランチ`YOUR_NAME/sample`を作る。
何か作業するときは、改変したいブランチから自分用のブランチを作成して作業する。
```bash
$ git checkout -b HOGE/sample origin/HOGE/sample # ブランチのチェックアウト = リモートのブランチと同じ状態の新しいブランチを手元に作りそこで作業する
$ git status # 今いるブランチの状況確認
$ git branch YOUR_NAME/sample # ブランチ作成
$ git switch YOUR_NAME/sample # ブランチ切り替え
$ git status
```

#### 個人用ブランチに修正を加えてリモートに反映させる
ブランチに何かしらの変更を加えたら、`add`でステージに乗せて、`commit`でブランチにコメントを付け加えた上でコミットする。
そのままだとローカルリポジトリの情報はリモートリポジトリに反映されないので、`push`することで変更を反映できる。

```bash
$ git add YOUR_NEW_FILE # 新ファイル、もしくは修正したファイルをステージにのせる
$ git commit -m "YOUR_COMMENT" # ブランチにコメント付きでコミットする
$ git push origin YOUR_BRANCH # 現在の自分のブランチ情報をリモートに送ってリモートのブランチを更新する
```

Gitコマンドはたくさんあり煩雑であるが、VScode上ではGUIで操作できるので結構便利(著者も使ってた)。


- 参考になるサイト
    - [サル先生のGit入門: https://backlog.com/ja/git-tutorial/](https://backlog.com/ja/git-tutorial/)
    - [Pro Git: http://git-scm.com/book/ja/v2](http://git-scm.com/book/ja/v2)
    - [VSCodeでのGitの基本操作まとめ](https://qiita.com/y-tsutsu/items/2ba96b16b220fb5913be)


## GitHubについて
Qiitaの読者には釈迦に説法だろうが、GitHubはリモートリポジトリを公開することができるWebホスティングサービスである。
GitHubのいいところは、単にリモートリポジトリを公開して簡単にアクセスすることができるだけではなく、Wikiやプロジェクト管理などのチーム開発が円滑に進むような仕組みが用意されている。
以下では、今回のチーム開発で利用した機能について紹介する。

## GitHubを用いたチーム開発
Gitでコードを共有しながらライブラリを開発する上で、
- 運用ルールの共有
- タスク管理

を円滑にできるかが重要である。
特に、今回のような初対面の人間同士で、半数はチーム開発未経験者のような環境では尚のことである。
ここである程度共通認識を持てていたから、いいチーム開発ができたと思う。

### 運用ルール
GitHubでチーム開発をする際のルールは「[Githubでチーム開発するためのマニュアル](https://qiita.com/siida36/items/880d92559af9bd245c34)」が参考になると思われる。
今回のチーム開発では、以下のようなルールを決めた。

- `master`ブランチからチェックアウトした`機能追加ブランチ`(`feature/NEW_FUNCTION`みたいな形式)から、さらに個々人がチェックアウトした`YOUR_NAME/YOUR_JOB`ブランチで作業する
  - 基本的には`YOUR_NAME/YOUR_JOB`ブランチのみで作業する
  - 作業が捗るようであれば個々人がいくらブランチを作っても構わないが、最終的には`YOUR_NAME/YOUR_JOB`ブランチに成果物が残るようにする
- `YOUR_NAME/YOUR_JOB`での個々人の開発が終わったら`YOUR_NAME/YOUR_JOB`ブランチから`feature/NEW_FUNCTION`ブランチに向けて開発者がPull Request(PR)を出す
  - 全員がレビューして`LGTM`[^3]のコメントをしたら、　PRを出した開発者自身がPRをmergeする
    - コードに対しての質問や指摘はできるだけカジュアルに行う。心理的障壁はもうけない
    - 修正は`YOUR_NAME/YOUR_JOB`ブランチに新たにcommitしてpushする
  - mergeしたブランチはGitHubからdeleteする
- 進んでしまった`feature/NEW_FUNCTION`ブランチに追随したほうが開発が捗るときは他ブランチから自ブランチへの`merge`や`rebase`を行ってもいい
  - `merge`や`rebase`の機能を理解していることが前提
  - 他ブランチに迷惑をかけなければ他のGit操作もOK

[^3]:`LGTM`は"Looks Good To Me"の略。コードレビューをして問題なさそうならPRのコメントに書き込む。

### Wiki
GitHubにはリポジトリごとにWiki機能がついており、開発者が自由に書き込めるようになっている。
今回のチーム開発では[Gitの使い方](#Gitについて)や[運用ルール](#運用ルール)をWikiに残しておいた。
2週間に1回しか関わらないプロジェクトだったためルールや使い方を忘れがちだったが、Wikiに記載されていることで忘れても参照することができて非常に便利だった。
![スクリーンショット 2022-04-05 21.25.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609832/85b3f23a-cfd4-5d96-323a-29eba705b8c3.png)


### プロジェクトボード
GitHubには[プロジェクトボード](https://docs.github.com/ja/issues/organizing-your-work-with-project-boards/managing-project-boards/about-project-boards)という機能があり、チケット管理システムを簡単に作ることができる。

今回のチーム開発でも、
- To-Do (何をしなければいけないか)
- In Progress (進行中のタスク)
- Done (完了したタスク)

の項目に分けて、
製作物の完成に向けて必要なタスクのカードをToDo書き込み、
各自で取り掛かるタスクを選んでIn Progressにドラッグ、
終わったらタスクのカードをDoneにドラッグ。
のような過程で進めた。

この機能を使えば、ToDoで課題を具体的切り分けておけば、あとは開発者が各自でタスクを消化していき、課題の進捗状況をチーム内で簡単に共有できる(しかも視覚的に！)ので、とても使い勝手がよかった。

![スクリーンショット 2022-04-07 11.17.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609832/e1103e8b-ca01-a01c-4ba2-f810184654fe.png)


### Pull Requestとコードレビュー
それぞれの開発が完了したら、ローカルリポジトリからリモートリポジトリにpushして、合流させたいブランチにPull Requestを出すことで、製作物がGitHub上に完成していく。
プルリクが出たら、更新されたものが問題ないかチームの全員で[^4]チェックする。
手元に持ってきてちゃんと動作するか確認したり、コード自体の不備がないか確認して問題がなさそうであれば、LGTM!とかをコメントしておく。
何か問題があったり、自分の手元の開発物と競合しそうであれば、コメントなり、直接の議論なりで解消する。
今回のチームは、コーディングに長けているメンバーが多く、大小のバグを発見していただき、いろいろコメントをもとに修正したので、プルリクの段階でちゃんとコードレビューすることの大切さを痛感した。
普段は人と一緒にコードを書くことがないので、コードレビューという作業が初めてで何をすればいいかわからなかったから、予めコードレビューをする指針を決めておくと初心者でもやりやすくなるかも？

あとは、テストを簡単にできる環境を整備しておくのも大切。関数を追加したら、それと一緒にテスト関数を作ることで、何らかのバグがあっても見つけやすくできる。
今回のチーム開発でも、1関数につき1テストを作って、pytestでテストできるようにしておいた。


[^4]:全員でチェックする必要があるかは、チームごとに検討すればいいと思う。

# 感想
量子ソフトウェア勉強会とはいいつつ、今回は量子計算ライブラリのためのチーム開発が主軸になったので、量子計算のコアな部分に触れる機会が少ないグループワークであったが、逆に普段はソフトウェア開発に触れることがない量子情報の学生としてはとってもいい経験になった。
僕自身は物理屋さんで、普段は実際に量子情報の実証実験や要素技術を作ることを主軸に置いてる研究室にいるので、ソフトウェア開発という情報屋さんが貢献できる別の視点から量子情報を見れたと思う。今回体験したような部分は、僕のような出自の人間だけでは効率的に開発できない部分だし、量子力学に精通していなくても十分貢献できるようなことなので、量子力学には自信がないけどプログラミングには自信がある！みたいなエンジニアの人たちが参入してくれると開発が進んで、量子技術ど真ん中の僕としては嬉しいと思った。
あと、タスクを切り分け、メンバーに分配して、お互いレビューするというチーム開発のフレームワークは、普段の研究する上でも役立てれそうな道具なので、この体験は研究生活にもプラスになる会だった。

## おまけ
アイデア出しの段階で、個人的に量子計算ライブラリの便利機能としてほしいと思ったものを貼っておく。
(つよつよエンジニアの人たちに作ってほしい。。。)
- AWS Bracketのリソース管理(量子コンピュータへのアクセス回数管理)
- 変分量子アルゴリズム(VQEや量子機械学習など)のshot数を推定してリコメンドするライブラリ 
- クラウド利用可能な量子コンピュータのステータスがリアルタイムに見れるサイト(qiskit_slackbotやionQのAPIを活用すればできるかも？？)