くまがいブログ

エンジニアに目指す社会人

GitHub Actions を使って Gemini API で月報を自動生成する

目次

はじめに


前回の記事(HCの月報を簡単にしてみよう)では、GitHub Actions を使って Markdown ファイルの日報を自動的にマージし、月報作成の手間を省く方法を紹介しました。

今回は、その続編として、マージしたファイルを Gemini API に渡し、月報のたたきを自動生成する方法を紹介します。

このプロジェクトでは、生成 AI の API を活用し、自動的に月報のたたきを作成するシステムを構築しました。これにより、マージしたファイルを手作業で生成AIに渡さなくても良くなり使い勝手が良くなりました。

開発の背景


日報のマージは自動化できましたが、結局それを手作業でWebページの生成AIに渡して月報にまとめるは面倒くさいのと、GeminiのAPIには無料枠があるとのことなので使ってみたい!!

Gemini API を活用することで、

  • まとまった日報データから自動で月報を生成
  • フォーマットを指定して見やすい形に整形
  • 手作業の負担をさらに軽減

この仕組みを実装し、より効率的な月報作成を実現しました。

月報テンプレート


月報はmonthly_report_template.mdを使用して作成されます。
daily_reportレポジトリーのルートデレクトリに下記のファイルを作成してください。

monthly_report_template.md
# 月報

## はじめに
---
(今月の学習全体の概要を要約)

## 学習時間
---
- **合計学習時間:** XX時間

## 学習内容
---
- (リスト形式で主要な学習項目を整理)

## よかったところ
---
- (学習を通じて得られたポジティブな点をリスト化)

## 問題点と改善点
---

  ### 問題点
  - (学習や作業で直面した課題をリスト化)

  ### 改善点
  - (問題点に対してどのように対策を考えたかをリスト化)

## まとめ
---
(今月の振り返りと次月の方針)

このテンプレートに沿って、Gemini API により自動生成される月報の内容を整理します。

GitHub Actions の設定


GEMINI_API_KEY の設定
  1. リポジトリの「Settings(設定)」を開く。
  2. 「Secrets and variables」→「Actions」 を選択。
  3. 「New repository secret」をクリック。
  4. GEMINI_API_KEY を登録。


GITHUB_TOKENの設定をしていない方はこちらから

GitHub Actions ワークフローの作成


以下の 2 つのワークフローを作成します。

1. 日報のマージワークフロー

このワークフローでは、指定された月の日報 Markdown ファイルをマージし、最新のコミットメッセージを追加します。前回の記事より変更しました。

merge_daily_reports.yml
name: Merge Daily Reports

on:
  workflow_dispatch:
    inputs:
      target_month:
        description: '対象の月 (now: 今月, last: 先月)'
        required: true
        default: 'last'

jobs:
  merge:
    runs-on: ubuntu-latest
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}  # 環境変数でトークン設定

    steps:
      - name: リポジトリをチェックアウト(全ファイル取得)
        uses: actions/checkout@v4
        with:
          ref: main
          fetch-depth: 0

      - name: 実行対象の年月を決定
        run: |
          if [ "${{ github.event.inputs.target_month }}" == "now" ]; then
            YEAR=$(date +'%Y')
            MONTH=$(date +'%m')
          else
            YEAR=$(date --date="last month" +'%Y')
            MONTH=$(date --date="last month" +'%m')
          fi

          echo "YEAR=$YEAR" >> $GITHUB_ENV
          echo "MONTH=$MONTH" >> $GITHUB_ENV

      - name: Markdownファイルを結合(各ファイルの LAST_COMMIT_MSG を追加)
        run: |
          REPORT_DIR="$YEAR/$MONTH"
          MERGED_DIR="merged"
          OUTPUT_FILE="${MERGED_DIR}/${YEAR}-${MONTH}-merged.md"

          echo "Looking for files in: $REPORT_DIR"

          if [ ! -d "$REPORT_DIR" ]; then
            echo "Directory $REPORT_DIR does not exist. Skipping merge."
            exit 0
          fi

          # 保存先ディレクトリが存在しない場合は作成
          mkdir -p "$MERGED_DIR"

          # 先頭にタイトルを追加
          echo -e "# Merged Daily Reports for $YEAR-$MONTH\n\n" > "$OUTPUT_FILE"

          # 各ファイルに対して処理
          for file in $(ls "$REPORT_DIR"/*.md | sort); do
            # 各ファイルの最新コミットメッセージを取得
            LAST_COMMIT_MSG=$(git log -1 --pretty=%B -- "$file")

            # ファイルの内容を取得
            CONTENT=$(cat "$file")

            # 結合用のフォーマットで出力
            echo -e "## $(basename "$file")\n" >> "$OUTPUT_FILE"
            echo -e "**Last Commit Message:** $LAST_COMMIT_MSG\n" >> "$OUTPUT_FILE"
            echo -e "$CONTENT\n\n" >> "$OUTPUT_FILE"
          done

      - name: 変更をコミット & プッシュ
        run: |
          git config --global user.name "github-actions[bot]"
          git config --global user.email "github-actions[bot]@users.noreply.github.com"

          MERGED_DIR="merged"
          MERGED_FILE="${MERGED_DIR}/${YEAR}-${MONTH}-merged.md"

          if [ -f "$MERGED_FILE" ]; then
            git add "$MERGED_FILE"
            git commit -m "${YEAR}年${MONTH}月の日報を結合"

            # `GITHUB_TOKEN` を使って認証して push
            git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}.git
            git push origin main
          else
            echo "Merged file $MERGED_FILE does not exist. Skipping commit & push."
            exit 0
          fi
2. Gemini API による月報生成ワークフロー

このワークフローでは、マージした日報データを Gemini API に渡し、月報を自動生成します。

generate_monthly_report.yml
name: Generate Monthly Report

on:
  workflow_dispatch:
    inputs:
      target_month:
        description: '対象の月 (now: 今月, last: 先月)'
        required: true
        default: 'last'
      save_location:
        description: '保存先 (github)'
        required: true
        default: 'github'

jobs:
  generate_report:
    runs-on: ubuntu-latest
    env:
      GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    steps:
      - name: リポジトリをチェックアウト
        uses: actions/checkout@v4
        with:
          ref: main
          fetch-depth: 0

      - name: 実行対象の年月を決定
        run: |
          set -e
          if [ "${{ github.event.inputs.target_month }}" == "now" ]; then
            YEAR=$(date +'%Y') || { echo "ERROR: Failed to get current year"; exit 1; }
            MONTH=$(date +'%m') || { echo "ERROR: Failed to get current month"; exit 1; }
          else
            YEAR=$(date --date="last month" +'%Y') || { echo "ERROR: Failed to get last year"; exit 1; }
            MONTH=$(date --date="last month" +'%m') || { echo "ERROR: Failed to get last month"; exit 1; }
          fi

          echo "YEAR=$YEAR" >> $GITHUB_ENV
          echo "MONTH=$MONTH" >> $GITHUB_ENV
          echo "Target year: $YEAR, month: $MONTH"

      - name: Gemini API を使って月報を生成
        run: |
          set -e
          mkdir -p report
          MERGED_FILE="merged/${YEAR}-${MONTH}-merged.md"
          TEMPLATE_FILE="monthly_report_template.md"

          if [ ! -f "$MERGED_FILE" ]; then
            echo "ERROR: $MERGED_FILE does not exist. Skipping report generation."
            exit 0
          fi

          if [ ! -f "$TEMPLATE_FILE" ]; then
            echo "ERROR: Template file $TEMPLATE_FILE does not exist. Using default format."
            TEMPLATE_CONTENT="## ${YEAR}年${MONTH}月の月報\n\n### 今月の振り返り\n\n### 達成したこと\n\n### 課題と改善点\n\n### 来月の目標"
          else
            TEMPLATE_CONTENT=$(cat "$TEMPLATE_FILE")
          fi

          # Gemini API 用のプロンプト作成
          PROMPT="以下のフォーマットに沿って、Markdown ファイルの内容を要約して月報を作成してください。\n\n---\nテンプレート:\n${TEMPLATE_CONTENT}\n---\n\n対象の内容:\n$(cat "$MERGED_FILE")"

          # Gemini API で月報を生成
          SUMMARY=$(curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${GEMINI_API_KEY}" \
            -H "Content-Type: application/json" \
            -d '{
              "contents": [{
                "parts": [{ "text": "'"$PROMPT"'" }]
              }]
            }' | jq -r '.candidates[0].content.parts[0].text')

          if [ -z "$SUMMARY" ]; then
            echo "ERROR: Failed to generate summary from Gemini API."
            exit 1
          fi

          echo "$SUMMARY" > report/report_summary.txt

      - name: GitHub に保存
        run: |
          set -e
          REPORT_FILE="report/${YEAR}-${MONTH}-report.md"
          echo -e "# ${YEAR}年${MONTH}月の月報\n\n$(cat report/report_summary.txt)" > "$REPORT_FILE"

          git config --global user.name "github-actions[bot]"
          git config --global user.email "github-actions[bot]@users.noreply.github.com"

          git add "$REPORT_FILE"
          git commit -m "${YEAR}年${MONTH}月の月報を追加"
          git push origin main

月報のたたき


実際に生成された月報

2025-02-report.md
# 20252月 月報

目次
- [はじめに](#はじめに)
- [学習時間](#学習時間)
- [学習内容](#学習内容)
- [よかったところ](#よかったところ)
- [問題点と改善点](#問題点と改善点)
  - [問題点](#問題点)
  - [改善点](#改善点)
- [まとめ](#まとめ)


## はじめに
---
20252月は、主にDjangoフレームワークを用いたECサイト構築に集中的に取り組みました。特にデプロイ、カート機能、チェックアウト機能の実装に苦戦しつつも、タイピング練習と並行して、ハッカソンにも参加しました。進捗は遅いながらも、着実に理解を深めることができました。

## 学習時間
---
- **合計学習時間:** 68時間

## 学習内容
---
- タイピング練習
- Django を用いた EC サイト構築
    - Herokuへのデプロイ
    - カート機能の実装
    - チェックアウト機能の実装
- Cloudinaryを用いたファイル保存
- ハッカソンへの参加(「1年に1度だけ使いたいもの」をテーマにしたサービス開発)
- ブログサイトのエラー修正
- PRの作成と修正

## よかったところ
---
- Cloudinaryを繋げられた(理由はなんとなくしかわからない)
- レビューしてもらえる環境に感謝
- ハッカソンで自身の成長を感じられた
- AIツール(Gamma)を使ってプレゼン資料を効率的に作成できた

## 問題点と改善点
---

  ### 問題点
  - デプロイに苦戦し、時間がかかった
  - エラー発生時の原因特定に時間がかかった
  - 画像の保存場所と表示場所の不一致に時間がかかった
  - カート画面のレイアウト実装に苦戦
  - チェックアウト機能に必要なテーブル設計に時間がかかった
  - 二日休むとどこまで進んだか確認するのが億劫になる
  - ハッカソンのテーマに沿ったサービスをなかなか思いつけない
  - やることが決まってもなかなかコーディングに取り掛かれなかった
  - プレゼン資料作成に時間がかかった
  - 一つ一つの機能実装につまづき、なかなか先に進まないと感じた
  
  ### 改善点
  - Herokuチュートリアルを参考に、デプロイ手順を理解する
  - デプロイは最低限の段階で済ませておく
  - エラー処理について事前に調査し、対応を考える
  - gitignoreの設定を徹底する
  - テーブル設計を事前にしっかりと検討する
  - 進捗状況をこまめに記録し、確認しやすいようにする
  - アイデア出しの時間を設け、テーマに沿ったサービスを検討する
  - 小さなタスクに分割し、コーディングに取り掛かりやすくする
  - AIツール(GAMMA)を積極的に活用し、資料作成を効率化する

## まとめ
---
2月はECサイト構築におけるデプロイ、カート機能、チェックアウト機能の実装に多くの時間を費やしました。特にデータベース設計の重要性を再認識しました。また、ハッカソンへの参加を通じて、自身の成長を感じることができました。3月は、チェックアウト機能の実装を完了させ、ECサイト全体の完成度を高めることを目標とします。また、日々の学習内容をより詳細に記録し、進捗を可視化することで、学習効率の向上を目指します。

まとめ


GitHub Actions を活用し、日報の自動マージと Gemini API による月報の自動生成を実装しました。手作業でまとめる手間が省け、よりスムーズに月報を作成できるようになりました。

特に、初めて生成 AIのAPI を使って月報のたたきを作成できた瞬間は、本当に感動しました。

これまで手作業で行っていた作業が、API を叩くだけで自動化できるという体験は、新しい可能性を感じるものでした。

この仕組みをさらに改善し、より精度の高いレポート生成や他の自動化にも応用していきたいと思います。