📋

githubActionsを定期実行させて、オリジナルなREADME.mdをつくる

2022/01/23に公開

githubでは自分のアカウント名でリポジトリを作成するとREADME.mdの内容がトップページに大きく表示されます。

個人のgithubのトップページなのでプロフィールとして活用する事が多いですが、書く内容や表示するものは基本的に自由です。

自分は仕事上、ほぼ毎日と言っていいくらいgithubにはアクセスするので、プロフィールというよりか、もっと自分が見たいオリジナルな情報をREADME.mdで確認したいと思っていました。

そんな時に、github Actionsを活用すればREADME.mdを自動で更新できるし、工夫すればできそうだなと思ったので、pythonを使って作成してみました。

今回はconpass(エンジニアをつなぐIT勉強会支援プラットフォーム)が提供している"conpass api"を活用して、自分が今月に参加するイベント一覧をgithubのREADME.mdに表示していつでも確認できるようにしました。

APIを叩いてレスポンスをもらう、という形であれば色々と流用ができると思います。

🎖 完成イメージ

  • 図の赤枠の部分について、1日に1回自動更新させて表示しています。
  • クリックするとconnpassのイベント概要ページに飛ぶようにしています。
  • 実際のgithubページ

https://github.com/kawa-t


🗂 構成とか手順

1. pythonで実行する内容を記述
2. ymlファイルで定期実行の設定
3. github Actionsを使って定期実行でpythonを動かす
4. レスポンスもらって処理
5. README.mdの内容を更新する

大きく構成は5つですが、実際に自分でやらないといけないのは1と2だけです。
残りはpythonとgithub actionsが上手いことやってくれるので、思ったよりも簡単にできます。


バージョン

macOS Monterey 12.0.1
python 3.9.6

ファイル構成

プロフィールのリポジトリ
├─.github
│ └─workflows
│   └─update-readme.yml
├─scripts
│ ├─README.md // pythonで出力したREADME.md
│ └─updateReadme.py
└─README.md

📐 作成手順

準備

まずは、ローカルでpythonを実行できる様にします。

dockerなど方法は色々ありますが、個人で気軽にやるならmac上でpythonを実行も可能です。

macでは標準でpythonを実行できますが、この記事では3系で記述しているので、まずはpythonのバージョンを確認して、2系か3系を確認します。

bash
python -V

Python 2.7.18 

もし2系だった場合は、下記のページを参考にして3系で実行できるようにします。
https://prog-8.com/docs/python-env


🔧 pythonで実行する内容を記述(手順①)

プロフィールのリポジトリが既にある場合は、githubからリポジトリをクローンします。

git clone リポジトリ名(githubのアカウント名)

ローカルにリポジトリを持ってこれたら、リポジトリ内にscriptsというファイル名を作成して、好きなファイル名で.pyファイルを作成します。この中にpythonを記述していきます!

pythonで記述する内容は大きく4つに分かれます。

  1. APIをリクエストして内容を取得する(connpassのAPIを利用)
  2. レスポンスで取得した情報を整形する
  3. README.mdに書き込む処理を記述する
  4. マークダウンファイルとして書き出す

1. APIをリクエストして内容を取得する

conpassが提供してくれているAPIを利用します。

updateReadme.py
import datetime
import requests

# 日付を指定する
date = datetime.datetime.now()
queryDate= "{0:%Y%m}".format(date)

# URL組み立てる
url = "https://connpass.com/api/v1/event/?nickname=conpassのアカウント名&ym="+ queryDate

# リクエストを投げる
res = requests.get(url)

# レスポンスをJSONに変換する
jsonData = res.json()

  • APIのリファレンスを参考にして、urlの末尾にクエリとして付与して、レスポンスを受け取っています。
  • 後続の処理で扱いやすい様にJSONに変換しています。

2. レスポンスで取得した情報を整形する

updateReadme.py
# 配列宣言
titleList = []
urlList = []
classTimeList = []
resultList = []

# 整形する
for item in jsonData["events"]:
  title = item['title']
  url = item['event_url']
  # 時間整形
  date = datetime.datetime.fromisoformat(item['started_at'])
  classTime = str(date.month) + "月"+ str(date.day) + "日" + str(date.hour) + "時" + str(date.minute) + "分〜"

  titleList.append(title)
  urlList.append(url)
  classTimeList.append(classTime)

# loopさせる
for (title, url, day) in zip(titleList, urlList, classTimeList):
  allList = ("- " + day + " [" + title + "](" + url + ")")
  resultList.append(allList)

# 結果
resultList = '\n'.join(resultList)

📃 ポイントとか工夫したところ

  • .append()を使って配列の末尾にイベント名などをそれぞれ格納しています。ループ処理にして取得する数が変わっても問題ならない様にしています。
  • 配列のままだと改行してくれずに表示してしまうため、'\n'.join()を使うことで、文字列要素ごとに改行しています。

3. README.mdに書き込む処理を記述する

updateReadme.py
import textwrap

docs_str = textwrap.dedent('''\
## 今月の視聴・参加イベント

{conpassList}

''').format(conpassList=resultList).strip()

📃 ポイントとか工夫したところ

  • テンプレートリテラルを使って、この中にREADME.mdの内容を記述します。テンプレートリテラルを使えば改行された状態で記述することができる為、書きやすく便利です。
  • textwrap.dedentで各行の先頭の空白削除しています。
  • テンプレート内で{}を書くと、この変数として扱うことができます。上の例では{conpassList}を変数として.format(conpassList=resultList).strip()すると、前述の2で成形した内容をテンプレートリテラルの中で展開する事ができます。

4. マークダウンファイルとして書き出す

updateReadme.py
with open('README.md', 'w') as f:
    f.write(docs_str)
  • with open(ファイル名,'w')と書いて、f.write(docs_str)とするとファイルが書き出されます。

  • pythonを実行してフォルダを確認すると、scriptsファイルにREADME.mdが生成されているはずです。

ファイル名を指定して実行
python updateReadme.py

同じディレクトリにREADME.mdができてればOK。

これでpythonの処理は完了です!!


🔌 ymlファイルで定期実行の設定(手順②)

次に、定期実行を行う様にするためのgithub actionsを動かすためのファイルを記述します。

準備

  1. リポジトリのルートディレクトリに.githubがあるか確認します。(隠しファイルはショートカットキー「command」+「shift」+「.」 で見れます)ファイルが無い場合はtouchコマンドで作成します。

  2. .githubファイル内にworkflowsというファイルを作成します。ファイル名はworkflowsじゃないと上手く動かないので注意。

  3. workflowsファイル内に、名前はなんでもいいのでymlファイルを作成します。

こんな感じで作ればOK。

├─.github
│ └─workflows
│   └─update-readme.yml

1. ymlファイル内に実行内容を記述する

こんな感じで書きます。
github Actionsでのymlファイルの書き方はある程度形式が決まっているので、調べると参考になる書き方が沢山載っています。

update-readme.yml 
name: update readme conpass schedule  # このワークフローの名前を記述(自由にきめてOK)
on:
  schedule:
    - cron: "0 15 * * *" # 午前0時に実行(UTC基準なので9時間引く)
  workflow_dispatch:
jobs:
  readme:
    runs-on: ubuntu-latest # 最新のubuntu環境で下記のジョブを実行
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-python@v2  # pythonをセットアップ
        with:
          python-version: "3.9" # pythonのバージョンを指定
          architecture: "x64" # アーキテクチャを指定
      - name: pip setting
        run: | # インストールを実行
          python -m pip install --upgrade pip
          pip install datetime
          pip install requests
      - name: run python
        working-directory: scripts # scriptsのファイルを指定
        run: |
          python updateReadme.py  # pythonを実行
          mv README.md ./../README.md # README.mdを上書き
      - name: commit files
        run: |  # githubの設定
          git config --global user.name "${{ github.actor }}"
          git config --global user.email "${{ github.actor }}@users.noreply.github.com"
          git add README.md
          git commit -m 'update README.md'
          git push origin main  # mainブランチにプッシュ

📃 ポイントとか

  • 今回は標準のライブラリを使用したが、標準外のライブラリを使うときは、scripts内でrequirements.txtを標準外のライブラリも実行できるようになります。今回は特に必要なかったので詳細は一番下の参考にリンクを載せます。

  • APIを叩くときに、認証情報など外部に見せたくない情報を書くときは、リポジトリ内のSecretsから設定することができます。設定すると、${{ }}でSecretsの内容を参照してくれる様になります。

  • 自分のユーザー名メールアドレスは${{ github.actor }}で取得することができます。

2. githubにリポジトリをpushする

pythonとymlファイルの記述が終わったら、リポジトリをgithubにpushします。

pushしたらgithubのページにアクセスし、github上でpythonが動くかどうか確認します。

確認ですぐに実行したい場合は、リポジトリにあるActionsからRunworkFlowをクリックすると、github Actioinが動きます。

実行してエラーが出ずに正常に終了すると成功です。
githubのトップページを見るとREADMD.mdが表示されています🎉🎉

3.(もしも)エラーになるとき

Online YAML Parser を使うとエラー内容がすぐに分かります。

http://yaml-online-parser.appspot.com/

  • 最初インデントの指定が間違っていてworkFlowがエラーになっていたので、Online YAML Parserに貼り付けて解決することができました。。

  • 1回上手くいけば、後はcronで指定した時間になれば更新してくれる様になります!!


🌲まとめ・所感とか

  • 今回はconnpassAPIを利用したが、他のAPIでも同じ様に流用すればオリジナルのREAD.meが作れそう。
  • python書ければスクレイピングとかでも応用もできそう。
  • github Actionsを使うと、サーバとか用意しなくても気軽に自動実行ができるので楽しい。

参考

  • requirements.txtを設定して、標準外のライブラリをgithubAcrionsを実行する

https://helve-blog.com/posts/git/github-actions-python/

  • Secretsを設定して、外部に見せたくない情報を書く方法

https://mottox2.com/posts/407

Discussion