GitHub Actionsを使った効率の良い学習の仕組み化

## はじめに
GitHubリポジトリ:  
https://github.com/yamd1/TIL.git

> [!NOTE]  
> 今まで利用していたのはプライベートリポジトリで個人的な内容が多分に含まれていて、とてもパブリックにはできませんでした
> そのためパブリックリポジトリを新規作成したばかりですので、記事自体は大変少ないです
> 徐々に移行していきますので記事少なすぎと思わないでください


## なぜ作ろうと思ったか
私はプレイベートのリポジトリでTodayILeaned(以下、TILと表記)[^til]を運用していました  
日々の学んだことを小さいことでも良いので言語化して、カテゴリごとに整理してGitHubで管理しています  

だけど中々記憶に定着しないです  
なんとなく「書いたこと」は覚えているので、困ったときにリポジトリ内を検索して見つける感じです  
これはこれで良いんですけれど、せっかく言語化して整理して保存しているんだから、もっと記憶に定着できるようにしたいなーと思ったのがきっかけです  

ところで皆さんはエビングハウスの忘却曲線[^エビングハウスの忘却曲線]をご存知でしょうか？ (私は知りませんでした)  
エビングハウスの忘却曲線によると「繰り返し復習すると長期記憶に残りやすいよ」と科学的に証明されているようです  
>1880年から1885年にかけて、エビングハウスは、自ら「子音・母音・子音」から成り立つ無意味な音節（rit, pek, tas, ...etc）を記憶し、その再生率を調べ、この曲線を導いた。結果は以下のようになった。

何を言っているのかよくわかりませんが、科学的に証明されているので大丈夫です  

一度学んでから、復習すると記憶に残りやすくなることはよくわかりました  
けれども怠慢な私は「定期的にコミットした内容を探して見直す」なんてことは絶対にできません  
絶対無理です  
ですが私は一応エンジニアです  
自動化しましょう  

## 何を作ったか
毎朝8時に `1日前` `7日前` にcommitした記事をまとめて、Slackに通知してくれる仕組みを作りました  
この記事では、GitHub Actionsを利用した次の3つの仕組みについて紹介します
1. `git log` コマンドを用いて過去のcommitを取得する
2. commitの内容をガッチャンコしてジョブサマリーに表示する
3. slackに通知する

ソースコード全文は以下にありますので、興味ある方は御覧ください  

https://github.com/yamd1/TIL/blob/main/.github/workflows/looking-back.yml

## どう作ったか
### [1. `git log` コマンドを用いて過去のcommitを取得する](https://github.com/yamd1/TIL/blob/e3029fbb64ae0165f1c6b8e5308ee025f62226a4/.github/workflows/looking-back.yml#L27-L28)
`git log`コマンドにはオプションが豊富にありますが、その中の`--after` `--before`を利用して対象期間のコミットのみ取得しています  
取得したいコミットへの相対的な日時を指定するのですが、その際に`T00:00:00+09:00`のようにISO8601形式で時刻まで厳密にする必要があります  
指定しなければ実行した時間が利用されるため、n日前の **すべての** コミットを取得できません  
> [!TIP]  
> 指定しない場合、`実行時間:08:00` -> `YYYY-mm-dd 08:00` より前のコミットを取得するので、同日の09:00にコミットした内容は取得できない

取得できた特定の期間にコミットされたファイル名などが取得できますので、`grep`でファイル名だけにします  
同一のファイル名が含まれているかもしれないので`uniq`コマンドで1つにします  
```sh
git log --date=short --format="%h" --name-only --after="$(date +'%Y-%m-%d' --date '1 day ago')T00:00:00+09:00" --before="$(date +'%Y-%m-%d' --date '0 day ago')"  | \
grep -oE '\S*\.[md]\S*' | sort | uniq | \
```

### [2. commitの内容をガッチャンコしてジョブサマリーに表示する](https://github.com/yamd1/TIL/blob/e3029fbb64ae0165f1c6b8e5308ee025f62226a4/.github/workflows/looking-back.yml#L29-L37)
git logで取得した結果なので、ファイル削除されている結果も含まれています  
なのでファイルが存在しているとは限らないので存在チェックをしています  
ファイルがあった場合はその内容と改行を `$GITHUB_STEP_SUMMARY` へリダイレクトしています  

> [!NOTE]  
> `echo -e` のオプションをつけることでエスケープシーケンスを解釈します
```sh
while read file; do
  echo $file
  if [ ! -e $file ]; then
    continue
  fi
  {
    cat $file
    echo -e "\n\n\n"
  } >> "$GITHUB_STEP_SUMMARY"
```

### [3. slackに通知する](https://github.com/yamd1/TIL/blob/e3029fbb64ae0165f1c6b8e5308ee025f62226a4/.github/workflows/looking-back.yml#L68-L75)
[slackapi/slack-github-action](https://github.com/slackapi/slack-github-action) を見ていただくのが一番です  
`${{ env.BUILD_URL }}`にGitHub Actionsのサマリー画面へのリンクを設定しています  
```yml
env:
  BUILD_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
```

毎朝届くメッセージを構築します  
```sh
uses: slackapi/slack-github-action@v1.25.0
with:
  payload: |
    {
      "text": "<${{ env.BUILD_URL }}|📦${{ env.DATETIME }}: Looking back TIL.>"
    }
env:
  SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
```

## おわりに
学んだ内容を `気軽に` `素早く` `少ない労力で` 記事にしたかったので、GitHub Issue から記事を生成するGitHub Actionsワークフローも構築しました  
こちらも合わせて御覧ください  

https://github.com/yamd1/TIL/blob/main/.github/workflows/post-til-from-issue.yml


[^til]:TodayILearnedとは  
[Githubのリポジトリ「TIL」を使って小さなアウトプットを習慣化する](https://qiita.com/nemui_/items/239335b4ed0c3c797add)

[^エビングハウスの忘却曲線]: https://ja.wikipedia.org/wiki/%E5%BF%98%E5%8D%B4%E6%9B%B2%E7%B7%9A