From d60a9ccb7d56c0eb99af367349c85bdcc8690f4a Mon Sep 17 00:00:00 2001 From: Meliox Date: Sun, 14 Jun 2026 01:21:16 +0200 Subject: [PATCH] sd --- .github/workflows/test-release.yml | 2 +- .github/workflows/validate-mods.yml | 13 ++- .github/workflows/weekly-patch-test.yml | 2 +- src/Scripts/test/test-syntax.sh | 144 ++++++++++++++++++++++++ 4 files changed, 154 insertions(+), 7 deletions(-) create mode 100644 src/Scripts/test/test-syntax.sh diff --git a/.github/workflows/test-release.yml b/.github/workflows/test-release.yml index 8a02c8a..a64a1cb 100644 --- a/.github/workflows/test-release.yml +++ b/.github/workflows/test-release.yml @@ -76,4 +76,4 @@ jobs: retention-days: 3 patch-install-test: needs: test-release-build - uses: ./.github/workflows/test-patches.yml \ No newline at end of file + uses: ./.github/workflows/validate-mods.yml \ No newline at end of file diff --git a/.github/workflows/validate-mods.yml b/.github/workflows/validate-mods.yml index 20fdca9..5fd7a74 100644 --- a/.github/workflows/validate-mods.yml +++ b/.github/workflows/validate-mods.yml @@ -1,8 +1,8 @@ -name: Test Patches - Post Build +name: Validate Mods # Called by Test Release Build after a successful .deb build. -# Installs the artifact on a Proxmox-seeded runner and verifies -# that every mod's patches apply and revert cleanly. +# Validates source syntax for all mods, then installs the artifact on a +# Proxmox-seeded runner and verifies that every mod's patches apply and revert cleanly. on: workflow_call: @@ -20,10 +20,13 @@ jobs: run: | apt-get update apt-get install -y --no-install-recommends \ - ca-certificates git sudo wget xz-utils dpkg + ca-certificates git sudo wget xz-utils dpkg nodejs - uses: actions/checkout@v4 + - name: Validate source syntax + run: bash src/Scripts/test/test-syntax.sh all + - name: Download deb artifact uses: actions/download-artifact@v4 with: @@ -38,4 +41,4 @@ jobs: run: apt-get install -y ./deb/*.deb - name: Test all mods - run: bash src/Scripts/test/test-mods.sh all \ No newline at end of file + run: bash src/Scripts/test/test-patches.sh all \ No newline at end of file diff --git a/.github/workflows/weekly-patch-test.yml b/.github/workflows/weekly-patch-test.yml index e4a700d..c43bf26 100644 --- a/.github/workflows/weekly-patch-test.yml +++ b/.github/workflows/weekly-patch-test.yml @@ -76,7 +76,7 @@ jobs: - name: Test mod run: | set -o pipefail - sudo bash src/Scripts/test/test-mods.sh "${{ matrix.mod }}" 2>&1 | tee test-output.log + sudo bash src/Scripts/test/test-patches.sh "${{ matrix.mod }}" 2>&1 | tee test-output.log - name: Report failure as issue if: failure() diff --git a/src/Scripts/test/test-syntax.sh b/src/Scripts/test/test-syntax.sh new file mode 100644 index 0000000..b52e43e --- /dev/null +++ b/src/Scripts/test/test-syntax.sh @@ -0,0 +1,144 @@ +#!/usr/bin/env bash +# src/Scripts/test/test-syntax.sh +# +# Validates source syntax for all mod files without requiring a running system. +# +# Usage: test-syntax.sh | all +# +# Mods are auto-discovered by scanning for subdirectories of src/ that contain +# a files/ or patches/ directory. No installed package required. +# +# For each target mod it: +# 1. runs perl -c on every .pm file under /files/ +# 2. runs node --check on every .js file under /files/ +# 3. runs bash -n on post-apply.sh and post-revert.sh in /patches/ + +set -u + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SRC_DIR="${PVE_MOD_SRC_DIR:-$(cd "$SCRIPT_DIR/../../.." && pwd)/src}" + +info() { echo "[syntax] $*"; } +warn() { echo "[syntax] WARNING: $*" >&2; } + +# List mod names by scanning SRC_DIR for subdirs that contain files/ or patches/. +list_modules() { + local d name + for d in "$SRC_DIR"/*/; do + [[ -d "$d" ]] || continue + name="$(basename "$d")" + if [[ -d "$d/files" || -d "$d/patches" ]]; then + echo "$name" + fi + done | sort +} + +# check_perl_syntax : run perl -c on every .pm under /files/ +check_perl_syntax() { + local mod="$1" + local files_dir="$SRC_DIR/$mod/files" + [[ -d "$files_dir" ]] || return 0 + + local ok=0 f output + while IFS= read -r f; do + output="$(perl -c "$f" 2>&1)" + if [[ $? -ne 0 ]]; then + warn "perl -c FAILED: $f" + echo "$output" + ok=1 + fi + done < <(find "$files_dir" -name "*.pm" -type f | sort) + return $ok +} + +# check_js_syntax : run node --check on every .js under /files/ +check_js_syntax() { + local mod="$1" + local files_dir="$SRC_DIR/$mod/files" + [[ -d "$files_dir" ]] || return 0 + + local ok=0 f output + while IFS= read -r f; do + output="$(node --check "$f" 2>&1)" + if [[ $? -ne 0 ]]; then + warn "node --check FAILED: $f" + echo "$output" + ok=1 + fi + done < <(find "$files_dir" -name "*.js" -type f | sort) + return $ok +} + +# check_bash_syntax : run bash -n on post-apply.sh and post-revert.sh +check_bash_syntax() { + local mod="$1" + local patches_src="$SRC_DIR/$mod/patches" + [[ -d "$patches_src" ]] || return 0 + + local ok=0 script f output + for script in post-apply.sh post-revert.sh; do + f="$patches_src/$script" + [[ -f "$f" ]] || continue + output="$(bash -n "$f" 2>&1)" + if [[ $? -ne 0 ]]; then + warn "bash -n FAILED: $f" + echo "$output" + ok=1 + fi + done + return $ok +} + +# test_syntax_one_mod : run all syntax checks for one mod. +# Returns 0 on pass, 1 on any failure. +test_syntax_one_mod() { + local mod="$1" + echo "::group::Syntax check: $mod" + local ok=0 + + check_perl_syntax "$mod" || ok=1 + check_js_syntax "$mod" || ok=1 + check_bash_syntax "$mod" || ok=1 + + if [[ $ok -eq 0 ]]; then + info "PASS: $mod" + else + warn "FAIL: $mod" + fi + echo "::endgroup::" + return $ok +} + +# ── main ────────────────────────────────────────────────────────────────────── +[[ $# -eq 1 ]] || { echo "Usage: $0 |all" >&2; exit 2; } + +if ! command -v perl >/dev/null 2>&1; then + warn "'perl' command not found; install perl." + exit 1 +fi + +if ! command -v node >/dev/null 2>&1; then + warn "'node' command not found; install nodejs." + exit 1 +fi + +targets=() +if [[ "$1" == "all" ]]; then + mapfile -t targets < <(list_modules) + [[ ${#targets[@]} -gt 0 ]] || { warn "no mods found in $SRC_DIR"; exit 1; } +else + targets=("$1") +fi + +failed=() +for mod in "${targets[@]}"; do + test_syntax_one_mod "$mod" || failed+=("$mod") +done + +echo "" +if [[ ${#failed[@]} -gt 0 ]]; then + warn "Failed mods: ${failed[*]}" + exit 1 +fi +info "All tested mods passed: ${targets[*]}" +exit 0