Most wallpaper websites feel heavy because they serve full-resolution images as thumbnails or generate previews through backend processing. I wanted a lightweight, frontend-only solution, so I created a GitHub workflow that automatically generates optimized thumbnails and maps them to their actual source.
HERE is the piece of code which was implemented:
1
2
3
4
5
6
7
8
9
| name: Generate & Upload Thumbnails
on:
push:
paths:
- "Pictures/**.jpg"
- "Pictures/**.jpeg"
schedule:
- cron: "*/5 * * * *" # every 5 minutes
workflow_dispatch: # manual trigger
|
- The workflow triggers automatically whenever
.jpg or .jpeg images in the Pictures/ directory are added or modified. Other formats like .png are excluded for efficiency. - It also runs automatically every five minutes via a scheduled cron job, regardless of changes.
- Manual execution is supported through the
workflow_dispatch trigger.
1
2
3
4
5
| jobs:
generate-thumbs:
runs-on: ubuntu-latest
permissions:
contents: write
|
- It has the single job to generate-thumbs and runs on ubuntu environment
- Needs
contents: write so that we can push updates
1
2
3
4
5
6
| steps:
- name: Checkout repository [main branch for source ]
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: main
|
- Clones the main branch
- Fetch-depth ensures full git history so that we can access existing thumbnails
- ref ensures we working on main branch at first
1
2
3
4
5
6
7
8
9
10
11
| - name: Install ImageMagick
run:sudo apt-get update && sudo apt-get install -y imagemagick
- name:Check for images
id:check
run:|
if ls Pictures/*.jpg Pictures/*.jpeg 1> /dev/null 2>&1; then
echo "has_images=true" >> $GITHUB_OUTPUT
else
echo "has_images=false" >> $GITHUB_OUTPUT
echo "No images found to process"
fi
|
- Installing imagemagick package for image manipulation
- Lists everything jpeg/jpg files images inside Pictures directory and return the has_image accordingly, further we can reference later from that check name
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| - name: Generate thumbnails in main branch
if: steps.check.outputs.has_images == 'true'
run: |
mkdir -p /tmp/new_thumbs
git fetch origin thumbs:thumbs 2>/dev/null || echo "thumbs branch doesn't exist."
shopt -s nullglob
echo "=== Processing thumbnails ==="
for img in Pictures/*.jpg Pictures/*.jpeg; do
[ -f "$img" ] || continue
base=$(basename "$img")
if git show thumbs:thumbnails/"$base" > /dev/null 2>&1; then
echo "Skip: $base (thumbnail already exists)"
else
echo "Generate: $base"
convert "$img" -resize 320x200^ -gravity center -extent 320x200 "/tmp/new_thumbs/$base"
fi
done
echo ""
echo "=== New thumbnails generated ==="
ls -lh /tmp/new_thumbs/ 2>/dev/null || echo "No new thumbs"
|
- Generates thumbnails only if
has_images is true from the previous check - Creates a temporary folder to store newly generated thumbnails
- Fetchs the
thumbs branch to check for existing thumbnails - Loops through all images in the
Pictures/ folder and extract the basename (filename with extension) - Skips images that already have corresponding thumbnails in the branch
- Uses ImageMagick
convert to create 320X200 thumbnails, preserving the same filename and extension in the temporary folder so that mapping would be easier later in sites
1
2
3
4
5
6
7
8
9
10
| - name: Switch to thumbs branch and sync
if: steps.check.outputs.has_images == 'true'
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
shopt -s nullglob
mkdir -p /tmp/source_list
for img in Pictures/*.jpg Pictures/*.jpeg; do
[ -f "$img" ] && touch "/tmp/source_list/$(basename "$img")"
done
|
- Configures Git with a local username and email for commits
- Enables nullglob to safely handle empty file patterns in loops
- Creates a temporary folder to track source images
- Loops through all JPG and JPEG files in the Pictures folder and record their basenames in the temporary folder
1
2
3
4
5
6
7
8
9
10
11
12
| if git show-ref --verify --quiet refs/remotes/origin/thumbs; then
git checkout thumbs
else
git checkout --orphan thumbs
git rm -rf . 2>/dev/null || true
mkdir -p thumbnails
git commit --allow-empty -m "Initialize thumbs branch"
fi
mkdir -p thumbnails
if [ -d "/tmp/new_thumbs" ] && [ "$(ls -A /tmp/new_thumbs)" ]; then
cp /tmp/new_thumbs/* thumbnails/
fi
|
- Checks if the
thumbs branch exists on the remote- If it exists, switches to the
thumbs branch - If it does not exist, creates a new orphan
thumbs branch, remove all files, creates the thumbnails folder, and make an initial empty commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
echo ""
echo "=== Cleaning orphaned thumbnails ==="
for thumb in thumbnails/*.jpg thumbnails/*.jpeg; do
[ -f "$thumb" ] || continue
base=$(basename "$thumb")
# Check if source image exists in main branch
if [ ! -f "/tmp/source_list/$base" ]; then
echo "Delete:$base (source image missing)"
rm "$thumb"
fi
done
echo ""
echo "=== Current thumbnails ==="
ls -lh thumbnails/ || echo "No thumbnails"
git add thumbnails/
if git diff --staged --quiet; then
echo "No changes to commit"
else
git commit -m "Auto-sync thumbnails [skip ci]"
git push origin thumbs
echo "Thumbnails synced to thumbs branch"
fi
|
- Loops through all JPEG and JPG files in the
thumbnails folder- For each file, gets it basename
- If the corresponding source image does not exist in
/tmp/source_list, deletes the thumbnail
The creating of branch might work or not… Well fuck around’ n find out !!