🐈‍⬛

GitHub Profileをかっこよくしたい!

に公開

はじめに

はじめて記事を書きます。よろしくお願いします。

GitHubのプロフィールをおしゃれにカッコよく見せる方法があると知り、やってみたことをまとめました。

導入

とりあえず始める!

クイックスタート

  1. 自分のアカウント名と全く同じリポジトリを用意する
  2. リポジトリはパブリック(公開)にする
  3. リポジトリ内にREADME.mdを作成する
  4. 作成したREADME.mdがユーザーのGitHubプロフィール画面に反映される

README.md内の要素の例

  • 自己紹介
  • SNS、Blogリンク
  • 技術スタック
  • 画像(バナーやアイコン)
  • GitHub Stats
    • リポジトリ
    • コミット
    • トロフィー

こだわりポイント

  • 絵文字を使う(多用には注意)

  • READMEだけはGitHub上のEditerでも編集できるが、リポジトリをローカルにクローンすることを推奨

  • markdownファイルはhtml要素も書ける

    • html要素で配置してcssで自分好みに調整したりもできる(一部のcssはGitHub上では反映されない)
  • いろいろなwidgetやtemplateを使えるので、試してみて決める

    https://github.com/durgeshsamariya/awesome-github-profile-readme-templates/tree/master/templates

プライベートでの作業履歴の反映(本編)

前述したところまでは少し調べると辿り着く内容ですが、ここからが自分の一番苦労したところです。誰かの参考になれば幸いです。

まず前提として、誰でも使えるwidgetやtemplateで反映させるステータスにはプライベートリポジトリでの作業や進行は含まれていません。それを実現するには、個人でAPIを立てる必要があります。

例として、「Top Languages Card」のwidgetで試してみます。

通常のURL

個人APIのURL

後者はTypescriptのコードがよく使われているというのが反映されていると思います。これはプライベートリポジトリで使われている言語の情報も取得できています。


API実装手順

ここからAPI実装の流れを解説します。

様々な方法が存在するとは思いますがここで説明するのは、このwidgetを提供しているリポジトリ内で推奨されているVercel(無料プラン)を使ってAPIを構築します。

  1. https://github.com/anuraghazra/github-readme-stats 公式リポジトリを開く

  2. このリポジトリをフォーク(Fork)する

  3. vercel.comにアクセスする

  4. GitHub認証をつかってログインする

  5. リポジトリへのアクセスを許可する。

    • 公式のREADME内では「すべてのリポジトリへをアクセスを許可する」とありますが、私はフォークしたリポジトリ限定を許可しました。(それでも今回の目的に沿って正常に動作するはずです!)
  6. Vercelのダッシュボードに移動する

  7. 右上の「Add New…」をクリックし、Projectを開く

  8. Import Git Repository」でフォークしたリポジトリを選んでインポートする

  9. GitHubを開いてトークン(Personal Access Token)を作る

    • repo と user の許可を与える
  10. Vercelに戻り、Configure Project内の「Environment Variables」で先ほど作ったTokenをセットする(名前はなんでもOK)

  11. Deployをクリックする

これでAPIの実装は完了です。

あとはURL部分を自分でつくったプロジェクトドメインにして、README.mdに記述すれば反映されるはずです。

「Top Languages Card」

[![{$user}'s GitHub stats](https://{$YOUR_DOMAIN_URL}/api/top-langs/?username={$user}&count_private=true&layout=compact)](https://github.com/{$user}/github-readme-stats)

ここでもう一つ問題が見つかりました。このままだと自分のAPIパスがネット上に公開されてしまうということです。APIは.svgを返すだけですし、無料プランしか登録していないので使われても大したことはないのですが、制限かけられるまでAPIをリクエストされると面倒臭いな、というくらいです。

ただ、今回プロフィールをカスタマイズしている理由として、誰か(技術者や企業)にみてもらいたいという思いもあります。個人のAPIパスを公開リポジトリに載せるのは自分の技術者としての評価を下げることになってしまい、いかがなものかと考えました。

ローカルで実装方法について試行錯誤し、APIパスをそのまま載せるのではなく環境変数に入力して使おうという結論に至ったんですが、ここでまた新しい壁にぶち当たりました。

ローカルとGitHub上の環境で違うのは動的に処理ができない点です。

ローカルではコマンドを使って環境変数上のAPIパスにアクセスすることができますが、GitHubのリポジトリ上での動作はあくまでもREADME.mdをプレビュー表示しているだけにすぎません。


GitHub Actions

GitHub Actionsとは、

GitHub上で動作する自動化の仕組みです。

リポジトリに対して「プッシュ(push)」や「プルリクエスト(pull request)」などのイベントが発生した際や、指定したスケジュールの時間に合わせて、あらかじめ定義しておいた処理(ワークフロー)を自動で実行することができます。

私はこれまでにかかわってきたプロジェクトでCI/CDでLinterを動かしたりしたことはあったのですが、あまりその実態について理解せずに使ってしまっていたこともあり、その存在を忘れていました。

そして今回初めて自分でGitHub Actionsを設定してみることにしました。

作業はローカルにクローンして行っています。

  1. プロフィール用のリポジトリにimg or images (画像ディレクトリ)を作る

  2. README内のwidgetsの画像をimgタグに変更し、画像ディレクトリから参照するようにする

    <a href="https://github.com/{$user}">
      <img align="left" src="img/profile_stats.svg"/>
    </a>
    <a href="https://github.com/{$user}">
      <img align="left" src="img/profile_languages.svg"/>
    </a>
    
  3. .github/workflows/にyamlファイルを作成する

    • 今回は二つの画像を表示させるworkflowになっている
    • JST 6:00に更新される
    # .github/workflows/update_profile_stats.yml
    name: Update profile SVGs
    
    on:
      schedule:
        # JST 06:00 → UTC 21:00
        - cron: '0 21 * * *'
      workflow_dispatch: {}
    
    concurrency:
      group: update-profile-svgs
      cancel-in-progress: false
    
    permissions:
      contents: write
    
    jobs:
      update:
        runs-on: ubuntu-latest
        env:
          PROFILE_STATS_URL: ${{ secrets.PROFILE_STATS_URL }}
          PROFILE_LANGUAGES_URL: ${{ secrets.PROFILE_LANGUAGES_URL }}
        steps:
          - name: Checkout
            uses: actions/checkout@v4
    
          - name: Validate secrets
            run: |
              if [ -z "${PROFILE_STATS_URL:-}" ] || [ -z "${PROFILE_LANGUAGES_URL:-}" ]; then
                echo "PROFILE_STATS_URL or PROFILE_LANGUAGES_URL is not set in Secrets"; exit 1
              fi
    
          - name: Fetch and update SVGs
            run: |
              set -euo pipefail
    
              PAIRS=(
                "${PROFILE_STATS_URL}|img/profile_stats.svg"
                "${PROFILE_LANGUAGES_URL}|img/profile_languages.svg"
              )
    
              for pair in "${PAIRS[@]}"; do
                IFS='|' read -r url dest <<< "$pair"
                tmp="$(mktemp)"
                echo "→ Fetch to: $dest"
                # キャッシュ回避用のクエリを付与して必ずAPIを叩く
                if echo "$url" | grep -q '?'; then
                  bust_url="${url}&_ts=$(date +%s)"
                else
                  bust_url="${url}?_ts=$(date +%s)"
                fi
    
                curl -fsSL --retry 3 --retry-delay 2 "$bust_url" -o "$tmp"
    
                if [ ! -s "$tmp" ]; then
                  echo "  ✗ empty file (skip)"; rm -f "$tmp"; continue
                fi
    
                mkdir -p "$(dirname "$dest")"
                # 差分の有無に関係なく常に上書き
                mv "$tmp" "$dest"
                echo "  ✓ wrote: $dest"
              done
    
          - name: Update marker file
            run: |
              set -euo pipefail
              mkdir -p .github
              date -u +%FT%TZ > .github/last-run.txt
    
          - name: Commit & Push
            run: |
              git config user.name  "github-actions[bot]"
              git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
              git add .github/last-run.txt img/profile_stats.svg img/profile_languages.svg
              git commit -m ":art: update profile stats"
              git push
    
    
  4. 内容を確認してコミット → プッシュ

  5. GitHub上のプロフィール用のリポジトリで Settings > Secrets and variables > Actionsに移動し、Repository secretsを作成する。ここで、個人のAPIドメインを使ったパスを指定します。

    • New repository secrets」を選択し作成

      https://{$YOUR_DOMAIN_URL}/api/?username={$user}&count_private=true&layout=compact
      
      https://{$YOUR_DOMAIN_URL}/api/top-langs/?username={$user}&count_private=true&layout=compact
      
  6. Actions内に今回追加したworkflow 「Update profile SVGs」が追加されているはず。「Run workflow」でイベントをトリガーしてテストする。

今回のworkflowについて、わかる範囲ですこし説明をしておきます。

  • secretsの値を環境変数に入力し、SVGファイルに出力するために使っている。
  • もともと作成していたyamlファイルでは、更新があったときのみコミットするように記述していたが、画像に更新があってもなくてもコミットしたいということで時刻などログを記述するファイルを作って空コミットを防止。
  • このworkflowで行っていることや命名などに関しては、自分好みにカスタマイズしてもらって構わない。(むしろしたほうが良い)

まとめ

いかがだったでしょうか?

はじめは開発中に気分転換で始めたGitHubプロフィールのカスタマイズですが、いつの間にか技術的なチャレンジにまで発展してしまいました笑。結果として、夏休みの自由研究のようなことができたと思っているので満足しています。それぞれの工程を説明している方はいらっしゃるのですが、一貫した流れの説明を残したいと思いこの記事を書きました。

まだプロフィールのカスタマイズでやってみたいことはあるので、この記事を更新することもあるかもしれません。それに、この休み期間に挑戦してみたいことはもっとあるので、気が向いたらまた記事を書いてみようと思います。それでは!

参考

https://note.com/watasi_y/n/n0fa26517bba4
https://zenn.dev/pageo/articles/a9acf452a84003

Discussion