11name : Generate Blog Images
22
33on :
4- workflow_dispatch : # 只支持手动触发
4+ push :
5+ branches :
6+ - main
7+ paths :
8+ - ' content/**/*.md'
9+ workflow_dispatch :
10+ inputs :
11+ image_service :
12+ description : ' AI service to use'
13+ required : false
14+ default : ' modelscope'
15+ type : choice
16+ options :
17+ - modelscope
18+ - gemini
19+ - both
20+ target_type :
21+ description : ' Generation target'
22+ required : false
23+ default : ' both'
24+ type : choice
25+ options :
26+ - covers
27+ - articles
28+ - both
29+ force_regenerate :
30+ description : ' Force regenerate existing images'
31+ required : false
32+ default : false
33+ type : boolean
34+ auto_generate :
35+ description : ' Auto-generate for new/updated articles only'
36+ required : false
37+ default : true
38+ type : boolean
539
640permissions :
741 contents : write
@@ -26,27 +60,57 @@ jobs:
2660 run : |
2761 cd scripts
2862 pip install -r requirements.txt
63+ pip install requests pillow python-dotenv
2964
3065 - name : Detect changed blog files
3166 id : detect-changes
3267 run : |
3368 # 获取本次提交修改的.md文件
3469 if [ "${{ github.event_name }}" = "push" ]; then
3570 if [ -z "${{ github.event.before }}" ]; then
36- # No previous commit to diff against (e.g., first commit), so no changed files
37- CHANGED_FILES=""
71+ # First commit, process all content files
72+ CHANGED_FILES=$(find content -name "*.md" -not -path "*/daily_ai/*" | tr '\n' ' ')
73+ echo "First commit detected, processing all files"
3874 else
39- CHANGED_FILES=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep '\.md$' | grep '^content/' || true)
75+ # Get changed .md files, excluding daily_ai
76+ CHANGED_FILES=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep '\.md$' | grep '^content/' | grep -v 'daily_ai' || true)
77+ echo "Push detected, analyzing changed files"
4078 fi
4179 else
4280 # 手动触发时处理所有没有图片的博客
4381 CHANGED_FILES=""
82+ echo "Manual workflow triggered"
83+ fi
84+
85+ # Filter for files that need AI covers (have description but no ai_cover)
86+ NEED_AI_COVER=""
87+ if [ -n "$CHANGED_FILES" ]; then
88+ for file in $CHANGED_FILES; do
89+ if [ -f "$file" ]; then
90+ # Check if file has description
91+ if grep -q "^description:" "$file"; then
92+ # Check if file doesn't have ai_cover or ai_generated: true
93+ if ! grep -q "ai_cover:" "$file" || ! grep -q "ai_generated: true" "$file"; then
94+ NEED_AI_COVER="$NEED_AI_COVER $file"
95+ echo "Need AI cover: $file"
96+ else
97+ echo "Already has AI cover: $file"
98+ fi
99+ else
100+ echo "No description, skipping: $file"
101+ fi
102+ fi
103+ done
44104 fi
45105
46106 echo "changed_files<<EOF" >> $GITHUB_OUTPUT
47107 echo "$CHANGED_FILES" >> $GITHUB_OUTPUT
48108 echo "EOF" >> $GITHUB_OUTPUT
49109
110+ echo "need_ai_cover<<EOF" >> $GITHUB_OUTPUT
111+ echo "$NEED_AI_COVER" >> $GITHUB_OUTPUT
112+ echo "EOF" >> $GITHUB_OUTPUT
113+
50114 - name : Generate images for new blogs
51115 if : steps.detect-changes.outputs.changed_files != ''
52116 env :
@@ -72,42 +136,152 @@ jobs:
72136 cd scripts
73137 python generate_image.py --backfill
74138
139+ - name : Auto-generate ModelScope AI Covers for new blogs
140+ if : github.event_name == 'push' && steps.detect-changes.outputs.need_ai_cover != ''
141+ env :
142+ MODELSCOPE_API_KEY : ${{ secrets.MODELSCOPE_API_KEY }}
143+ TEXT2IMAGE_PROVIDER : modelscope
144+ WORKFLOW_MODE : true
145+ FORCE_REGENERATE : false
146+ run : |
147+ cd scripts
148+ echo "🤖 Auto-generating ModelScope AI covers for new blogs..."
149+ echo "Files needing AI covers: ${{ steps.detect-changes.outputs.need_ai_cover }}"
150+
151+ # Process files that need AI covers (limit to avoid API overload)
152+ NEED_COVER_FILES="${{ steps.detect-changes.outputs.need_ai_cover }}"
153+ file_count=0
154+ max_files=5 # Limit per push to avoid API overload
155+
156+ for file in $NEED_COVER_FILES; do
157+ if [ -f "$file" ] && [ $file_count -lt $max_files ]; then
158+ echo "Processing: $file"
159+ python ai_cover_generator.py --workflow-mode --target=covers --specific-file="$file"
160+ file_count=$((file_count + 1))
161+ elif [ $file_count -ge $max_files ]; then
162+ echo "Reached limit of $max_files files, skipping remaining files"
163+ break
164+ fi
165+ done
166+
167+ echo "✅ Auto-generation completed: processed $file_count files"
168+
169+ - name : Generate ModelScope AI Covers (manual trigger)
170+ if : github.event_name == 'workflow_dispatch' && (contains(github.event.inputs.image_service, 'modelscope') || github.event.inputs.image_service == 'both')
171+ env :
172+ MODELSCOPE_API_KEY : ${{ secrets.MODELSCOPE_API_KEY }}
173+ TEXT2IMAGE_PROVIDER : modelscope
174+ WORKFLOW_MODE : true
175+ FORCE_REGENERATE : ${{ github.event.inputs.force_regenerate }}
176+ run : |
177+ cd scripts
178+ echo "🤖 Generating ModelScope AI covers..."
179+ echo "Target: ${{ github.event.inputs.target_type }}"
180+ echo "Force regenerate: $FORCE_REGENERATE"
181+
182+ # Generate covers if target includes covers
183+ if [[ "${{ github.event.inputs.target_type }}" == "covers" || "${{ github.event.inputs.target_type }}" == "both" ]]; then
184+ python ai_cover_generator.py --workflow-mode --target=covers --force=${FORCE_REGENERATE}
185+ else
186+ echo "Skipping cover generation (target: articles only)"
187+ fi
188+
75189 - name : Create images directory
76190 run : |
77191 mkdir -p static/images/articles
78- echo "Created static/images/articles directory"
192+ mkdir -p static/images/generated-covers
193+ echo "Created image directories"
79194
80195 - name : Commit generated images
81196 if : always()
82197 env :
83198 GITHUB_TOKEN : ${{ secrets.MY_GITHUB_TOKEN }}
84199 run : |
85- # 检查是否有新的图片文件
200+ git config --local user.email "action@github.com"
201+ git config --local user.name "GitHub Action"
202+ git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}.git
203+
204+ has_changes=false
205+
206+ # Check for article images
86207 if [ -d "static/images/articles" ] && [ "$(ls -A static/images/articles 2>/dev/null)" ]; then
87- echo "Found new images to commit"
88- git config --local user.email "action@github.com"
89- git config --local user.name "GitHub Action"
90- git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}.git
208+ echo "Found new article images to commit"
91209 git add static/images/articles/
92- git commit -m "Auto-generate blog images [skip ci]" || echo "No changes to commit"
210+ has_changes=true
211+ fi
212+
213+ # Check for generated covers
214+ if [ -d "static/images/generated-covers" ] && [ "$(ls -A static/images/generated-covers 2>/dev/null)" ]; then
215+ echo "Found new AI-generated covers to commit"
216+ git add static/images/generated-covers/
217+ has_changes=true
218+ fi
219+
220+ # Commit if there are changes
221+ if [ "$has_changes" = true ]; then
222+ git commit -m "🤖 Auto-generate blog images and AI covers [skip ci]" || echo "No new changes to commit"
93223 git push
224+ echo "✅ Images committed successfully"
94225 else
95- echo "No new images to commit"
226+ echo "ℹ️ No new images to commit"
96227 fi
97228
98229 - name : Create summary
99230 if : always()
100231 run : |
101232 echo "## Blog Image Generation Summary" >> $GITHUB_STEP_SUMMARY
102233 echo "" >> $GITHUB_STEP_SUMMARY
234+ echo "### 📋 Configuration" >> $GITHUB_STEP_SUMMARY
103235 echo "**Trigger:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
236+ echo "**Image Service:** ${{ github.event.inputs.image_service || 'N/A' }}" >> $GITHUB_STEP_SUMMARY
237+ echo "**Target Type:** ${{ github.event.inputs.target_type || 'N/A' }}" >> $GITHUB_STEP_SUMMARY
238+ echo "**Force Regenerate:** ${{ github.event.inputs.force_regenerate || 'false' }}" >> $GITHUB_STEP_SUMMARY
104239 echo "**Changed files:** ${{ steps.detect-changes.outputs.changed_files }}" >> $GITHUB_STEP_SUMMARY
105240 echo "" >> $GITHUB_STEP_SUMMARY
106- echo "### Generated Images:" >> $GITHUB_STEP_SUMMARY
107- if [ -d "static/images/articles" ]; then
108- ls -la static/images/articles/ | tail -n +2 | while read line; do
109- echo "- $line" >> $GITHUB_STEP_SUMMARY
241+
242+ echo "### 🖼️ Generated Article Images" >> $GITHUB_STEP_SUMMARY
243+ if [ -d "static/images/articles" ] && [ "$(ls -A static/images/articles 2>/dev/null)" ]; then
244+ echo "| Filename | Size | Type |" >> $GITHUB_STEP_SUMMARY
245+ echo "|----------|------|------|" >> $GITHUB_STEP_SUMMARY
246+ cd static/images/articles
247+ ls -lh *.jpg *.png *.webp 2>/dev/null | while read -r line; do
248+ filename=$(echo $line | awk '{print $9}')
249+ size=$(echo $line | awk '{print $5}')
250+ echo "| $filename | $size | Image |" >> $GITHUB_STEP_SUMMARY
251+ done
252+ else
253+ echo "No article images generated" >> $GITHUB_STEP_SUMMARY
254+ fi
255+ echo "" >> $GITHUB_STEP_SUMMARY
256+
257+ echo "### 🤖 Generated AI Covers" >> $GITHUB_STEP_SUMMARY
258+ if [ -d "static/images/generated-covers" ] && [ "$(ls -A static/images/generated-covers 2>/dev/null)" ]; then
259+ echo "| Filename | Size | AI Service |" >> $GITHUB_STEP_SUMMARY
260+ echo "|----------|------|-----------|" >> $GITHUB_STEP_SUMMARY
261+ cd static/images/generated-covers
262+ ls -lh *.jpg *.png *.webp 2>/dev/null | while read -r line; do
263+ filename=$(echo $line | awk '{print $9}')
264+ size=$(echo $line | awk '{print $5}')
265+ echo "| $filename | $size | ModelScope |" >> $GITHUB_STEP_SUMMARY
110266 done
111267 else
112- echo "No images directory found" >> $GITHUB_STEP_SUMMARY
268+ echo "No AI covers generated" >> $GITHUB_STEP_SUMMARY
269+ fi
270+ echo "" >> $GITHUB_STEP_SUMMARY
271+
272+ # Add generation statistics
273+ article_count=$(find static/images/articles -name "*.jpg" -o -name "*.png" -o -name "*.webp" 2>/dev/null | wc -l)
274+ cover_count=$(find static/images/generated-covers -name "*.jpg" -o -name "*.png" -o -name "*.webp" 2>/dev/null | wc -l)
275+
276+ echo "### 📊 Statistics" >> $GITHUB_STEP_SUMMARY
277+ echo "**Article Images:** $article_count files" >> $GITHUB_STEP_SUMMARY
278+ echo "**AI Covers:** $cover_count files" >> $GITHUB_STEP_SUMMARY
279+ echo "**Total Images:** $((article_count + cover_count)) files" >> $GITHUB_STEP_SUMMARY
280+ echo "" >> $GITHUB_STEP_SUMMARY
281+
282+ echo "### ✅ Status" >> $GITHUB_STEP_SUMMARY
283+ if [ $((article_count + cover_count)) -gt 0 ]; then
284+ echo "🎉 **Generation Successful**: Images were generated and committed" >> $GITHUB_STEP_SUMMARY
285+ else
286+ echo "ℹ️ **No Generation**: No new images were generated" >> $GITHUB_STEP_SUMMARY
113287 fi
0 commit comments