/`, а в нём flat-файлы Index. */ declare(strict_types=1); $root = dirname(__DIR__); $failures = []; foreach ([ '1/01_desk_1-source.avif', '1/01_desk_2-result.avif', '1/01_desk_3-thumb.avif', '1/05_mob_1-source.avif', '1/05_mob_2-result.avif', '1/05_mob_3-thumb.avif', '2/01_desk_1-source.avif', '2/05_mob_2-result.avif', ] as $relativePath) { if (!is_file($root . '/' . $relativePath)) { $failures[] = "Отсутствует Index-совместимый asset {$relativePath}."; } } foreach ([ 'images/demo', 'images/demo-2', ] as $obsoletePath) { if (is_dir($root . '/' . $obsoletePath)) { $failures[] = "Устаревший каталог {$obsoletePath} не должен оставаться в репозитории."; } } $template = (string) file_get_contents($root . '/template.php'); $examples = (string) file_get_contents($root . '/components/examples.php'); foreach ([ [$template, '"/{$indpic}"'], [$template, '01_desk_1-source.avif'], [$examples, "sprintf('%02d', \$number)"], [$examples, "'desk', '1-source'"], [$examples, "'mob', '3-thumb'"], ] as [$source, $expected]) { if (!str_contains($source, $expected)) { $failures[] = "Путь примеров должен использовать корневой flat-формат Index ({$expected})."; } } $workflow = (string) file_get_contents($root . '/.gitea/workflows/deploy.yml'); foreach ([ '"$PRELAND_URL/1/01_desk_1-source.avif"', '"$PRELAND_URL/2/01_desk_1-source.avif"', '2/01_mob_1-source.avif', 'Remove obsolete demo directories', ] as $requiredStageSmokeCheck) { if (!str_contains($workflow, $requiredStageSmokeCheck)) { $failures[] = "Stage-деплой обязан проверять публикацию {$requiredStageSmokeCheck}."; } } if (substr_count($workflow, 'while [ -n "$dir" ]; do') < 2) { $failures[] = 'SFTP-деплой должен создавать все родительские каталоги для новых наборов assets.'; } if ($failures !== []) { fwrite(STDERR, "FAILED\n- " . implode("\n- ", $failures) . "\n"); exit(1); } fwrite(STDOUT, "OK: Preland root sets match Index layout\n");