Skip to content

Commit 00719fb

Browse files
committed
ci(workflow): add automatic cover image generation for PRs
Add workflow that triggers on PRs modifying blog posts to automatically generate cover images for posts that don't have one. The generated image is committed back to the PR branch and a comment is posted showing the preview.
1 parent e8c13fc commit 00719fb

1 file changed

Lines changed: 124 additions & 0 deletions

File tree

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
name: Generate Cover Images
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize]
6+
paths:
7+
- 'src/content/blog/**/index.md'
8+
9+
permissions:
10+
contents: write
11+
pull-requests: write
12+
13+
jobs:
14+
generate-covers:
15+
name: Generate Missing Cover Images
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout PR branch
19+
uses: actions/checkout@v4
20+
with:
21+
ref: ${{ github.head_ref }}
22+
fetch-depth: 0
23+
token: ${{ secrets.GITHUB_TOKEN }}
24+
25+
- name: Setup Node.js
26+
uses: actions/setup-node@v4
27+
with:
28+
node-version: '20'
29+
30+
- name: Install dependencies
31+
run: npm ci
32+
33+
- name: Find blog posts needing covers
34+
id: find-posts
35+
run: |
36+
# Get list of changed files in this PR
37+
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
38+
39+
# Find blog post directories with changes but no cover.png
40+
POSTS_NEEDING_COVERS=""
41+
42+
for file in $CHANGED_FILES; do
43+
# Check if it's a blog post index.md
44+
if [[ "$file" =~ ^src/content/blog/[0-9]+/.+/index\.md$ ]]; then
45+
POST_DIR=$(dirname "$file")
46+
COVER_PATH="$POST_DIR/cover.png"
47+
48+
# Check if cover.png already exists
49+
if [ ! -f "$COVER_PATH" ]; then
50+
POSTS_NEEDING_COVERS="$POSTS_NEEDING_COVERS $POST_DIR"
51+
echo "Post needs cover: $POST_DIR"
52+
else
53+
echo "Post already has cover: $POST_DIR"
54+
fi
55+
fi
56+
done
57+
58+
# Trim leading space and output
59+
POSTS_NEEDING_COVERS=$(echo "$POSTS_NEEDING_COVERS" | xargs)
60+
echo "posts=$POSTS_NEEDING_COVERS" >> $GITHUB_OUTPUT
61+
62+
if [ -z "$POSTS_NEEDING_COVERS" ]; then
63+
echo "No posts need cover images"
64+
echo "has_posts=false" >> $GITHUB_OUTPUT
65+
else
66+
echo "has_posts=true" >> $GITHUB_OUTPUT
67+
fi
68+
69+
- name: Generate cover images
70+
if: steps.find-posts.outputs.has_posts == 'true'
71+
run: |
72+
for post_dir in ${{ steps.find-posts.outputs.posts }}; do
73+
echo "Generating cover for: $post_dir"
74+
node scripts/generate-cover.js "$post_dir"
75+
done
76+
77+
- name: Commit and push cover images
78+
if: steps.find-posts.outputs.has_posts == 'true'
79+
run: |
80+
git config user.name "github-actions[bot]"
81+
git config user.email "github-actions[bot]@users.noreply.github.com"
82+
83+
# Add only the generated cover images
84+
for post_dir in ${{ steps.find-posts.outputs.posts }}; do
85+
git add "$post_dir/cover.png"
86+
done
87+
88+
# Check if there are changes to commit
89+
if git diff --staged --quiet; then
90+
echo "No new cover images to commit"
91+
echo "committed=false" >> $GITHUB_OUTPUT
92+
else
93+
git commit -m "ci(blog): generate cover images for new posts [skip ci]"
94+
git push
95+
echo "committed=true" >> $GITHUB_OUTPUT
96+
fi
97+
98+
- name: Comment on PR with cover images
99+
if: steps.find-posts.outputs.has_posts == 'true'
100+
env:
101+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
102+
run: |
103+
# Get the commit SHA after push
104+
COMMIT_SHA=$(git rev-parse HEAD)
105+
106+
# Build comment body with all generated covers
107+
COMMENT="## 🖼️ Generated Cover Images\n\n"
108+
109+
for post_dir in ${{ steps.find-posts.outputs.posts }}; do
110+
# Extract post title from directory name
111+
POST_SLUG=$(basename "$post_dir")
112+
POST_YEAR=$(basename $(dirname "$post_dir"))
113+
114+
# Build raw GitHub URL for the image
115+
IMAGE_URL="https://raw.githubusercontent.com/${{ github.repository }}/${COMMIT_SHA}/${post_dir}/cover.png"
116+
117+
COMMENT="${COMMENT}### ${POST_YEAR}/${POST_SLUG}\n\n"
118+
COMMENT="${COMMENT}![Cover Image](${IMAGE_URL})\n\n"
119+
done
120+
121+
COMMENT="${COMMENT}---\n*If you'd like a different style, delete the cover image and push again, or generate one locally with \`npm run cover\`.*"
122+
123+
# Post comment to PR
124+
echo -e "$COMMENT" | gh pr comment ${{ github.event.pull_request.number }} --body-file -

0 commit comments

Comments
 (0)