Stop 404ing on every header, and start pvesh before the checks #8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Verify split files | |
| # shared/tools.func and shared/build-ui.func are loaders whose implementations | |
| # sit in shared/tools/ and shared/build-ui/. A split can silently lose a | |
| # function -- most easily by cutting through a heredoc that contains a column-0 | |
| # function definition, which looks like a definition but is payload. That only | |
| # surfaces on a user's host at install time, so it is checked here instead. | |
| # | |
| # The same applies to the prefetch lists in shared/build.func and | |
| # shared/install.func: a .func missing from one still works, it just costs a | |
| # round trip nobody would notice. So they are checked, not trusted. | |
| on: | |
| pull_request: | |
| paths: | |
| - "shared/**" | |
| - "pve/**" | |
| - "incus/**" | |
| push: | |
| branches: [main] | |
| paths: | |
| - "shared/**" | |
| - "pve/**" | |
| - "incus/**" | |
| workflow_dispatch: | |
| jobs: | |
| verify: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Every part parses | |
| run: | | |
| set -euo pipefail | |
| fail=0 | |
| for f in shared/tools.func shared/tools/*.func shared/build-ui.func shared/build-ui/*.func; do | |
| bash -n "$f" || { echo "::error file=$f::syntax error"; fail=1; } | |
| done | |
| exit $fail | |
| - name: Prefetch lists cover every engine file | |
| run: | | |
| set -euo pipefail | |
| fail=0 | |
| mapfile -t on_disk < <(find shared pve incus -name '*.func' -type f | sort) | |
| mapfile -t listed < <( | |
| sed -n '/^_CS_ENGINE_FILES=(/,/^)/p' shared/build.func | | |
| tr -s '[:space:]' '\n' | grep -E '^(shared|pve|incus)/.*\.func$' | sort | |
| ) | |
| for f in "${on_disk[@]}"; do | |
| # build.func is the file doing the fetching; it is already loaded. | |
| [[ "$f" == "shared/build.func" ]] && continue | |
| printf '%s\n' "${listed[@]}" | grep -qxF "$f" || { | |
| echo "::error file=shared/build.func::$f is missing from _CS_ENGINE_FILES" | |
| fail=1 | |
| } | |
| done | |
| for f in "${listed[@]}"; do | |
| [[ -f "$f" ]] || { | |
| echo "::error file=shared/build.func::_CS_ENGINE_FILES lists $f, which does not exist" | |
| fail=1 | |
| } | |
| done | |
| # install.func fetches the subset a container needs, by bare name. | |
| mapfile -t ct_listed < <( | |
| sed -n '/^_CS_CT_ENGINE_FILES=(/,/^)/p' shared/install.func | | |
| tr -s '[:space:]' '\n' | grep -E '\.func$' | sort | |
| ) | |
| for f in "${ct_listed[@]}"; do | |
| [[ -f "shared/$f" ]] || { | |
| echo "::error file=shared/install.func::_CS_CT_ENGINE_FILES lists $f, which does not exist" | |
| fail=1 | |
| } | |
| done | |
| for f in shared/tools/*.func; do | |
| printf '%s\n' "${ct_listed[@]}" | grep -qxF "${f#shared/}" || { | |
| echo "::error file=shared/install.func::${f#shared/} is missing from _CS_CT_ENGINE_FILES" | |
| fail=1 | |
| } | |
| done | |
| echo "engine: ${#listed[@]} of ${#on_disk[@]} listed, container: ${#ct_listed[@]}" | |
| exit $fail | |
| - name: Each loader still defines its whole API | |
| run: | | |
| set -euo pipefail | |
| check() { | |
| local loader="$1" snapshot="$2" | |
| bash -c ' | |
| COMMUNITY_SCRIPTS_CORE_DIR="$PWD" | |
| _cs_source_func() { source "$COMMUNITY_SCRIPTS_CORE_DIR/$1"; } | |
| source "'"$loader"'" >/dev/null 2>&1 | |
| declare -F | awk "{print \$3}" | | |
| grep -vE "^(_cs_source_func|_tools_source_part|_build_ui_source)$" | sort | |
| ' > /tmp/actual.txt | |
| if ! diff -u "$snapshot" /tmp/actual.txt; then | |
| echo "::error::$loader exports a different set of functions." | |
| echo "Intentional? Regenerate $snapshot in the same PR." | |
| return 1 | |
| fi | |
| echo "$loader: $(wc -l < /tmp/actual.txt) functions, unchanged" | |
| } | |
| fail=0 | |
| check shared/tools.func shared/tools/API.txt || fail=1 | |
| check shared/build-ui.func shared/build-ui/API.txt || fail=1 | |
| exit $fail |