From 16a403d7dc5ca28424afe01d0db7dd3741dc7e71 Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Thu, 30 Apr 2026 13:05:06 -0600 Subject: [PATCH 1/2] refactor(fleet): use shared derived repo validation --- .github/workflows/build.yml | 2 +- .github/workflows/check-upstream.yml | 2 +- .github/workflows/publish-release.yml | 2 +- .github/workflows/release.yml | 2 +- scripts/validate-derived-repo.sh | 130 +++++--------------------- 5 files changed, 28 insertions(+), 110 deletions(-) mode change 100644 => 100755 scripts/validate-derived-repo.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f3568ea..18626f8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -64,7 +64,7 @@ concurrency: jobs: aio-build: - uses: JSONbored/aio-fleet/.github/workflows/aio-build.yml@c4099c09cb2375a0f5a5a822a0f8af02a77d0526 + uses: JSONbored/aio-fleet/.github/workflows/aio-build.yml@6cb527a4cccd624ad73447b6b73cda9b56b4c9c7 permissions: contents: read packages: write diff --git a/.github/workflows/check-upstream.yml b/.github/workflows/check-upstream.yml index 67cd6cb..1496902 100644 --- a/.github/workflows/check-upstream.yml +++ b/.github/workflows/check-upstream.yml @@ -14,7 +14,7 @@ concurrency: jobs: check-upstream: - uses: JSONbored/aio-fleet/.github/workflows/aio-check-upstream.yml@c4099c09cb2375a0f5a5a822a0f8af02a77d0526 + uses: JSONbored/aio-fleet/.github/workflows/aio-check-upstream.yml@6cb527a4cccd624ad73447b6b73cda9b56b4c9c7 permissions: contents: write pull-requests: write diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index b16beea..3a6169d 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -8,7 +8,7 @@ permissions: jobs: publish-release: - uses: JSONbored/aio-fleet/.github/workflows/aio-publish-release.yml@c4099c09cb2375a0f5a5a822a0f8af02a77d0526 + uses: JSONbored/aio-fleet/.github/workflows/aio-publish-release.yml@6cb527a4cccd624ad73447b6b73cda9b56b4c9c7 permissions: actions: read contents: write diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 91d03d5..8b7102e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ permissions: jobs: prepare-release: - uses: JSONbored/aio-fleet/.github/workflows/aio-prepare-release.yml@c4099c09cb2375a0f5a5a822a0f8af02a77d0526 + uses: JSONbored/aio-fleet/.github/workflows/aio-prepare-release.yml@6cb527a4cccd624ad73447b6b73cda9b56b4c9c7 permissions: contents: write pull-requests: write diff --git a/scripts/validate-derived-repo.sh b/scripts/validate-derived-repo.sh old mode 100644 new mode 100755 index ae1a53f..d6cf5fb --- a/scripts/validate-derived-repo.sh +++ b/scripts/validate-derived-repo.sh @@ -1,120 +1,38 @@ #!/usr/bin/env bash -# shellcheck disable=SC2312 set -euo pipefail repo_root="${1:-.}" -cd "${repo_root}" strict_placeholders="${STRICT_PLACEHOLDERS:-false}" -fail() { - echo "template validation error: $*" >&2 - exit 1 -} - -require_file() { - local path="$1" - [[ -f ${path} ]] || fail "missing required file: ${path}" -} - -require_absent() { - local path="$1" - [[ ! -e ${path} ]] || fail "remove template placeholder path in derived repo: ${path}" -} - -check_no_placeholder() { - local pattern="$1" - shift - if grep -F -n -- "${pattern}" "$@" >/dev/null 2>&1; then - fail "found unresolved placeholder '${pattern}' in: $*" - fi -} - -require_file "Dockerfile" -require_file "README.md" -require_file "pyproject.toml" -require_file "tests/template/test_validate_template.py" -require_file "tests/integration/test_container_runtime.py" -require_file "scripts/validate-template.py" -if [[ -f components.toml ]]; then - require_file "scripts/components.py" -fi -require_file "scripts/update-template-changes.py" -require_file ".github/FUNDING.yml" -require_file "SECURITY.md" -require_file ".github/pull_request_template.md" -require_file ".github/ISSUE_TEMPLATE/bug_report.yml" -require_file ".github/ISSUE_TEMPLATE/feature_request.yml" -require_file ".github/ISSUE_TEMPLATE/installation_help.yml" -require_file ".github/ISSUE_TEMPLATE/config.yml" -require_file "renovate.json" -require_absent ".github/CODEOWNERS" - -effective_template_xml="${TEMPLATE_XML-}" -component_template_xml=() -if [[ -f components.toml ]]; then - while IFS= read -r template_path; do - [[ -n ${template_path} ]] || continue - component_template_xml+=("${template_path}") - done < <( - python3 - <<'PY' -from scripts.components import load_components - -for component in load_components(): - print(component.template) -PY - ) +args=(validate-derived --repo-path "${repo_root}") +if [[ ${strict_placeholders} == "true" ]]; then + args+=(--strict-placeholders) fi -if [[ -z ${effective_template_xml} ]]; then - repo_name="${PWD##*/}" - inferred_repo_xml="${repo_name}.xml" - if [[ -f ${inferred_repo_xml} ]]; then - effective_template_xml="${inferred_repo_xml}" - else - root_xml_files=() - shopt -s nullglob - for xml_path in ./*.xml; do - [[ -f ${xml_path} ]] || continue - root_xml_files+=("${xml_path#./}") - done - shopt -u nullglob - if [[ ${#root_xml_files[@]} -eq 1 ]]; then - effective_template_xml="${root_xml_files[0]}" - fi - fi +if python3 -c "import aio_fleet" >/dev/null 2>&1; then + exec python3 -m aio_fleet.cli "${args[@]}" fi -is_template_repo="false" -if [[ -f .github/workflows/publish-release.yml ]] && grep -F -q -- "Publish Release / Template" .github/workflows/publish-release.yml; then - is_template_repo="true" +script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +candidate_roots=() +if [[ -n ${AIO_FLEET_PATH-} ]]; then + candidate_roots+=("${AIO_FLEET_PATH}") fi - -if [[ -n ${effective_template_xml} ]]; then - require_file "${effective_template_xml}" - if [[ ${is_template_repo} != "true" ]]; then - require_absent "template-aio.xml" +candidate_roots+=( + "${script_dir}/../../aio-fleet" + "${script_dir}/../../../aio-fleet" + "../aio-fleet" + "../../aio-fleet" +) + +for candidate in "${candidate_roots[@]}"; do + if [[ -d ${candidate}/src/aio_fleet ]]; then + PYTHONPATH="${candidate}/src${PYTHONPATH:+:${PYTHONPATH}}" exec python3 -m aio_fleet.cli "${args[@]}" fi -fi - -xml_files=() -for xml_path in "${component_template_xml[@]}"; do - require_file "${xml_path}" - xml_files+=("${xml_path}") done -if [[ -n ${effective_template_xml} ]] && [[ -f ${effective_template_xml} ]]; then - xml_files+=("${effective_template_xml}") -fi - -if [[ ${strict_placeholders} == "true" ]]; then - check_no_placeholder "Replace this starter base with the real upstream image once the derived repo is wired." "Dockerfile" - if [[ ${#xml_files[@]} -gt 0 ]]; then - check_no_placeholder "yourapp-aio" "${xml_files[@]}" - check_no_placeholder "Replace this overview with the real app description and first-run guidance." "${xml_files[@]}" - check_no_placeholder "replace-with-real-search-terms" "${xml_files[@]}" - check_no_placeholder "Replace this with any real operational prerequisites or remove it." "${xml_files[@]}" - check_no_placeholder "https://github.com/JSONbored/yourapp-aio/releases" "${xml_files[@]}" - fi - check_no_placeholder "aio-template starter app" rootfs/etc/services.d/app/run rootfs/usr/local/bin/aio-template-app.py -fi -echo "Derived repo validation passed." +cat >&2 <<'EOF' +template validation error: aio-fleet is required for derived repo validation. +Install aio-fleet or set AIO_FLEET_PATH to a local aio-fleet checkout. +EOF +exit 1 From 79accd61e4b7beb22ad55f0fda959fa0690d6575 Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Thu, 30 Apr 2026 13:13:51 -0600 Subject: [PATCH 2/2] ci(fleet): repin shared workflow validator --- .github/workflows/build.yml | 2 +- .github/workflows/check-upstream.yml | 2 +- .github/workflows/publish-release.yml | 2 +- .github/workflows/release.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 18626f8..5ada56d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -64,7 +64,7 @@ concurrency: jobs: aio-build: - uses: JSONbored/aio-fleet/.github/workflows/aio-build.yml@6cb527a4cccd624ad73447b6b73cda9b56b4c9c7 + uses: JSONbored/aio-fleet/.github/workflows/aio-build.yml@388300f0f98701ea81bd8185660257d06cd8f472 permissions: contents: read packages: write diff --git a/.github/workflows/check-upstream.yml b/.github/workflows/check-upstream.yml index 1496902..7eeaa63 100644 --- a/.github/workflows/check-upstream.yml +++ b/.github/workflows/check-upstream.yml @@ -14,7 +14,7 @@ concurrency: jobs: check-upstream: - uses: JSONbored/aio-fleet/.github/workflows/aio-check-upstream.yml@6cb527a4cccd624ad73447b6b73cda9b56b4c9c7 + uses: JSONbored/aio-fleet/.github/workflows/aio-check-upstream.yml@388300f0f98701ea81bd8185660257d06cd8f472 permissions: contents: write pull-requests: write diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 3a6169d..fe1c368 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -8,7 +8,7 @@ permissions: jobs: publish-release: - uses: JSONbored/aio-fleet/.github/workflows/aio-publish-release.yml@6cb527a4cccd624ad73447b6b73cda9b56b4c9c7 + uses: JSONbored/aio-fleet/.github/workflows/aio-publish-release.yml@388300f0f98701ea81bd8185660257d06cd8f472 permissions: actions: read contents: write diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8b7102e..1e01cd0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ permissions: jobs: prepare-release: - uses: JSONbored/aio-fleet/.github/workflows/aio-prepare-release.yml@6cb527a4cccd624ad73447b6b73cda9b56b4c9c7 + uses: JSONbored/aio-fleet/.github/workflows/aio-prepare-release.yml@388300f0f98701ea81bd8185660257d06cd8f472 permissions: contents: write pull-requests: write