Githubで己のバージョン管理してみた

この記事は『[LITALICO Engineers Advent Calendar 2021](https://qiita.com/advent-calendar/2021/litalico)』の11日目の記事です。
はじめまして、21新卒エンジニアの小林（@bashiiko）です。
去年までは大学院で機械学習系の研究をしていたので、アカデミアにはない楽しさも難しさも感じる日々です。

学生時代からの変化の一つとして、「目標設定と振り返り」を意識して行うようになった、ということがあります。
やってこなかったので当たり前ですが、私は目標設定も振り返りも超苦手です。ただ、重要性を感じてからは苦手なりに色々試行錯誤をしてきました。

その中で　**『Githubを使って、取り組んだことと自分自身のスキルの変化を履歴として管理する』方法が、効果的な振り返りのための材料をちゃんと集めるという観点で使い勝手が良かった**ので、今回紹介したいと思います。
ちなみにGithub使ってみたら、というアイディアは@kamesennin さんからいただきました。ありがとうございます！

## 要約
### やったこと
- 効果的な振り返りのための材料をちゃんと集めるため、Githubを使って自分自身の状態やスキルの変化をバージョン管理をする方法を考えた
- 一ヶ月運用してみた

### 結果
- 良い。手軽さもあって1ヶ月ちゃんと継続できた
- やったこととその結果の履歴がちゃんと残っていて、必要なタイミングで振り返れるのが良い
- ツール自体はGithubじゃなくても別にいい。抑えるべきポイントが結構見えたので、それが実現できれば何でもいい

まだ運用して1ヶ月ですが、結構良さげなので、振り返り苦手で苦戦してる同志の一つの参考になれば嬉しいです。

---

## そもそもなんで目標設定とか振り返りって必要なんだっけ
私自身、時間をかけてやるに値する、と納得できるだけ理由がなかなか分からず、「目標設定と振り返り」が上手そうな人の話をたくさん聞きました。その結果、受け売りも多いですが、以下のように考えています。

- 目標は立てなければ叶わないから
- 目標を達成するために振り返りが必要不可欠
   - 自分の得意不得意や性質などを把握し、自分がパフォーマンスを発揮できる状況を作れるようにする
   - うまくいかなかったことは理由を分析し、改善方法を探す
   - うまくいったことも理由を分析し、再現性を高める

（これは個人レベルの話で書いていますが、プロジェクトやチームレベルでももちろん同様のことが言えると思ってます）


そして効果的な振り返りを行うためには、振り返りをするための材料を日々貯めておくことが重要だと感じています。
日報を書いて管理をしたりもしましたが、どうしてもタスクレベルに寄ってしまいました。
そうではなく、「半年後や一年後の目標状態」を達成するための、という観点に立った時に

- 自分の状態の変化
- 目標達成のために行ったことの歴史

をなんかうまいこと管理したい！その情報から効果的な振り返りを行うことで、目標達成したい！というのが今回のモチベーションです。
結果的にたどり着いたのがこの記事の本題であり、次で紹介する『**Githubを使って己のバージョン管理をする**』方法です。
ファイルに対して、いつ・（誰が）・何をやって・どう変化したのかを管理するバージョン管理システムの構造を使って、自分自身の状態やスキルの変化もバージョン管理しよう！ということをやっています。

## Githubを使って己のバージョン管理をする

:::note info
一ヶ月運用する中で、良い振り返りをする＋目標達成のための行動するためにポイントだなと感じた部分を緑の枠で示しています。
:::


### 運用方法（例）
#### ① 最初の準備
- 管理用のgithubリポジトリを作成する
    - テンプレートリポジトリは[ここ](https://github.com/bashiiko/self-versioning-template)で公開しています
- `skils` ディレクトリ以下に管理したいスキル・指標のディレクトリを作成する
    - 例えば、`technical-skil`（技術力）や、`management-skil`（管理能力）など

#### ② 日々やること
##### `yyyymmdd.md`のようなファイルを作成してやったことのログを突っ込む

:::note info
綺麗にまとめる必要はないので、手軽に『やったこと・結果・理想と現状と差分』を履歴として記録できるようにする
うまくいったこと・できたことだけでなく、うまくいかなかったことも記録に残す
:::

- `skils` 以下に作った各ディレクトリ下に追加します
- 例えば以下に例として示しているような形式で書きます
- 便宜上、この記事の中では、このファイルのことをログファイルと呼びます
- 理想状態と現状は基本固定で、変化があった場合だけ修正するようにします

```md
## 20211201.md
# 例：技術力(等級1)

## 理想状態

- 〇〇が自走して推進できる
- 〇〇を理解して××できる
- など。
- 正直理想状態を定義するのが難しいので、
- 今は会社の等級制度・評価指標や、自社や同じ業界の会社の中途採用ページで公開されている募集スキルあたりを参考にしています

## 現状

- 〇〇であれば自走して推進できるが、××は上位等級のサポートがないと一人では行えない
- 〇〇は理解しているが××は理解しておらず、△△は対応できない
    - など

---

## やったこと、結果

- github actions の[公式ドキュメント](https://docs.github.com/ja/actions)を読んで勉強した
    - github docs整理されてて勉強しやすかった
- シェルスクリプト の書き方勉強した
- github actionsを利用して、push時にREADME.mdを自動で更新できる仕組みを作った

## メモなど

- notionに勉強メモ書いた
- github actionsいろいろできそうなので、チームの開発リポジトリでも何か応用できないか考えたい
```

##### 追加したファイルをcommit＆pushする
:::note info
スキル（指標）ごとに、『理想状態・現状・行動量』が常に観測できる状態を作る
→ 理想状態と現状との差分を常に意識して、次何やればいいのかを考えられる
→ 行動量を可視化して、自分が注力できていること/いないこと気付ける＆モチベが上げる
:::

- コミットメッセージにやったことや結果の要約を書いておくと分かりやすいです
- github actionsなどを使って、ファイル追加時やリモートリポジトリへのpushをトリガーに、自動でREADMEを更新するようにしておくのがおすすめです
    - ログファイルに基づく最新の『理想状態・現状・行動量』が常にREADME上で見れるようにします
    - 最悪自動化せず手作業で書き換えてもいいが、めんどくさいので。めんどくさいとやらなくなるので。
    - [私のリポジトリの場合](https://github.com/bashiiko/self-versioning-template)は、push時に以下の2つのシェルスクリプトが走るようにGithub Actionsを設定し、画像のようなREADMEが自動で作成・更新されるようにしました
<details>
<summary>`コミット履歴をグラフ化するシェルスクリプト `</summary><div>

```bash
#!/bin/sh

function plot(){
  dirs=`find skils -mindepth 1 -maxdepth 1 -type d`
  for dir in $dirs;
  do
    md_files=($(ls $dir/*.md | grep -v '^.*template.md'))
    arr=()
    for md_file in ${md_files[*]};
    do
      arr+=(`basename $md_file .md`)
      today=$(date "+%Y%m%d")
    done 

    echo 'date count' > data/`basename $dir`.csv
    for i in ${!arr[*]}
    do
      echo ${arr[$i]} $((i+1)) >> data/`basename $dir`.csv
    done
  done


  gnuplot -e "
    set term png; 
    set xdata time; 
    set timefmt '%Y%m%d'; 
    set xrange ['20211120':'$today'];
    plot for [i in system('find data -mindepth 1 -maxdepth 1')] i using 1:2 w lp  pt 7 title system('basename '.i)
  " > "commit.png"
}

cd `git rev-parse --show-toplevel`
plot
```

</div></details>

<details>
<summary>`README.mdを自動更新するシェルスクリプト `</summary><div>

```bash
#!/bin/bash

function update_readme(){
  echo "![commit image](commit.png)" > README.md
  for dir in `find skils -mindepth 1 -maxdepth 1 -type d`;
  do
    latest_md_file=`ls -rt $dir *.md | tail -n 1`
    echo "`cat $dir/$latest_md_file | sed -n '/---/q;p'`">>README.md
    echo "## 最新コミット">>README.md
    for i in $(seq 1 3); do
      commit_id=`git log -n $i --pretty=%h $dir | tail -n 1`
      commit_data=`git log -n $i --date=short --pretty=format:"%ad : %s" $dir | tail -n 1`
      echo "- [$commit_id](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/commit/$commit_id) $commit_data">>README.md
    done
  done
}

cd `git rev-parse --show-toplevel`
update_readme
```

</div></details>

![last image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423220/3eaa1bae-3e2e-67fb-eead-540bf9a16b71.png)

#### ③ 振り返る
- 2つの方法で定期的に振り返ります
    - **1〜2週間に1回**、Githubにたまった材料をもとに振り返りを行う
    - **数ヶ月に1回**、「Githubにたまった材料 ＋ 1〜2週間ごとの振り返りって来た内容」をもとに振り返りを行う
 
[冒頭](#そもそもなんで目標設定とか振り返りって必要なんだっけ)でも書きましたが、私は振り返りの目的を以下のように定めています。
> - 自分の得意不得意や性質などを把握し、自分がパフォーマンスを発揮できる状況を作れるようにする
- うまくいかなかったことは理由を分析し、改善方法を探す
- うまくいったことも理由を分析し、再現性を高める

なので、

- 記録ログを見ながら
    - うまくいったこと、うまくいかなかったことの原因って何？
    - 理想状態と現状との差分はどこにあるか？どうやったらその差は埋められるか？
- コミット履歴のグラフを見ながら
    - 今の自分・過去の自分ってどこに力を入れて取り組んできたんだっけ？
    - 来週/来月はどこに力を入れようか

みたいなことを考えて、これを「振り返り 【 ○月○日〜○月○日 】」みたいな感じでissueを作って記録しています。

また、ある程度期間を置いて長いスパンで再度振り返りを行うことで、例えば「3ヶ月前にやった○○、当時はあんまりよくないと思っていたけど、今になって振り返るとやってよかった」みたいな気づきが得られると期待しています。逆も然り。

:::note
やったこととその結果の履歴さえちゃんと残せていることが大事
それさえあれば、後からどうとでも有益な振り返りができる
:::

## 1ヶ月運用してみた結果
- Good
    - ちゃんと継続できる手軽さ
    - やったこととその結果の履歴がちゃんと残っていて、必要なタイミングで振り返れる
    - コミット履歴をグラフ化するようにしたことで、行動量が一目でわかる。
    - 振り返りの材料として蓄積される情報が圧倒的に増えたので、より効果的な振り返りができるようになった（はず）
- More
    - Githubである必要性は今のところそこまでない。基本的にただファイルを追加してるだけなので
        - 何のツールを使うかではなく、記事中緑枠で書いたポイントをちゃんと抑えられるのが大切そうだとわかったので、もっといい方法見つけたら全然乗り換える
    - （細かいが） Github Actionsを使ってREADMEの自動更新を行なっているため、ローカルで新しいログファイルを追加したいときに毎回`git pull`しなくてはいけなくて面倒なので変えたい


## おしまい
明日は @jumpeiMano さんです！
おたのしみに！私も楽しみにしています！