Skip to content

Conversation

@igorpecovnik
Copy link
Member

@igorpecovnik igorpecovnik commented Dec 11, 2025

Purpose

Establish consistent image naming and automated image distribution for both boards and vendors.

Description

This change enforces consistent naming with a 1:1 relationship between:

  • board configuration names and board images (<board>.png)
  • BOARD_VENDOR names and vendor logos (<vendor>.png)

When a PNG image is added to board-images/ (boards) or board-vendor-logos/ (vendors) and matches the corresponding name, automation:

  • generates a standardized set of thumbnails at widths 100, 150, 272, 300, 360, 480, 768, 960, 1024, and 1920 pixels,
  • preserves aspect ratio and transparency,
  • optimizes images for web delivery,
  • uploads the results to Armbian cache mirrors.

Images are published under stable, predictable URL schemes, for example:

Board image (size 300):
https://cache.armbian.com/images/300/uefi-x86.png
UEFI x86 board image

Vendor logo (size 300):
https://cache.armbian.com/images/vendors/300/radxa.png
Radxa vendor logo

This guarantees consistent naming, automated thumbnail generation, and reliable image availability across mirrors.

- two images had whit background not transparent
- several images were not optimally compressed
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 11, 2025

Warning

Rate limit exceeded

@igorpecovnik has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 11 minutes and 28 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between d1f8e76 and 475c353.

⛔ Files ignored due to path filters (25)
  • board-images/9tripod-x3568-v4.png is excluded by !**/*.png
  • board-images/aml-a311d-cc.png is excluded by !**/*.png
  • board-images/aml-s905d3-cc.png is excluded by !**/*.png
  • board-images/aml-s9xx-box.png is excluded by !**/*.png
  • board-images/bananapim5.png is excluded by !**/*.png
  • board-images/cherryba-m1.png is excluded by !**/*.png
  • board-images/hinlink-h88k.png is excluded by !**/*.png
  • board-images/imb3588.png is excluded by !**/*.png
  • board-images/jethubj100.png is excluded by !**/*.png
  • board-images/jethubj80.png is excluded by !**/*.png
  • board-images/khadas-edge.png is excluded by !**/*.png
  • board-images/kickpik2b.png is excluded by !**/*.png
  • board-images/lime.png is excluded by !**/*.png
  • board-images/lubancat2.png is excluded by !**/*.png
  • board-images/mangopi-m28k.png is excluded by !**/*.png
  • board-images/mekotronics-r58x-pro.png is excluded by !**/*.png
  • board-images/nanopi-r1s-h5.png is excluded by !**/*.png
  • board-images/nanopi-r2s-plus.png is excluded by !**/*.png
  • board-images/onecloud.png is excluded by !**/*.png
  • board-images/qemu-uboot-arm64.png is excluded by !**/*.png
  • board-images/qemu-uboot-x86.png is excluded by !**/*.png
  • board-images/qemu-uefi-x86.png is excluded by !**/*.png
  • board-images/rk3328-heltec.png is excluded by !**/*.png
  • board-images/roc-rk3399-pc.png is excluded by !**/*.png
  • board-images/rock-5-cm-rpi-cm4-io.png is excluded by !**/*.png
📒 Files selected for processing (2)
  • .github/workflows/generate-thumbnails.yml (1 hunks)
  • README.md (1 hunks)

Walkthrough

Adds a new GitHub Actions workflow at .github/workflows/generate-thumbnails.yml named "Generate board images" triggered on push and workflow_dispatch. The workflow sets environment variables for board/vendor paths, thumbnail widths, shards, and output dirs; uses a board-images concurrency group; and adds Check, Boards-index, and Vendors-index jobs to validate permissions and build JSON matrices. A sharded Generate-images job depends on those indexes and performs repo checkout, SSH key setup, ImageMagick installation with fallback, scanning of board PNGs and vendor logos (including SVG rendering), thumbnail generation across widths (optional pngquant, non-fatal failures), per-item logging, per-shard summaries, and uploading images to cache servers discovered via NetBox. README.md is updated with a workflow badge and a short description.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Review .github/workflows/generate-thumbnails.yml (structure, triggers, env vars, concurrency).
  • Inspect shell logic that scans directories and config files, normalizes/deduplicates names, and emits JSON matrices.
  • Verify sharding/matrix distribution and per-shard processing loops.
  • Validate ImageMagick detection/fallback, thumbnail generation commands, error handling, and optional pngquant usage.
  • Audit NetBox server discovery, SSH key setup, server filtering, and rsync upload steps.
  • Review README.md badge and wording.

Files/areas needing extra attention:

  • .github/workflows/generate-thumbnails.yml
  • README.md
  • Inline shell scripts and commands within workflow steps

Possibly related PRs

Suggested labels

ready to merge

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Keep consistent board & vendor thumbnail generation' accurately summarizes the main objective of the PR, which is to establish automated, consistent thumbnail generation for both board images and vendor logos.
Description check ✅ Passed The description clearly explains the PR's purpose, detailing the 1:1 naming convention, the automation workflow for thumbnail generation at specified widths, and the publishing scheme to cache mirrors.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between bea24a2 and fc5eb1a.

⛔ Files ignored due to path filters (124)
  • board-images/avaota-a1.png is excluded by !**/*.png
  • board-images/ayn-odin2.png is excluded by !**/*.png
  • board-images/bananapi.png is excluded by !**/*.png
  • board-images/bananapif3.png is excluded by !**/*.png
  • board-images/bananapim2.png is excluded by !**/*.png
  • board-images/bananapim2plus.png is excluded by !**/*.png
  • board-images/bananapim2pro.png is excluded by !**/*.png
  • board-images/bananapim2s.png is excluded by !**/*.png
  • board-images/bananapim2zero.png is excluded by !**/*.png
  • board-images/bananapim3.png is excluded by !**/*.png
  • board-images/bananapim4zero.png is excluded by !**/*.png
  • board-images/bananapim64.png is excluded by !**/*.png
  • board-images/bananapim7.png is excluded by !**/*.png
  • board-images/bananapipro.png is excluded by !**/*.png
  • board-images/bananapir2.png is excluded by !**/*.png
  • board-images/beaglev.png is excluded by !**/*.png
  • board-images/beelinkx2.png is excluded by !**/*.png
  • board-images/clearfogbase.png is excluded by !**/*.png
  • board-images/clearfogpro.png is excluded by !**/*.png
  • board-images/cubieboard2.png is excluded by !**/*.png
  • board-images/cubietruck.png is excluded by !**/*.png
  • board-images/cubietruckplus.png is excluded by !**/*.png
  • board-images/cubox-i.png is excluded by !**/*.png
  • board-images/espressobin.png is excluded by !**/*.png
  • board-images/firefly-rk3399.png is excluded by !**/*.png
  • board-images/helios4.png is excluded by !**/*.png
  • board-images/helios64.png is excluded by !**/*.png
  • board-images/hikey960.png is excluded by !**/*.png
  • board-images/inovato-quadra.png is excluded by !**/*.png
  • board-images/jetson-nano.png is excluded by !**/*.png
  • board-images/khadas-edge2.png is excluded by !**/*.png
  • board-images/khadas-vim1.png is excluded by !**/*.png
  • board-images/khadas-vim2.png is excluded by !**/*.png
  • board-images/khadas-vim3.png is excluded by !**/*.png
  • board-images/khadas-vim3l.png is excluded by !**/*.png
  • board-images/khadas-vim4.png is excluded by !**/*.png
  • board-images/lafrite.png is excluded by !**/*.png
  • board-images/lepotato.png is excluded by !**/*.png
  • board-images/licheepi-4a.png is excluded by !**/*.png
  • board-images/lime-a10.png is excluded by !**/*.png
  • board-images/lime-a33.png is excluded by !**/*.png
  • board-images/lime-a64.png is excluded by !**/*.png
  • board-images/lime2.png is excluded by !**/*.png
  • board-images/mixtile-blade3.png is excluded by !**/*.png
  • board-images/mkspi.png is excluded by !**/*.png
  • board-images/nanopct4.png is excluded by !**/*.png
  • board-images/nanopi-m6.png is excluded by !**/*.png
  • board-images/nanopi-r1.png is excluded by !**/*.png
  • board-images/nanopi-r2s.png is excluded by !**/*.png
  • board-images/nanopia64.png is excluded by !**/*.png
  • board-images/nanopiduo.png is excluded by !**/*.png
  • board-images/nanopik1plus.png is excluded by !**/*.png
  • board-images/nanopim1.png is excluded by !**/*.png
  • board-images/nanopim1plus.png is excluded by !**/*.png
  • board-images/nanopim4.png is excluded by !**/*.png
  • board-images/nanopim4v2.png is excluded by !**/*.png
  • board-images/nanopineo.png is excluded by !**/*.png
  • board-images/nanopineo2.png is excluded by !**/*.png
  • board-images/nanopineo2black.png is excluded by !**/*.png
  • board-images/nanopineo3.png is excluded by !**/*.png
  • board-images/nanopineo4.png is excluded by !**/*.png
  • board-images/odroidc1.png is excluded by !**/*.png
  • board-images/odroidc2.png is excluded by !**/*.png
  • board-images/odroidc4.png is excluded by !**/*.png
  • board-images/odroidhc4.png is excluded by !**/*.png
  • board-images/odroidm1.png is excluded by !**/*.png
  • board-images/odroidn2.png is excluded by !**/*.png
  • board-images/odroidxu4.png is excluded by !**/*.png
  • board-images/oneplus-kebab.png is excluded by !**/*.png
  • board-images/orangepi-r1plus.png is excluded by !**/*.png
  • board-images/orangepi-rk3399.png is excluded by !**/*.png
  • board-images/orangepi.png is excluded by !**/*.png
  • board-images/orangepi2.png is excluded by !**/*.png
  • board-images/orangepi3-lts.png is excluded by !**/*.png
  • board-images/orangepi3.png is excluded by !**/*.png
  • board-images/orangepi3b.png is excluded by !**/*.png
  • board-images/orangepi4.png is excluded by !**/*.png
  • board-images/orangepi5-max.png is excluded by !**/*.png
  • board-images/orangepi5.png is excluded by !**/*.png
  • board-images/orangepi5pro.png is excluded by !**/*.png
  • board-images/orangepilite.png is excluded by !**/*.png
  • board-images/orangepilite2.png is excluded by !**/*.png
  • board-images/orangepimini.png is excluded by !**/*.png
  • board-images/orangepione.png is excluded by !**/*.png
  • board-images/orangepioneplus.png is excluded by !**/*.png
  • board-images/orangepipc.png is excluded by !**/*.png
  • board-images/orangepipc2.png is excluded by !**/*.png
  • board-images/orangepipcplus.png is excluded by !**/*.png
  • board-images/orangepiplus.png is excluded by !**/*.png
  • board-images/orangepiplus2e.png is excluded by !**/*.png
  • board-images/orangepiprime.png is excluded by !**/*.png
  • board-images/orangepiwin.png is excluded by !**/*.png
  • board-images/orangepizero.png is excluded by !**/*.png
  • board-images/orangepizero2.png is excluded by !**/*.png
  • board-images/orangepizero2w.png is excluded by !**/*.png
  • board-images/orangepizero3.png is excluded by !**/*.png
  • board-images/orangepizeroplus.png is excluded by !**/*.png
  • board-images/orangepizeroplus2-h3.png is excluded by !**/*.png
  • board-images/orangepizeroplus2-h5.png is excluded by !**/*.png
  • board-images/pcduino2.png is excluded by !**/*.png
  • board-images/pcduino3.png is excluded by !**/*.png
  • board-images/pcduino3nano.png is excluded by !**/*.png
  • board-images/pine64.png is excluded by !**/*.png
  • board-images/pinebook-a64.png is excluded by !**/*.png
  • board-images/pinecube.png is excluded by !**/*.png
  • board-images/quartz64a.png is excluded by !**/*.png
  • board-images/radxa-e25.png is excluded by !**/*.png
  • board-images/radxa-zero2.png is excluded by !**/*.png
  • board-images/renegade.png is excluded by !**/*.png
  • board-images/rock64.png is excluded by !**/*.png
  • board-images/rockpi-s.png is excluded by !**/*.png
  • board-images/rockpro64.png is excluded by !**/*.png
  • board-images/rpi4b.png is excluded by !**/*.png
  • board-images/sk-am64b.png is excluded by !**/*.png
  • board-images/star64.png is excluded by !**/*.png
  • board-images/station-m1.png is excluded by !**/*.png
  • board-images/station-p1.png is excluded by !**/*.png
  • board-images/station-p2.png is excluded by !**/*.png
  • board-images/sweet-potato.png is excluded by !**/*.png
  • board-images/udoo.png is excluded by !**/*.png
  • board-images/visionfive.png is excluded by !**/*.png
  • board-images/visionfive2.png is excluded by !**/*.png
  • board-images/youyeetoo-r1-v3.png is excluded by !**/*.png
  • board-images/z28pro.png is excluded by !**/*.png
📒 Files selected for processing (1)
  • .github/workflows/generate-thumbnails.yml (1 hunks)
🔇 Additional comments (4)
.github/workflows/generate-thumbnails.yml (4)

119-119: Clarify intent of --update=none flag in copy command.

Line 119 uses cp --update=none, which will not overwrite existing files. If the original image already exists in the output directory from a prior run, this command will silently skip it. Confirm whether this is intentional or if you meant to use --update=all (which would overwrite only if source is newer) or remove the flag entirely to always update.


143-182: Approve publish step logic.

The artifact download and git push workflow is clean and handles edge cases reasonably (e.g., no changes to commit, merge-multiple artifacts). The setup correctly fetches the data branch and configures git credentials.


44-63: Approve boards discovery logic.

The board matrix generation correctly discovers config files, strips extensions, sorts boards, and outputs valid JSON for the matrix strategy. The find command and jq pipeline are well-constructed.


81-85: ImageMagick on Ubuntu 24.04 supports required features; consider pinning version for reproducibility.

Ubuntu 24.04's default ImageMagick (6.9.12.98) includes full support for PNG compression level configuration (-define png:compression-level=N) and alpha channel operations (-alpha set, -transparent, etc.). However, using @latest without version pinning may result in unpredictable updates. For production workflows requiring consistent behavior, consider pinning the action to a specific version or ImageMagick release.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
.github/workflows/generate-thumbnails.yml (1)

147-147: ImageMagick convert command missing transparency and compression settings required by PR objectives.

The convert command lacks critical flags to address the stated PR objectives:

  1. White background issue: Without -background none before -extent, the operation fills the canvas with opaque white, causing the "white background instead of transparent" problem mentioned in the PR description.
  2. Compression optimization: No PNG compression level is specified, resulting in suboptimal file sizes (contradicts PR objective for "optimally compressed" images).

Additionally, -alpha set ensures the alpha channel is active for full transparency preservation.

Apply this diff to fix transparency preservation and enable PNG compression:

-              convert "${ORIGINAL}" -resize "${size}^" -gravity center -extent "${size}" "${OUT}"
+              convert "${ORIGINAL}" \
+                -alpha set \
+                -background none \
+                -resize "${size}^" \
+                -gravity center \
+                -extent "${size}" \
+                -define png:compression-level=9 \
+                "${OUT}"

The flag order matters: -alpha set and -background none must precede -extent to take effect.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between fc5eb1a and 62660a4.

📒 Files selected for processing (1)
  • .github/workflows/generate-thumbnails.yml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.9)
.github/workflows/generate-thumbnails.yml

180-180: input "if-no-artifact-found" is not defined in action "actions/download-artifact@v6". available inputs are "artifact-ids", "github-token", "merge-multiple", "name", "path", "pattern", "repository", "run-id"

(action)

@igorpecovnik igorpecovnik force-pushed the device_images branch 2 times, most recently from 41e1b43 to 42a525e Compare December 12, 2025 05:45
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
.github/workflows/generate-thumbnails.yml (1)

159-164: Preserve transparency + apply PNG compression in thumbnail generation (still missing).
The convert ... -extent call will fill extended canvas with the current background (commonly white) unless you explicitly set a transparent background; also no PNG compression settings are applied.

-              convert "${ORIGINAL}" -resize "${size}^" -gravity center -extent "${size}" "${OUT}"
+              convert "${ORIGINAL}" \
+                -alpha set \
+                -background none \
+                -resize "${size}^" \
+                -gravity center \
+                -extent "${size}" \
+                -define png:compression-level=9 \
+                "${OUT}"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 41e1b43 and 42a525e.

📒 Files selected for processing (1)
  • .github/workflows/generate-thumbnails.yml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Generate board images (2)
🔇 Additional comments (1)
.github/workflows/generate-thumbnails.yml (1)

190-196: Good: removed invalid download-artifact@v6 input.
This step now only uses supported inputs.

@igorpecovnik igorpecovnik force-pushed the device_images branch 3 times, most recently from 79ae768 to 03d02c2 Compare December 12, 2025 06:16
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
.github/workflows/generate-thumbnails.yml (2)

219-220: Use robust git branch checkout that handles missing local branches.

The current git checkout data command will fail if the local data branch doesn't exist. Use git checkout -B to ensure the local branch is created or reset to track origin/data reliably.

Apply this diff:

           git fetch origin data
-          git checkout data
+          git checkout -B data origin/data

163-163: Add transparency preservation and PNG compression to ImageMagick command to address PR objectives.

The PR objectives explicitly state: "Two images had white background instead of being transparent" and "Several images were not optimally compressed." However, the convert command lacks the necessary flags to address both issues.

Without -background none before -extent, the default white background is used, converting any transparent pixels to white. Additionally, no PNG compression level is specified, leaving files larger than necessary.

Apply this diff to fix the transparency and compression issues:

-            convert "${ORIGINAL}" -resize "${size}^" -gravity center -extent "${size}" "${OUT}"
+            convert "${ORIGINAL}" \
+              -alpha set \
+              -background none \
+              -resize "${size}^" \
+              -gravity center \
+              -extent "${size}" \
+              -define png:compression-level=9 \
+              "${OUT}"
  • -alpha set: Ensures the alpha channel is present and active.
  • -background none: Sets transparent background (must precede -extent).
  • -define png:compression-level=9: Applies maximum PNG compression.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 97cc358 and 03d02c2.

📒 Files selected for processing (1)
  • .github/workflows/generate-thumbnails.yml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Publish board images to data branch

@igorpecovnik igorpecovnik force-pushed the device_images branch 2 times, most recently from 05c9741 to e7c4cea Compare December 12, 2025 07:00
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (4)
.github/workflows/generate-thumbnails.yml (4)

198-212: Fix board-images-thumb vs board-images directory mismatch (publish gate will always skip).
You download artifacts into board-images-thumb (Line 201) but the “Skip publish if no images” step checks board-images (Line 209), so it can incorrectly exit 0 even when images exist.

       - name: "Skip publish if no images"
         run: |
-
           set -euo pipefail
-          if [ ! -d board-images ] || ! find board-images -type f -name '*.png' -print -quit | grep -q .; then
-            echo "No images found in board-images, nothing to publish."
+          if [ ! -d board-images-thumb ] || ! find board-images-thumb -type f -name '*.png' -print -quit | grep -q .; then
+            echo "No images found in board-images-thumb, nothing to publish."
             exit 0
           fi

227-229: Make data branch checkout robust (don’t assume local branch exists).
git checkout data can fail on a fresh runner if the local branch doesn’t exist.

           git fetch origin data
-          git checkout data
+          git checkout -B data origin/data

167-172: Preserve transparency + apply PNG compression when using -extent.
Current convert ... -extent can introduce a white background unless you set a transparent background first; also no PNG compression tuning is applied.

-              convert "${ORIGINAL}" -resize "${size}^" -gravity center -extent "${size}" "${OUT}"
+              convert "${ORIGINAL}" \
+                -alpha set \
+                -background none \
+                -resize "${size}^" \
+                -gravity center \
+                -extent "${size}" \
+                -define png:compression-level=9 \
+                "${OUT}"
ImageMagick: does `-background none` need to appear before `-extent` to preserve transparency, and is `-define png:compression-level=9` the recommended knob for PNG compression in current ImageMagick (v6/v7)?

95-113: Install tree if you require it later, or make it non-fatal.
You call tree later (Line 235) but only install imagemagick here. On ubuntu runners tree is not guaranteed.

             sudo apt-get update -y
-            sudo apt-get install -y imagemagick
+            sudo apt-get install -y imagemagick tree

(Alternative: keep tree as best-effort: command -v tree >/dev/null && tree ... || ls -R ....)

🧹 Nitpick comments (1)
.github/workflows/generate-thumbnails.yml (1)

142-144: Avoid accidentally re-discovering generated outputs during find (future-proofing).
If this workflow later runs in a workspace that already contains output/images, find . could pick up generated thumbnails as “originals”. Consider excluding ./output/ (and possibly ./.git/) from the search.

-            mapfile -t matches < <(find . -type f -iname "${BOARD}.png" | sort || true)
+            mapfile -t matches < <(find . -type f -iname "${BOARD}.png" \
+              -not -path "./output/*" -not -path "./.git/*" | sort || true)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 03d02c2 and 05c9741.

📒 Files selected for processing (1)
  • .github/workflows/generate-thumbnails.yml (1 hunks)

Comment on lines +21 to +31
Check:
name: "Check permissions"
runs-on: ubuntu-24.04
steps:
- name: "Check permissions"
uses: armbian/actions/team-check@main
with:
ORG_MEMBERS: ${{ secrets.ORG_MEMBERS }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TEAM: "Release manager"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

armbian/actions/team-check GitHub Action versions releases tags

💡 Result:

I can look that up — do you mean the GitHub repo armbian/actions (an action named team-check) or a repo named armbian/team-check? Please confirm the exact repo URL or owner/repo so I can fetch its releases/tags.


🏁 Script executed:

# Search for any references to armbian/actions in the repository to understand context
rg "armbian/actions" --type yaml -A 2 -B 2

Repository: armbian/armbian.github.io

Length of output: 217


🏁 Script executed:

# Search more broadly for armbian references
rg "armbian" -type yml -A 2 -B 2

# Also check if there's any documentation about dependencies or actions used
find . -name "*.md" -o -name "*.txt" | head -20

Repository: armbian/armbian.github.io

Length of output: 161


🏁 Script executed:

# Get a general file listing to understand repo structure
git ls-files | head -30

Repository: armbian/armbian.github.io

Length of output: 1151


🏁 Script executed:

cat -n .github/workflows/generate-thumbnails.yml

Repository: armbian/armbian.github.io

Length of output: 9527


🏁 Script executed:

# Check if there's any documentation about armbian/actions or action pinning
rg "armbian/actions" .

Repository: armbian/armbian.github.io

Length of output: 51


🌐 Web query:

site:github.com armbian/actions team-check releases versions tags

💡 Result:

Found the armbian/actions GitHub repo — it includes a team-check action (path: /team-check) and has tags/releases v1.0 and v1.1. [1][2][3]

Sources

  • armbian/actions repository (shows team-check folder). [1]
  • Tags page (tags 1.0 — 2023-05-03, 1.1 — 2024-09-26). [2]
  • Releases page (1.0 and 1.1 listed). [3]

🏁 Script executed:

# Check if there are any other workflows that might show how armbian/actions is used elsewhere
rg "armbian/actions" --type yaml

Repository: armbian/armbian.github.io

Length of output: 217


Pin armbian/actions/team-check to a specific release version for supply-chain safety.

armbian/actions/team-check@main is a moving target. The action publishes releases (v1.0, v1.1); pin to v1.1 or a specific commit SHA instead of @main.

🤖 Prompt for AI Agents
.github/workflows/generate-thumbnails.yml lines 21-31: the workflow uses
armbian/actions/team-check@main which is a moving target; pin this to a fixed
release (e.g., armbian/actions/[email protected]) or to a specific commit SHA to
ensure supply-chain stability; update the uses line to reference the chosen tag
or SHA and commit the change.

@igorpecovnik igorpecovnik force-pushed the device_images branch 3 times, most recently from 542ae2d to 9577786 Compare December 12, 2025 07:10
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
.github/workflows/generate-thumbnails.yml (2)

187-193: Harden the NetBox jq filter to safely handle missing or null tags.

The current filter on lines 191-192 errors when .tags is null or missing. Use optional object iteration with fallback to safely handle VMs without tags.

           curl -sS \
             -H "Authorization: Token ${{ secrets.NETBOX_TOKEN }}" \
             -H "Accept: application/json; indent=4" \
             "${{ secrets.NETBOX_API }}/virtualization/virtual-machines/?limit=500&name__empty=false&status=active" \
-          | jq '.results[] 
-                 | select([.tags[].name] | index("cache")) 
-                 | {id, name, custom_fields}' > servers.json
+          | jq '.results[]
+                 | select((.tags // []) | any(.name == "cache"))
+                 | {id, name, custom_fields}' > servers.json

The current filter throws Cannot iterate over null when a VM has no tags. The fix uses (.tags // []) to provide an empty array fallback and any() for safe filtering.


165-170: Add transparency and PNG compression flags to ImageMagick command.

The current convert command on line 169 has two issues:

  1. -extent fills added canvas with white by default (the background color must be explicitly set to none for transparency)
  2. No PNG compression level specified, resulting in larger file sizes
             for size in ${SIZES}; do
               mkdir -p "output/images/${size}"
               OUT="output/images/${size}/${BOARD}.png"
               echo "Generating ${OUT}"
-              convert "${ORIGINAL}" -resize "${size}^" -gravity center -extent "${size}" "${OUT}"
+              convert "${ORIGINAL}" \
+                -alpha set \
+                -background none \
+                -resize "${size}^" \
+                -gravity center \
+                -extent "${size}" \
+                -define png:compression-level=9 \
+                "${OUT}"
             done
  • -alpha set: Ensures the alpha channel is present and active for transparency handling
  • -background none: Sets transparent background for canvas operations (must precede -extent)
  • -define png:compression-level=9: Applies maximum PNG compression
🧹 Nitpick comments (1)
.github/workflows/generate-thumbnails.yml (1)

115-180: Verify shard-based processing handles board indexing correctly.

The sharding logic at lines 133-136 uses modulo on a sequential index (idx % SHARDS == SHARD). Confirm that:

  1. The board ordering from all-boards.txt is stable across runs (jq produces deterministic output)
  2. No boards are skipped or double-processed due to concurrent shard execution
  3. The incremental counter correctly maps all boards to exactly one shard

Test the sharding logic with a sample board list to ensure even distribution and no gaps.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 05c9741 and 9577786.

📒 Files selected for processing (1)
  • .github/workflows/generate-thumbnails.yml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Generate board images (2)
  • GitHub Check: Generate board images (3)
  • GitHub Check: Generate board images (1)
  • GitHub Check: Generate board images (0)
🔇 Additional comments (1)
.github/workflows/generate-thumbnails.yml (1)

21-31: Pin armbian/actions/team-check to a specific release version.

The action is pinned to @main, which is a moving target. Use a fixed release tag (v1.1) or commit SHA for supply-chain stability.

       - name: "Check permissions"
-        uses: armbian/actions/team-check@main
+        uses: armbian/actions/[email protected]
         with:
           ORG_MEMBERS: ${{ secrets.ORG_MEMBERS }}
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           TEAM: "Release manager"

@igorpecovnik igorpecovnik force-pushed the device_images branch 5 times, most recently from be62966 to 60adddc Compare December 12, 2025 07:46
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
.github/workflows/generate-thumbnails.yml (3)

21-31: Pin armbian/actions/team-check (avoid @main).

armbian/actions/team-check@main is a moving target; pin to a release tag or SHA.

-        uses: armbian/actions/team-check@main
+        uses: armbian/actions/[email protected]

170-185: Make thumbnail generation preserve alpha + use real PNG compression; don’t fail hard on pngquant.

  • -quality 90 isn’t a dependable PNG compression control.
  • pngquant can fail for some PNGs; with set -e this aborts the job.
                 convert "${ORIGINAL}" \
                     -resize "${width}>" \
+                    -alpha set \
                     -strip \
-                    -quality 90 \
+                    -define png:compression-level=9 \
                     "${OUT}"
 
                 # Optional but recommended, if you installed pngquant:
-                pngquant --quality=65-85 --speed 1 --force --output "${OUT}" "${OUT}"
+                pngquant --quality=65-85 --speed 1 --force --output "${OUT}" "${OUT}" "${OUT}" || true

201-209: Harden NetBox jq filter for missing/null .tags.

Current .tags[].name can throw when tags is null/missing.

-          | jq '.results[] 
-                 | select([.tags[].name] | index("cache")) 
-                 | {id, name, custom_fields}' > servers.json
+          | jq '.results[]
+                 | select((.tags // []) | any(.name == "cache"))
+                 | {id, name, custom_fields}' > servers.json
🧹 Nitpick comments (2)
.github/workflows/generate-thumbnails.yml (2)

94-111: Prefer pinning 3rd-party actions by SHA (supply-chain hardening).

Consider pinning shimataro/ssh-key-action@v2 and even actions/checkout@v4 to commit SHAs to reduce risk from tag retargeting.


140-163: Avoid accidentally picking generated outputs as “originals” (exclude output/).

If the repo ever contains output/images/** (or if this step is refactored to reuse a workspace), find . can pick derived images. Safer to exclude.

-            mapfile -t matches < <(find . -type f -iname "${BOARD}.png" | sort || true)
+            mapfile -t matches < <(find . -type f -iname "${BOARD}.png" -not -path './output/*' | sort || true)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9577786 and 60adddc.

📒 Files selected for processing (1)
  • .github/workflows/generate-thumbnails.yml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Generate board images (1)
  • GitHub Check: Generate board images (3)
  • GitHub Check: Generate board images (0)

@igorpecovnik igorpecovnik force-pushed the device_images branch 5 times, most recently from 14dff50 to 382217b Compare December 12, 2025 09:00
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
.github/workflows/generate-thumbnails.yml (3)

141-141: Exclude generated output/ directory from find to prevent self-matching on reruns.

The find command can match previously-generated thumbnails under output/images/ on subsequent runs, treating them as the original source image. Add a path exclusion:

-            mapfile -t matches < <(find . -type f -iname "${BOARD}.png" | sort || true)
+            mapfile -t matches < <(find . -type f -iname "${BOARD}.png" -not -path "./output/*" | sort || true)

220-244: Critical: NetBox jq filter is null-unsafe, uses broken index logic, and produces non-array JSON; upload loop will fail to parse.

The filter has three fatal issues:

  1. Null-safety: .tags[] errors if .tags is null or missing.
  2. Broken index logic: [.tags[].name] | index("cache") returns position (0, 1, 2...) or null. When "cache" is at position 0, index() returns 0 (falsy), and select() incorrectly rejects it.
  3. Non-array output: The filter produces a stream of objects, but line 229 consumes it as a JSON array with jq -r '@base64', causing a parse error.

Fix the jq filter to produce a valid JSON array and use safe tag matching:

           curl -sS \
             -H "Authorization: Token ${{ secrets.NETBOX_TOKEN }}" \
             -H "Accept: application/json; indent=4" \
             "${{ secrets.NETBOX_API }}/virtualization/virtual-machines/?limit=500&name__empty=false&status=active" \
-          | jq '.results[] 
-                 | select([.tags[].name] | index("cache")) 
-                 | {id, name, custom_fields}' > servers.json
+          | jq '[
+                  .results[]
+                  | select((.tags // []) | any(.name == "cache"))
+                  | {id, name, custom_fields}
+                ]' > servers.json

           if [[ ! -s servers.json ]]; then
             echo "No cache servers returned from NetBox query, nothing to upload."
             exit 0
           fi

-          for row in $(jq -r '@base64' servers.json); do
+          for row in $(jq -r '.[] | @base64' servers.json); do

Explanation:

  • [...] wraps the filter output into a JSON array.
  • (.tags // []) defaults null/missing tags to an empty array.
  • any(.name == "cache") returns true if any tag matches; correctly handles position-0 matches.
  • jq -r '.[] | @base64' iterates over the array and base64-encodes each element.

174-178: Critical: ImageMagick command missing transparency and PNG compression flags required by PR objectives.

The current command lacks three essential flags that directly address PR goals:

  1. Transparency preservation: -alpha set -background none (before -extent if used) prevents white fill of padding.
  2. PNG compression: -quality 90 targets JPEG; PNG requires -define png:compression-level=9.

Without these, thumbnails will have white backgrounds instead of transparency and will not be optimally compressed.

                 if ! convert "${ORIGINAL}" \
+                        -alpha set \
+                        -background none \
                         -resize "${width}>" \
                         -strip \
+                        -define png:compression-level=9 \
                         -quality 90 \
                         "${OUT}"; then
🧹 Nitpick comments (3)
README.md (1)

44-44: Quote the href URL to comply with HTML/Markdown standards.

The href attribute value should be quoted. This also resolves the markdownlint MD034 warning.

-<a href=https://github.com/armbian/armbian.github.io/actions/workflows/generate-board-images.yml><img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/armbian/armbian.github.io/generate-board-images.yml?logo=githubactions&label=Status&style=for-the-badge&branch=main&logoColor=white"></a>
+<a href="https://github.com/armbian/armbian.github.io/actions/workflows/generate-board-images.yml"><img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/armbian/armbian.github.io/generate-board-images.yml?logo=githubactions&label=Status&style=for-the-badge&branch=main&logoColor=white"></a>
.github/workflows/generate-thumbnails.yml (2)

26-26: Pin armbian/actions/team-check to a specific release version for supply-chain safety.

Using @main is a moving target. Per the past review, the action publishes releases (v1.0, v1.1). Pin to a stable version instead.

-        uses: armbian/actions/team-check@main
+        uses: armbian/actions/[email protected]

200-209: Initialize summary files at the start of the job to avoid conditional overhead.

The code conditionally checks for file existence (line 207) to avoid cat errors under set -euo pipefail. While the conditional works, explicit initialization is clearer and avoids edge cases:

           echo "Shard: ${SHARD}/${SHARDS}"
           echo "Widths: ${WIDTHS}"

+          touch processed.md missing.md
+
           # Parse boards JSON into a simple newline list
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 62c1352 and a5479f9.

⛔ Files ignored due to path filters (174)
  • board-images/aml-c400-plus.png is excluded by !**/*.png
  • board-images/aml-s805-mxq.png is excluded by !**/*.png
  • board-images/aml-t95z-plus.png is excluded by !**/*.png
  • board-images/armsom-aim7-io.png is excluded by !**/*.png
  • board-images/armsom-cm5-io.png is excluded by !**/*.png
  • board-images/armsom-cm5-rpi-cm4-io.png is excluded by !**/*.png
  • board-images/armsom-forge1.png is excluded by !**/*.png
  • board-images/armsom-sige1.png is excluded by !**/*.png
  • board-images/armsom-sige3.png is excluded by !**/*.png
  • board-images/armsom-sige5.png is excluded by !**/*.png
  • board-images/armsom-sige7.png is excluded by !**/*.png
  • board-images/armsom-w3.png is excluded by !**/*.png
  • board-images/bananapicm4io.png is excluded by !**/*.png
  • board-images/bananapim1plus.png is excluded by !**/*.png
  • board-images/bananapim2ultra.png is excluded by !**/*.png
  • board-images/bananapim4berry.png is excluded by !**/*.png
  • board-images/bananapim5pro.png is excluded by !**/*.png
  • board-images/bananapir2pro.png is excluded by !**/*.png
  • board-images/bananapir4.png is excluded by !**/*.png
  • board-images/beaglebone-ai64.png is excluded by !**/*.png
  • board-images/beagleplay.png is excluded by !**/*.png
  • board-images/beagley-ai.png is excluded by !**/*.png
  • board-images/bigtreetech-cb1.png is excluded by !**/*.png
  • board-images/bigtreetech-cb2.png is excluded by !**/*.png
  • board-images/clockworkpi-a06.png is excluded by !**/*.png
  • board-images/cm3588-nas.png is excluded by !**/*.png
  • board-images/coolpi-cm5.png is excluded by !**/*.png
  • board-images/coolpi-genbook.png is excluded by !**/*.png
  • board-images/cubieboard.png is excluded by !**/*.png
  • board-images/cyber-aib-rk3588.png is excluded by !**/*.png
  • board-images/dshanpi-a1.png is excluded by !**/*.png
  • board-images/dshanpi-r1.png is excluded by !**/*.png
  • board-images/dusun-dsom-010r.png is excluded by !**/*.png
  • board-images/firefly-itx-3588j.png is excluded by !**/*.png
  • board-images/fxblox-rk1.png is excluded by !**/*.png
  • board-images/h96-tvbox-3566.png is excluded by !**/*.png
  • board-images/hinlink-h28k.png is excluded by !**/*.png
  • board-images/hinlink-h66k.png is excluded by !**/*.png
  • board-images/hinlink-h68k.png is excluded by !**/*.png
  • board-images/hinlink-ht2.png is excluded by !**/*.png
  • board-images/indiedroid-nova.png is excluded by !**/*.png
  • board-images/jp-tvbox-3566.png is excluded by !**/*.png
  • board-images/khadas-vim1s.png is excluded by !**/*.png
  • board-images/lckfb-taishanpi.png is excluded by !**/*.png
  • board-images/leez-p710.png is excluded by !**/*.png
  • board-images/longanpi-3h.png is excluded by !**/*.png
  • board-images/luckfox-core3566.png is excluded by !**/*.png
  • board-images/luckfox-lyra-plus.png is excluded by !**/*.png
  • board-images/luckfox-lyra-ultra-w.png is excluded by !**/*.png
  • board-images/luckfox-lyra-zero-w.png is excluded by !**/*.png
  • board-images/luckfox-pico-max.png is excluded by !**/*.png
  • board-images/luckfox-pico-mini.png is excluded by !**/*.png
  • board-images/mba8mpxl-ras314.png is excluded by !**/*.png
  • board-images/mba8mpxl.png is excluded by !**/*.png
  • board-images/mekotronics-r58-4x4.png is excluded by !**/*.png
  • board-images/mekotronics-r58-minipc.png is excluded by !**/*.png
  • board-images/mekotronics-r58hd.png is excluded by !**/*.png
  • board-images/mekotronics-r58x-4g.png is excluded by !**/*.png
  • board-images/mekotronics-r58x.png is excluded by !**/*.png
  • board-images/melea1000.png is excluded by !**/*.png
  • board-images/mixtile-edge2.png is excluded by !**/*.png
  • board-images/mk808c.png is excluded by !**/*.png
  • board-images/mksklipad50.png is excluded by !**/*.png
  • board-images/musepipro.png is excluded by !**/*.png
  • board-images/nanopct6-lts.png is excluded by !**/*.png
  • board-images/nanopct6.png is excluded by !**/*.png
  • board-images/nanopi-m5.png is excluded by !**/*.png
  • board-images/nanopi-r2c.png is excluded by !**/*.png
  • board-images/nanopi-r3s-lts.png is excluded by !**/*.png
  • board-images/nanopi-r3s.png is excluded by !**/*.png
  • board-images/nanopi-r4s.png is excluded by !**/*.png
  • board-images/nanopi-r4se.png is excluded by !**/*.png
  • board-images/nanopi-r5c.png is excluded by !**/*.png
  • board-images/nanopi-r5s.png is excluded by !**/*.png
  • board-images/nanopi-r6c.png is excluded by !**/*.png
  • board-images/nanopi-r6s.png is excluded by !**/*.png
  • board-images/nanopi-r76s.png is excluded by !**/*.png
  • board-images/nanopiair.png is excluded by !**/*.png
  • board-images/nanopiduo2.png is excluded by !**/*.png
  • board-images/nanopik2-s905.png is excluded by !**/*.png
  • board-images/nanopineocore2.png is excluded by !**/*.png
  • board-images/nanopineoplus2.png is excluded by !**/*.png
  • board-images/odroidm1s.png is excluded by !**/*.png
  • board-images/odroidm2.png is excluded by !**/*.png
  • board-images/odroidn2l.png is excluded by !**/*.png
  • board-images/olimex-a20-olinuxino-micro.png is excluded by !**/*.png
  • board-images/olimex-teres-a64.png is excluded by !**/*.png
  • board-images/olinux-som-a13.png is excluded by !**/*.png
  • board-images/orangepi-r1.png is excluded by !**/*.png
  • board-images/orangepi-r1plus-lts.png is excluded by !**/*.png
  • board-images/orangepi4-lts.png is excluded by !**/*.png
  • board-images/orangepi5-plus.png is excluded by !**/*.png
  • board-images/orangepi5-ultra.png is excluded by !**/*.png
  • board-images/orangepi5b.png is excluded by !**/*.png
  • board-images/panther-x2.png is excluded by !**/*.png
  • board-images/phytiumpi.png is excluded by !**/*.png
  • board-images/pine64so.png is excluded by !**/*.png
  • board-images/pinebook-pro.png is excluded by !**/*.png
  • board-images/pineh64-b.png is excluded by !**/*.png
  • board-images/pineh64.png is excluded by !**/*.png
  • board-images/pocketbeagle2.png is excluded by !**/*.png
  • board-images/pocketchip-sd.png is excluded by !**/*.png
  • board-images/quartz64b.png is excluded by !**/*.png
  • board-images/radxa-cm4-io.png is excluded by !**/*.png
  • board-images/radxa-cm5-io.png is excluded by !**/*.png
  • board-images/radxa-cubie-a5e.png is excluded by !**/*.png
  • board-images/radxa-dragon-q6a.png is excluded by !**/*.png
  • board-images/radxa-e20c.png is excluded by !**/*.png
  • board-images/radxa-e24c.png is excluded by !**/*.png
  • board-images/radxa-e52c.png is excluded by !**/*.png
  • board-images/radxa-e54c.png is excluded by !**/*.png
  • board-images/radxa-nio-12l.png is excluded by !**/*.png
  • board-images/radxa-rock-4d.png is excluded by !**/*.png
  • board-images/radxa-zero.png is excluded by !**/*.png
  • board-images/radxa-zero3.png is excluded by !**/*.png
  • board-images/recore.png is excluded by !**/*.png
  • board-images/retro-lite-cm5.png is excluded by !**/*.png
  • board-images/retroidpocket-rp5.png is excluded by !**/*.png
  • board-images/retroidpocket-rpmini.png is excluded by !**/*.png
  • board-images/rk322x-box.png is excluded by !**/*.png
  • board-images/rk3318-box.png is excluded by !**/*.png
  • board-images/rock-2a.png is excluded by !**/*.png
  • board-images/rock-2f.png is excluded by !**/*.png
  • board-images/rock-3a.png is excluded by !**/*.png
  • board-images/rock-3c.png is excluded by !**/*.png
  • board-images/rock-4se.png is excluded by !**/*.png
  • board-images/rock-5-cmio.png is excluded by !**/*.png
  • board-images/rock-5-itx.png is excluded by !**/*.png
  • board-images/rock-5a.png is excluded by !**/*.png
  • board-images/rock-5b-plus.png is excluded by !**/*.png
  • board-images/rock-5b.png is excluded by !**/*.png
  • board-images/rock-5c.png is excluded by !**/*.png
  • board-images/rock-5t.png is excluded by !**/*.png
  • board-images/rock-s0.png is excluded by !**/*.png
  • board-images/rockpi-4a.png is excluded by !**/*.png
  • board-images/rockpi-4b.png is excluded by !**/*.png
  • board-images/rockpi-4bplus.png is excluded by !**/*.png
  • board-images/rockpi-4c.png is excluded by !**/*.png
  • board-images/rockpi-4cplus.png is excluded by !**/*.png
  • board-images/rockpi-e.png is excluded by !**/*.png
  • board-images/rockpi-n10.png is excluded by !**/*.png
  • board-images/sakurapi-rk3308b.png is excluded by !**/*.png
  • board-images/sk-am62a.png is excluded by !**/*.png
  • board-images/sk-am62b.png is excluded by !**/*.png
  • board-images/sk-am62p.png is excluded by !**/*.png
  • board-images/sk-am68.png is excluded by !**/*.png
  • board-images/sk-am69.png is excluded by !**/*.png
  • board-images/sk-tda4vm.png is excluded by !**/*.png
  • board-images/smart-am40.png is excluded by !**/*.png
  • board-images/station-m2.png is excluded by !**/*.png
  • board-images/station-m3.png is excluded by !**/*.png
  • board-images/sunvell-r69.png is excluded by !**/*.png
  • board-images/tanix-tx6.png is excluded by !**/*.png
  • board-images/thinkpad-x13s.png is excluded by !**/*.png
  • board-images/tinker-edge-r.png is excluded by !**/*.png
  • board-images/tinkerboard-2.png is excluded by !**/*.png
  • board-images/tinkerboard.png is excluded by !**/*.png
  • board-images/tmds62levm.png is excluded by !**/*.png
  • board-images/tritium-h3.png is excluded by !**/*.png
  • board-images/tritium-h5.png is excluded by !**/*.png
  • board-images/uefi-arm64.png is excluded by !**/*.png
  • board-images/uefi-riscv64.png is excluded by !**/*.png
  • board-images/uefi-x86.png is excluded by !**/*.png
  • board-images/x96-mate.png is excluded by !**/*.png
  • board-images/x96q.png is excluded by !**/*.png
  • board-images/xt-q8l-v10.png is excluded by !**/*.png
  • board-images/youyeetoo-yy3588.png is excluded by !**/*.png
  • board-images/zeropi.png is excluded by !**/*.png
  • board-vendor-logos/allwinner-logo.png is excluded by !**/*.png
  • board-vendor-logos/amlogic-logo.png is excluded by !**/*.png
  • board-vendor-logos/asus-logo.png is excluded by !**/*.png
  • board-vendor-logos/beagleboard-logo.png is excluded by !**/*.png
  • board-vendor-logos/beelink-logo.png is excluded by !**/*.png
  • board-vendor-logos/cool-pi-logo.png is excluded by !**/*.png
📒 Files selected for processing (2)
  • .github/workflows/generate-thumbnails.yml (1 hunks)
  • README.md (1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
README.md

44-44: Bare URL used

(MD034, no-bare-urls)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Generate board images (3)
  • GitHub Check: Generate board images (2)
  • GitHub Check: Generate board images (0)
  • GitHub Check: Generate board images (1)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (2)
.github/workflows/generate-thumbnails.yml (2)

309-311: Fix NetBox jq filter: handle null tags and correct tag matching logic.

The jq filter has two critical issues:

  1. Null-safety: .tags[] will error if .tags is null or missing on any VM.
  2. Faulty index logic: [.tags[].name] | index("cache") returns position (0, 1, 2...) or null. When "cache" is at position 0, index() returns 0 (falsy), and select() incorrectly rejects it.
           curl -sS \
             -H "Authorization: Token ${{ secrets.NETBOX_TOKEN }}" \
             -H "Accept: application/json; indent=4" \
             "${{ secrets.NETBOX_API }}/virtualization/virtual-machines/?limit=500&name__empty=false&status=active" \
-          | jq '.results[]
-                 | select([.tags[].name] | index("cache"))
-                 | {id, name, custom_fields}' > servers.json
+          | jq '.results[]
+                 | select((.tags // []) | any(.name == "cache"))
+                 | {id, name, custom_fields}' > servers.json
  • (.tags // []): Defaults null/missing tags to an empty array, preventing errors.
  • any(.name == "cache"): Returns true if any tag matches; correctly handles position-0 tags.

193-200: Add transparency preservation flags to ImageMagick command.

The convert command lacks flags needed to preserve transparency during resizing. Without -alpha set -background none, the resize operation can default to opaque backgrounds, destroying transparency in source PNG images.

               if ! convert "${ORIGINAL}" \
+                    -alpha set \
+                    -background none \
                     -resize "${width}>" \
                     -strip \
                     -quality 90 \
                     "${OUT}"; then
  • -alpha set: Ensures the alpha channel is active for transparency preservation.
  • -background none: Sets a transparent background before resize operations to prevent white/opaque padding.

Note: -quality 90 already provides PNG compression level 9 (via the tens digit), so no additional compression flag is needed.

🧹 Nitpick comments (2)
.github/workflows/generate-thumbnails.yml (2)

27-27: Pin armbian/actions/team-check to a specific release version.

Using @main is a moving target and introduces supply-chain risk. The action publishes releases (v1.0, v1.1); pin to a specific version like @v1.1.

-        uses: armbian/actions/team-check@main
+        uses: armbian/actions/[email protected]

309-318: Consolidate servers.json into a proper JSON array for clarity and robustness.

The jq filter currently outputs a stream of individual objects to servers.json, which happens to work with the base64 iteration (line 318) but is fragile and non-obvious. Wrap the filter output in [...] to produce a single JSON array, then iterate with .[] | @base64 for clarity.

           | jq '[
                   .results[]
                   | select((.tags // []) | any(.name == "cache"))
                   | {id, name, custom_fields}
                 ]' > servers.json

           if [[ ! -s servers.json ]]; then
             echo "No cache servers returned from NetBox query, nothing to upload."
             exit 0
           fi

-          for row in $(jq -r '@base64' servers.json); do
+          for row in $(jq -r '.[] | @base64' servers.json); do

This clarifies that servers.json is an array and makes the iteration intent explicit.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a5479f9 and 10dab81.

📒 Files selected for processing (1)
  • .github/workflows/generate-thumbnails.yml (1 hunks)
🔇 Additional comments (1)
.github/workflows/generate-thumbnails.yml (1)

175-175: No fix needed for the find command on line 175.

The concern about matching previously-generated thumbnails is not valid. The find command searches only in board-images/ (the source directory), while generated output is written to a separate output/images/ directory. These directories are independent, so the find command cannot match thumbnails from prior runs.

Likely an incorrect or invalid review comment.

@igorpecovnik igorpecovnik force-pushed the device_images branch 5 times, most recently from acde47e to aa76baa Compare December 13, 2025 16:50
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (3)
.github/workflows/generate-thumbnails.yml (3)

22-31: Pin armbian/actions/team-check (avoid @main) for supply-chain stability.

armbian/actions/team-check@main can change without notice; pin to a release tag or commit SHA.

-        uses: armbian/actions/team-check@main
+        uses: armbian/actions/[email protected]

194-206: Board/vendor thumbnail convert commands don’t enforce transparency + PNG compression (and -quality is misleading for PNG).

This conflicts with the stated goal “preserves aspect ratio and transparency” + “optimizes images for web delivery”. Add explicit alpha/background and PNG compression defines (apply similarly for vendor SVG render, vendor normalization, and vendor thumbnails).

               if ! convert "${ORIGINAL}" \
+                    -alpha set \
+                    -background none \
                     -resize "${width}>" \
                     -strip \
-                    -quality 90 \
+                    -define png:compression-level=9 \
                     "${OUT}"; then
                 echo "WARN: convert failed for ${BOARD} width ${width}" >&2
                 continue
               fi
@@
               if [[ "${VORIG,,}" == *.svg ]]; then
-                if ! convert -background none -density 300 "${VORIG}" -strip "output/images/vendors/original/${out_name}"; then
+                if ! convert -alpha set -background none -density 300 "${VORIG}" \
+                      -strip -define png:compression-level=9 \
+                      "output/images/vendors/original/${out_name}"; then
                   echo "WARN: failed to render SVG for ${VENDOR}" >&2
                   vidx=$((vidx + 1))
                   continue
                 fi
               else
-                if ! convert "${VORIG}" -strip "output/images/vendors/original/${out_name}"; then
+                if ! convert "${VORIG}" -alpha set -background none \
+                      -strip -define png:compression-level=9 \
+                      "output/images/vendors/original/${out_name}"; then
                   echo "WARN: failed to normalize logo for ${VENDOR}" >&2
                   vidx=$((vidx + 1))
                   continue
                 fi
               fi
@@
                 if ! convert "output/images/vendors/original/${out_name}" \
+                      -alpha set \
+                      -background none \
                       -resize "${width}>" \
                       -strip \
-                      -quality 90 \
+                      -define png:compression-level=9 \
                       "${OUT}"; then

Also applies to: 252-276


306-332: NetBox jq selection + servers.json format will break upload loop (null-unsafe + stream vs array).

  • .tags[] errors when tags is null/missing.
  • index("cache") returns 0 for the first match (falsy), dropping valid cache servers.
  • servers.json is written as a stream but later consumed as a single JSON value and looped incorrectly.
           curl -sS \
             -H "Authorization: Token ${{ secrets.NETBOX_TOKEN }}" \
             -H "Accept: application/json; indent=4" \
             "${{ secrets.NETBOX_API }}/virtualization/virtual-machines/?limit=500&name__empty=false&status=active" \
-          | jq '.results[]
-                 | select([.tags[].name] | index("cache"))
-                 | {id, name, custom_fields}' > servers.json
+          | jq '[
+                  .results[]
+                  | select((.tags // []) | any(.name == "cache"))
+                  | {id, name, custom_fields}
+                ]' > servers.json
@@
-          if [[ ! -s servers.json ]]; then
+          if jq -e 'length == 0' servers.json >/dev/null; then
             echo "No cache servers returned from NetBox query, nothing to upload."
             exit 0
           fi
@@
-          for row in $(jq -r '@base64' servers.json); do
+          for row in $(jq -r '.[] | @base64' servers.json); do
             _jq() { echo "${row}" | base64 --decode | jq -r "${1}"; }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c27d1ce and aa76baa.

⛔ Files ignored due to path filters (1)
  • board-vendor-logos/arm-logo.png is excluded by !**/*.png
📒 Files selected for processing (1)
  • .github/workflows/generate-thumbnails.yml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Generate board + vendor images (2)
  • GitHub Check: Generate board + vendor images (0)
  • GitHub Check: Generate board + vendor images (3)
  • GitHub Check: Generate board + vendor images (1)

@igorpecovnik igorpecovnik force-pushed the device_images branch 6 times, most recently from c7d3ec0 to 4ff08e2 Compare December 13, 2025 19:17
@igorpecovnik igorpecovnik changed the title Establish consistent board image naming and push to mirrors Establish consistent board and vendor image naming and push images to mirrors. Dec 13, 2025
@igorpecovnik igorpecovnik changed the title Establish consistent board and vendor image naming and push images to mirrors. Keep consistent board & vendor thumbnail generation Dec 13, 2025
@igorpecovnik igorpecovnik force-pushed the device_images branch 4 times, most recently from 14f1def to d1f8e76 Compare December 14, 2025 08:54
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (3)
.github/workflows/generate-thumbnails.yml (3)

252-265: Vendor “original normalization” should set alpha + PNG compression (both SVG and raster paths).

               if [[ "${VORIG,,}" == *.svg ]]; then
-                if ! convert -background none -density 300 "${VORIG}" -strip "output/images/vendors/original/${out_name}"; then
+                if ! convert -alpha set -background none -density 300 "${VORIG}" \
+                      -define png:compression-level=9 \
+                      -strip "output/images/vendors/original/${out_name}"; then
                   echo "WARN: failed to render SVG for ${VENDOR}" >&2
                   vidx=$((vidx + 1))
                   continue
                 fi
               else
-                if ! convert "${VORIG}" -strip "output/images/vendors/original/${out_name}"; then
+                if ! convert "${VORIG}" -alpha set -background none \
+                      -define png:compression-level=9 \
+                      -strip "output/images/vendors/original/${out_name}"; then
                   echo "WARN: failed to normalize logo for ${VENDOR}" >&2
                   vidx=$((vidx + 1))
                   continue
                 fi
               fi

308-334: NetBox parsing/upload loop is currently broken (null-unsafe tags + wrong JSON shape + wrong jq iteration).

  • .tags[] can error when tags is null/missing.
  • index("cache") is falsy at position 0.
  • servers.json is written as an object stream, but later treated like a single JSON value; jq -r '@base64' servers.json won’t iterate objects.
           curl -sS \
             -H "Authorization: Token ${{ secrets.NETBOX_TOKEN }}" \
             -H "Accept: application/json; indent=4" \
             "${{ secrets.NETBOX_API }}/virtualization/virtual-machines/?limit=500&name__empty=false&status=active" \
-          | jq '.results[]
-                 | select([.tags[].name] | index("cache"))
-                 | {id, name, custom_fields}' > servers.json
+          | jq '[
+                 .results[]
+                 | select((.tags // []) | any(.name == "cache"))
+                 | {id, name, custom_fields}
+               ]' > servers.json
@@
-          if [[ ! -s servers.json ]]; then
+          if jq -e 'length == 0' servers.json >/dev/null; then
             echo "No cache servers returned from NetBox query, nothing to upload."
             exit 0
           fi
@@
-          for row in $(jq -r '@base64' servers.json); do
+          for row in $(jq -r '.[] | @base64' servers.json); do
             _jq() { echo "${row}" | base64 --decode | jq -r "${1}"; }

69-75: Avoid non-stable ref: igorpecovnik-patch-3 for armbian/build checkout. Using a feature branch instead of the stable main branch reduces reproducibility and makes the workflow fragile to upstream branch changes. Switch to the default stable branch:

       - name: "Checkout armbian/build"
         uses: actions/checkout@v4
         with:
           repository: armbian/build
           path: build
-          ref: igorpecovnik-patch-3
+          ref: main
🧹 Nitpick comments (1)
.github/workflows/generate-thumbnails.yml (1)

26-32: Pin armbian/actions/team-check to a specific version tag or commit SHA instead of @main.

The repository consistently pins external actions to specific versions (e.g., @v4, @v8), but armbian/actions uses @main, which can introduce unexpected behavior changes. Verify the available versions in the armbian/actions repository and update the pinning accordingly.

-        uses: armbian/actions/team-check@main
+        uses: armbian/actions/team-check@<version>

Note: This pattern appears in other workflows (generate-runners-status.yml, generate-redirector-config.yml) as well.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 14f1def and d1f8e76.

⛔ Files ignored due to path filters (25)
  • board-images/9tripod-x3568-v4.png is excluded by !**/*.png
  • board-images/aml-a311d-cc.png is excluded by !**/*.png
  • board-images/aml-s905d3-cc.png is excluded by !**/*.png
  • board-images/aml-s9xx-box.png is excluded by !**/*.png
  • board-images/bananapim5.png is excluded by !**/*.png
  • board-images/cherryba-m1.png is excluded by !**/*.png
  • board-images/hinlink-h88k.png is excluded by !**/*.png
  • board-images/imb3588.png is excluded by !**/*.png
  • board-images/jethubj100.png is excluded by !**/*.png
  • board-images/jethubj80.png is excluded by !**/*.png
  • board-images/khadas-edge.png is excluded by !**/*.png
  • board-images/kickpik2b.png is excluded by !**/*.png
  • board-images/lime.png is excluded by !**/*.png
  • board-images/lubancat2.png is excluded by !**/*.png
  • board-images/mangopi-m28k.png is excluded by !**/*.png
  • board-images/mekotronics-r58x-pro.png is excluded by !**/*.png
  • board-images/nanopi-r1s-h5.png is excluded by !**/*.png
  • board-images/nanopi-r2s-plus.png is excluded by !**/*.png
  • board-images/onecloud.png is excluded by !**/*.png
  • board-images/qemu-uboot-arm64.png is excluded by !**/*.png
  • board-images/qemu-uboot-x86.png is excluded by !**/*.png
  • board-images/qemu-uefi-x86.png is excluded by !**/*.png
  • board-images/rk3328-heltec.png is excluded by !**/*.png
  • board-images/roc-rk3399-pc.png is excluded by !**/*.png
  • board-images/rock-5-cm-rpi-cm4-io.png is excluded by !**/*.png
📒 Files selected for processing (1)
  • .github/workflows/generate-thumbnails.yml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Generate board + vendor images (0)
  • GitHub Check: Generate board + vendor images (2)
  • GitHub Check: Generate board + vendor images (1)
  • GitHub Check: Generate board + vendor images (3)

@igorpecovnik igorpecovnik force-pushed the device_images branch 3 times, most recently from 67605f2 to e1cb522 Compare December 14, 2025 09:33
@igorpecovnik igorpecovnik merged commit eb3cbd0 into main Dec 14, 2025
6 checks passed
@igorpecovnik igorpecovnik deleted the device_images branch December 14, 2025 09:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants