0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

第3回:GitHubのMarkdownにプロフィールバッジを自動挿入

0
Last updated at Posted at 2026-07-26

【GitHub Actions】Markdownにプロフィールバッジを毎回手動で貼るのが面倒…Pushするだけで自動挿入する仕組みを作った

この記事でわかること

  • ✅ Markdownファイルにプロフィールバッジを自動挿入する方法
  • ✅ 変更された.mdのみ対象で無駄なCommitを防ぐ仕組み
  • 重複挿入を防ぐマーカー方式の実装
  • ✅ 私が実際に運用して気づいた2つの落とし穴と対処法

はじめに:この悩み、ありませんか?

GitHubのREADMEやドキュメントを書いていると、こんな経験ありませんか?

「新しいMarkdownファイルを作るたびに、GitHub・Qiita・Zennのプロフィールバッジを手動で貼るのが面倒くさい…」

「バッジのリンク先を変更したいのに、全ファイルを手動で修正するのが大変で更新が滞る…」

「バッジを貼り忘れて、ドキュメントの統一感がなくなってしまう…」

私も複数リポジトリで同じバッジを管理していて、新規ファイル作成時の貼り忘れリンク変更時の一斉修正に何度も苦労しました。そこで、MarkdownファイルをPushするだけで、プロフィールバッジが自動的に挿入・更新される仕組みを作りました。

本記事では、そのワークフローを完全公開します。


なぜプロフィールバッジを自動挿入するのか

GitHubのREADMEやドキュメントにプロフィールバッジを貼ることで、以下の効果があります。

効果 説明
信頼性向上 執筆者のGitHub・Qiita・Zennプロフィールへ誘導でき、記事の信頼性が増す
フォロワー増加 読者が他のプラットフォームでもフォローしやすくなる
統一感 全ドキュメントでバッジの位置・デザインが統一される
自己ブランディング 技術ブログやSNSとの連携が強化される

しかし、手動管理では以下の問題が発生します。

  • 新規Markdown作成時に貼り忘れる
  • バッジのリンク先変更時に全ファイル修正が必要
  • バッジの位置がファイルごとにばらつく

そこで、GitHub Actionsで完全自動化します。

Markdownファイルを Push
        │
        ▼
GitHub Actions 起動
        │
        ▼
変更された .md のみ検出
        │
        ▼
見出し直後にバッジを挿入
        │
        ▼
既存バッジがあればスキップ
        │
        ▼
変更があれば自動 Commit & Push

開発者がやることは「Markdownを書いてPushする」だけ。
バッジの管理は一切不要です。


このWorkflowで実現できること

  • 🏷️ プロフィールバッジの自動挿入 — GitHub / Qiita / Zenn / LinkedIn
  • 🎯 変更されたMarkdownのみ対象 — 無駄なCommitを防ぐ
  • 🔄 重複挿入防止PROFILE_BADGE_START/ENDマーカーで管理
  • 📍 見出し直後に自然に挿入 — Markdown構造を崩さない
  • 🚀 GitHub Pushだけで自動化 — 手作業ゼロ
  • 🧹 変更がなければCommitしない — 履歴をクリーンに保持

システム構成(処理の流れ)

Markdownファイルを Push
        │
        ▼
GitHub Actions 起動
        │
        ├─ push時:変更された .md のみ検出
        └─ workflow_dispatch時:全 .md を対象
        │
        ▼
各 .md ファイルを処理
        │
        ▼
最初の # 見出しを検出
        │
        ▼
PROFILE_BADGE_START/END マーカーを確認
        │
        ├─ 既存バッジあり → スキップ
        └─ バッジなし → 見出し直後に挿入
        │
        ▼
変更があれば自動 Commit & Push

事前準備

特別なツールのインストールは不要です。

Workflowファイルは以下に配置します。

.github/workflows/insert-profile-badge.yaml

ワークフロー全文

name: Insert Profile Badges into Markdown

on:
  push:
    paths:
      - '**.md'
  workflow_dispatch:

jobs:
  insert-badges:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 2

      - name: Detect target Markdown files
        id: detect
        run: |
          if [ "${{ github.event_name }}" = "push" ]; then
            changed_files=$(git diff --name-only HEAD~1 HEAD -- '*.md')
          else
            changed_files=$(find . -name '*.md' -not -path './.git/*')
          fi

          if [ -z "$changed_files" ]; then
            echo "No Markdown files to process."
            echo "files=" >> $GITHUB_OUTPUT
            exit 0
          fi

          echo "files<<EOF" >> $GITHUB_OUTPUT
          echo "$changed_files" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Insert profile badges
        if: steps.detect.outputs.files != ''
        run: |
          BADGE_START='<!-- PROFILE_BADGE_START -->'
          BADGE_END='<!-- PROFILE_BADGE_END -->'

          BADGE_CONTENT='<!-- PROFILE_BADGE_START -->

[![GitHub](https://img.shields.io/badge/GitHub-Profile-181717?logo=github)](https://github.com/xxxxxxxx)
[![Qiita](https://img.shields.io/badge/Qiita-Profile-55C500?logo=qiita&logoColor=white)](https://qiita.com/xxxxxxxx)
[![Zenn](https://img.shields.io/badge/Zenn-Profile-3EA8FF?logo=zenn&logoColor=white)](https://zenn.dev/xxxxxxxx)
[![LinkedIn](https://img.shields.io/badge/LinkedIn-Profile-0A66C2?logo=linkedin&logoColor=white)](https://www.linkedin.com/in/xxxxxxxx)

<!-- PROFILE_BADGE_END -->'

          echo "${{ steps.detect.outputs.files }}" | while IFS= read -r file; do
            [ -z "$file" ] && continue

            # 既存バッジチェック
            if grep -q "$BADGE_START" "$file"; then
              echo "Skipped (already has badge): $file"
              continue
            fi

            # 最初の # 見出しを検出
            first_heading=$(grep -n '^#' "$file" | head -n 1 | cut -d: -f1)

            if [ -n "$first_heading" ]; then
              # 見出しの次の行に挿入
              sed -i "${first_heading}a\\
\\
${BADGE_CONTENT}\\
" "$file"
            else
              # 見出しがない場合はファイル先頭に挿入
              echo -e "${BADGE_CONTENT}\n\n$(cat "$file")" > "$file"
            fi

            echo "Inserted badge: $file"
          done

      - name: Commit and push if changed
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add -A
          if git diff --cached --quiet; then
            echo "No changes to commit."
          else
            git commit -m "chore: insert profile badges into Markdown files [skip ci]"
            git push
          fi

ワークフローのポイント解説

① 対象ファイルの検出

if [ "${{ github.event_name }}" = "push" ]; then
  changed_files=$(git diff --name-only HEAD~1 HEAD -- '*.md')
else
  changed_files=$(find . -name '*.md')
fi
  • push時:変更された.mdのみを対象にし、無駄な処理とCommitを防ぐ
  • workflow_dispatch時:リポジトリ全体の.mdを対象にし、一斉更新が可能

② 重複挿入防止

if grep -q "$BADGE_START" "$file"; then
  echo "Skipped (already has badge): $file"
  continue
fi

<!-- PROFILE_BADGE_START --> / <!-- PROFILE_BADGE_END --> マーカーで既存バッジを検出。同じファイルにバッジが2重に挿入されることを完全に防ぎます。

③ 見出し直後への自然な挿入

first_heading=$(grep -n '^#' "$file" | head -n 1 | cut -d: -f1)
sed -i "${first_heading}a\\... " "$file"

Markdownの構造を崩さず、最初の#見出しの直後に自然に挿入します。見出しがない場合はファイル先頭にフォールバック。

④ 変更がなければCommitしない

if git diff --cached --quiet; then
  echo "No changes to commit."

無駄なコミット履歴を増やさず、Gitログをクリーンに保ちます。


実際に運用して気づいた2つの落とし穴

🚨 落とし穴1:バッジ挿入後の無限ループ

初期版では、バッジ挿入後のCommitが新たなpushイベントを発火し、Workflowが無限ループする問題がありました。

対処:Commitメッセージに [skip ci] を付与し、CIトリガーを回避するよう制御しました。

git commit -m "chore: insert profile badges [skip ci]"

🚨 落とし穴2:マーカー誤検出でバッジ更新がされない

PROFILE_BADGE_START という一般的な文字列が、他のコメントと誤ってマッチするケースがありました。

対処:マーカーを <!-- PROFILE_BADGE_START --> というHTMLコメント形式に変更し、誤検出を完全に排除しました。


導入後の効果

項目 Before After
新規Markdown作成時のバッジ貼り付け 手動(1〜2分/ファイル) 0分(自動)
プロフィールリンク変更時の一斉修正 全ファイル手動修正(30分〜) Workflow変更だけで全ファイル反映
バッジ貼り忘れ 頻発 物理的に発生しない
ドキュメントの統一感 ばらつきあり 全ファイルで統一
Git履歴の汚染 手動修正Commitが増える [skip ci]でCI履歴をクリーンに

応用アイデア

このWorkflowの考え方は、以下にも応用できます。

アイデア 内容
CIステータスバッジ自動挿入 READMEにテスト結果やカバレッジバッジを自動追加
ライセンスバッジ自動挿入 リポジトリのライセンスに応じたバッジを自動追加
ドキュメントテンプレート自動生成 新規.md作成時にテンプレートを自動挿入
Prettier自動整形 MarkdownのフォーマットをPush時に自動修正
Zenn/Qiita自動投稿 記事公開と連携した自動化

GitHub Actionsは「小さな自動化」を積み重ねると、驚くほど開発体験が向上します。


今後の展開

このWorkflowは、GitHub Actions活用シリーズの第3弾です。

第4回では、バッジのリンク先変更時に、既存のバッジを自動更新する仕組みを紹介しています。本記事と組み合わせることで、「新規挿入+既存更新」の完全自動化が実現できます。


まとめ

項目 内容
解決した課題 プロフィールバッジの手動貼り付け・貼り忘れ・一斉修正の手間
キーワード GitHub Actions, Markdown自動化, プロフィールバッジ, Shields.io, CI/CD
得られる効果 ドキュメント統一感向上、自己ブランディング強化、保守コスト削減

この仕組みを導入すれば、**「Markdownを書いてPushするだけで、プロフィールバッジが自動的に付く」**世界が実現します。複数リポジトリを運用している方には特にオススメです。

ぜひご自身のリポジトリで試してみてください。動作報告や改善案があれば、コメントやGitHub Issueでお知らせください!


ソースコード

今回ご紹介したGitHub Actions Workflowのソースコードは、GitHubでも公開しています。

以下のリポジトリから、Workflowファイルや設定内容を確認できます。

本記事がお役に立ちましたら、いいね❤️GitHub Star⭐ をいただけると励みになります!IssueやPull Requestも歓迎していますので、改善案や機能追加のアイデアがありましたら、お気軽にご連絡ください。


📢 掲載通知を受け取る
著者をフォローして次回または新掲載の通知をお待ちください!


0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?