From c34c7cf9c21e68e52141ded395a224ecd880ba89 Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Tue, 16 Dec 2025 12:17:26 +0100 Subject: [PATCH] GHA: Enforce board and vendor image availability for newly added boards --- .github/workflows/pr-check-pictures.yml | 170 ++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 .github/workflows/pr-check-pictures.yml diff --git a/.github/workflows/pr-check-pictures.yml b/.github/workflows/pr-check-pictures.yml new file mode 100644 index 0000000000..583c064f94 --- /dev/null +++ b/.github/workflows/pr-check-pictures.yml @@ -0,0 +1,170 @@ +name: "Check new board assets exist (images + vendor logos)" + +on: + pull_request: + paths: + - "config/boards/**" + +env: + WEBSITE_REPO: "armbian/armbian.github.io" + WEBSITE_REF: "main" + + BOARDS_PATH: "config/boards" + BOARD_IMAGES_DIR: "board-images" + VENDOR_LOGOS_DIR: "board-vendor-logos" + +jobs: + Check: + name: "Verify assets for newly added boards" + runs-on: ubuntu-24.04 + permissions: + contents: read + pull-requests: write + + steps: + - name: "Checkout build repo (PR head)" + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: "Checkout armbian.github.io (images repo)" + uses: actions/checkout@v4 + with: + repository: ${{ env.WEBSITE_REPO }} + ref: ${{ env.WEBSITE_REF }} + path: website + fetch-depth: 1 + + - name: "Find newly added board configs in PR" + id: added + shell: bash + run: | + set -euo pipefail + + BASE_SHA="${{ github.event.pull_request.base.sha }}" + HEAD_SHA="${{ github.event.pull_request.head.sha }}" + + git diff --name-status "${BASE_SHA}" "${HEAD_SHA}" -- "${BOARDS_PATH}" \ + | awk '$1=="A"{print $2}' \ + | grep -E '\.(conf|csc|wip|tvb)$' \ + > added-files.txt || true + + echo "New board config files:" + cat added-files.txt || true + + if [[ ! -s added-files.txt ]]; then + echo "No new board configs detected." + echo "none=true" >> "$GITHUB_OUTPUT" + else + echo "none=false" >> "$GITHUB_OUTPUT" + fi + + - name: "Validate board image + vendor logo exist on website repo" + id: validate + if: ${{ steps.added.outputs.none != 'true' }} + shell: bash + run: | + set -euo pipefail + + missing_any=0 + comment_file="$(mktemp)" + + { + echo "" + echo "This PR adds new board configuration(s). Required assets must already exist in [github/${WEBSITE_REPO}](https://github.com/${WEBSITE_REPO})." + echo "They are required by [Armbian Imager](https://github.com/armbian/imager) to ensure all boards are displayed with proper images." + echo "" + echo "- Board images: \`${BOARD_IMAGES_DIR}/.png\`" + echo "- Vendor logos: \`${VENDOR_LOGOS_DIR}/-logo.png\`" + echo "" + echo "### Missing items" + echo "" + } > "$comment_file" + + while IFS= read -r cfg; do + [[ -z "${cfg}" ]] && continue + + file="$(basename "$cfg")" + board="${file%.*}" + + vendor="$( + grep -E '^[[:space:]]*(export[[:space:]]+)?BOARD_VENDOR[[:space:]]*=' -m1 -- "$cfg" 2>/dev/null \ + | sed -E 's/^[[:space:]]*(export[[:space:]]+)?BOARD_VENDOR[[:space:]]*=[[:space:]]*//; s/^"//; s/"$//' \ + | tr '[:upper:]' '[:lower:]' \ + | tr '_' '-' \ + | awk 'NF{print; exit}' \ + || true + )" + + board_img_match="$(find "website/${BOARD_IMAGES_DIR}" -maxdepth 1 -type f -iname "${board}.png" | head -n1 || true)" + + if [[ -z "${board_img_match}" ]]; then + { + echo "- ❌ **Board image missing** for \`${board}\`" + echo " - Expected: \`${BOARD_IMAGES_DIR}/${board}.png\`" + echo " - Fix: add the file to **${WEBSITE_REPO}** (folder \`${BOARD_IMAGES_DIR}/\`)" + echo "" + } >> "$comment_file" + missing_any=1 + fi + + if [[ -z "${vendor}" ]]; then + { + echo "- ❌ **BOARD_VENDOR not found** in \`${cfg}\`" + echo " - Fix: add e.g. \`BOARD_VENDOR=\"radxa\"\` (lowercase recommended)" + echo "" + } >> "$comment_file" + missing_any=1 + continue + fi + + found_logo="$(find "website/${VENDOR_LOGOS_DIR}" -maxdepth 1 -type f \ + \( -iname "${vendor}-logo.png" -o -iname "${vendor}-logo.jpg" -o -iname "${vendor}-logo.jpeg" -o -iname "${vendor}-logo.svg" \) \ + | head -n1 || true)" + + if [[ -z "${found_logo}" ]]; then + { + echo "- ❌ **Vendor logo missing** for vendor \`${vendor}\` (used by board \`${board}\`)" + echo " - Expected: \`${VENDOR_LOGOS_DIR}/${vendor}-logo.(png|jpg|jpeg|svg)\`" + echo " - Fix: add the file to **${WEBSITE_REPO}** (folder \`${VENDOR_LOGOS_DIR}/\`)" + echo " - Naming rules: lowercase, dashes (e.g. \`kobol-logo.png\`, not \`Kobol_logo.png\`)" + echo "" + } >> "$comment_file" + missing_any=1 + fi + done < added-files.txt + + if [[ "${missing_any}" -ne 0 ]]; then + echo "missing=true" >> "$GITHUB_OUTPUT" + echo 'comment<> "$GITHUB_OUTPUT" + cat "$comment_file" >> "$GITHUB_OUTPUT" + echo 'EOF' >> "$GITHUB_OUTPUT" + echo "::warning ::Missing required assets (see PR comment)." + else + echo "missing=false" >> "$GITHUB_OUTPUT" + fi + + - name: "Comment on PR with missing asset instructions" + if: always() && github.event_name == 'pull_request' && steps.validate.outputs.missing == 'true' + uses: actions/github-script@v7 + env: + COMMENT_BODY: ${{ steps.validate.outputs.comment }} + WEBSITE_REPO: ${{ env.WEBSITE_REPO }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const body = + `### 🚫 Missing required board assets + + ${process.env.COMMENT_BODY} + + Once the missing files are added (or a PR is opened in **${process.env.WEBSITE_REPO}**), re-run this check. + `; + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body + });