Skip to content

Commit 8f28b2b

Browse files
committed
CI: Validate board images and vendor logos in pull requests
1 parent 1b78f82 commit 8f28b2b

2 files changed

Lines changed: 135 additions & 0 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Validate board images & vendor logos
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- "board-images/**"
7+
- "board-vendor-logos/**"
8+
9+
jobs:
10+
validate:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@v4
15+
with:
16+
fetch-depth: 0
17+
18+
- name: Install ImageMagick
19+
run: |
20+
sudo apt-get update
21+
sudo apt-get install -y imagemagick
22+
23+
- name: Validate images
24+
env:
25+
BASE_REF: "origin/${{ github.base_ref }}"
26+
HEAD_REF: "${{ github.sha }}"
27+
run: |
28+
scripts/validate-board-assets.sh

scripts/validate-board-assets.sh

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# Validate images in PRs:
5+
# - board-images/: must be 16:9 AND either 1920x1080 or 3840x2160
6+
# - board-vendor-logos/: must be square (WxH equal)
7+
#
8+
# Requires ImageMagick's `identify`.
9+
10+
BASE_REF="${BASE_REF:-origin/${GITHUB_BASE_REF:-main}}"
11+
HEAD_REF="${HEAD_REF:-HEAD}"
12+
13+
# Fetch base ref if needed (useful on CI with shallow clones)
14+
git fetch --no-tags --prune --depth=50 origin "+refs/heads/*:refs/remotes/origin/*" >/dev/null 2>&1 || true
15+
16+
mapfile -t CHANGED < <(git diff --name-only "${BASE_REF}...${HEAD_REF}" -- \
17+
'board-images/**' 'board-vendor-logos/**' || true)
18+
19+
if [[ ${#CHANGED[@]} -eq 0 ]]; then
20+
echo "No changes in board-images/ or board-vendor-logos/. ✅"
21+
exit 0
22+
fi
23+
24+
# Filter to image files we can validate
25+
VALID_EXT_RE='\.(png|jpg|jpeg|webp)$'
26+
FILES=()
27+
for f in "${CHANGED[@]}"; do
28+
[[ "$f" =~ $VALID_EXT_RE ]] || continue
29+
[[ -f "$f" ]] || continue
30+
FILES+=("$f")
31+
done
32+
33+
if [[ ${#FILES[@]} -eq 0 ]]; then
34+
echo "No supported image files changed (png/jpg/jpeg/webp). ✅"
35+
exit 0
36+
fi
37+
38+
if ! command -v identify >/dev/null 2>&1; then
39+
echo "ERROR: 'identify' not found. Install ImageMagick."
40+
exit 2
41+
fi
42+
43+
fail=0
44+
45+
check_board_image() {
46+
local file="$1"
47+
local w h
48+
read -r w h < <(identify -format '%w %h' "$file" 2>/dev/null || echo "0 0")
49+
50+
if [[ "$w" -le 0 || "$h" -le 0 ]]; then
51+
echo "$file: could not read dimensions"
52+
return 1
53+
fi
54+
55+
# Must be exact 16:9 -> w*9 == h*16
56+
if [[ $(( w * 9 )) -ne $(( h * 16 )) ]]; then
57+
echo "$file: must be 16:9 (got ${w}x${h})"
58+
return 1
59+
fi
60+
61+
if ! { [[ "$w" -eq 1920 && "$h" -eq 1080 ]] || [[ "$w" -eq 3840 && "$h" -eq 2160 ]]; }; then
62+
echo "$file: must be 1920x1080 or 3840x2160 (got ${w}x${h})"
63+
return 1
64+
fi
65+
66+
echo "$file: OK (${w}x${h})"
67+
return 0
68+
}
69+
70+
check_vendor_logo() {
71+
local file="$1"
72+
local w h
73+
read -r w h < <(identify -format '%w %h' "$file" 2>/dev/null || echo "0 0")
74+
75+
if [[ "$w" -le 0 || "$h" -le 0 ]]; then
76+
echo "$file: could not read dimensions"
77+
return 1
78+
fi
79+
80+
if [[ "$w" -ne "$h" ]]; then
81+
echo "$file: vendor logos must be square (got ${w}x${h})"
82+
return 1
83+
fi
84+
85+
echo "$file: OK (${w}x${h})"
86+
return 0
87+
}
88+
89+
echo "Validating ${#FILES[@]} image(s)..."
90+
for f in "${FILES[@]}"; do
91+
if [[ "$f" == board-images/* ]]; then
92+
check_board_image "$f" || fail=1
93+
elif [[ "$f" == board-vendor-logos/* ]]; then
94+
check_vendor_logo "$f" || fail=1
95+
else
96+
# Shouldn't happen because of the diff filter, but keep it safe.
97+
echo "Skipping unrelated file: $f"
98+
fi
99+
done
100+
101+
if [[ "$fail" -ne 0 ]]; then
102+
echo ""
103+
echo "Image validation failed. Please resize/crop the files to match the rules above."
104+
exit 1
105+
fi
106+
107+
echo "All image validations passed. ✅"

0 commit comments

Comments
 (0)