feat: единая админка runtime-конфигов и indpic (#22)
deploy-preland / deploy zoomstage.online (push) Successful in 1m1s
deploy-preland / deploy zoomstage.online (push) Successful in 1m1s
This commit is contained in:
1 parent
5b6b2d2053
commit
9515c1c62b
52 files changed
+2459
-34
No files matched your search
@@ -50,9 +50,9 @@ foreach ([
|
||||
|
||||
$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',
|
||||
'php bin/release-assets.php --stage-sets "$PRELAND_URL"',
|
||||
'php bin/release-assets.php --remote "$PRELAND_URL"',
|
||||
'php-imagick',
|
||||
'Remove obsolete demo directories',
|
||||
] as $requiredStageSmokeCheck) {
|
||||
if (!str_contains($workflow, $requiredStageSmokeCheck)) {
|
||||
@@ -60,6 +60,14 @@ foreach ([
|
||||
}
|
||||
}
|
||||
|
||||
// #22: реальный runtime config выбирает наборы; удаление неиспользуемого /2/
|
||||
// не должно блокировать выпуск. Обязательные файлы/размеры проверяет guard.
|
||||
require_once $root . '/bin/release-assets.php';
|
||||
foreach (releaseFiles($root) as $file) {
|
||||
if (preg_match('~^(admin/|config\.json$|[0-9]+/)~', $file)) $failures[] = 'Runtime/приватный файл в поставке: ' . $file;
|
||||
}
|
||||
if (runtimeSetNumbers(['utm' => ['indpic' => ['default' => '3', 'weights' => ['3' => 1]]]]) !== [3]) $failures[] = 'Наборы должны определяться фактическим config';
|
||||
|
||||
if (!str_contains($workflow, '|[0-9]+/)')) {
|
||||
$failures[] = 'Stage-деплой не должен перезаписывать корневые наборы /N/: stage владеет их содержимым.';
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/** preland#22: runtime-контент независим от Git, контракт изображений обязателен. */
|
||||
declare(strict_types=1);
|
||||
require_once dirname(__DIR__) . '/bin/check-runtime-sets.php';
|
||||
require_once dirname(__DIR__) . '/bin/release-assets.php';
|
||||
$root = dirname(__DIR__);
|
||||
$fixture = sys_get_temp_dir() . '/preland22-' . bin2hex(random_bytes(6));
|
||||
mkdir($fixture);
|
||||
mkdir($fixture . '/1');
|
||||
$assertFails = static function (callable $operation): void {
|
||||
try { $operation(); } catch (RuntimeException $expected) { return; }
|
||||
throw new LogicException('Повреждённый runtime-контракт принят');
|
||||
};
|
||||
try {
|
||||
foreach (runtimeSetDimensions() as $name => $dimensions) copy($root . '/1/' . $name, $fixture . '/1/' . $name);
|
||||
$config = ['utm' => ['indpic' => ['default' => '1', 'weights' => ['1' => 1]]]];
|
||||
// Замена изображения корректным новым изображением не требует Git SHA.
|
||||
$image = new Imagick($fixture . '/1/01_desk_1-source.jpg');
|
||||
$image->setImageProperty('comment', 'runtime replacement preland#22');
|
||||
$image->writeImage($fixture . '/1/01_desk_1-source.jpg');
|
||||
$image->clear();
|
||||
if (hash_file('sha256', $fixture . '/1/01_desk_1-source.jpg') === hash_file('sha256', $root . '/1/01_desk_1-source.jpg')) throw new LogicException('Fixture не изменён');
|
||||
checkRuntimeSets($config, runtimeLocalReader($fixture), $fixture);
|
||||
$requests = [];
|
||||
checkRuntimeSets($config, static function (string $path) use ($fixture, &$requests): string { $requests[] = $path; return runtimeLocalReader($fixture)($path); });
|
||||
if (count($requests) !== 90) throw new LogicException('HTTP-путь обязан прочитать все 90 файлов');
|
||||
$bytes = file_get_contents($fixture . '/1/01_desk_1-source.jpg');
|
||||
file_put_contents($fixture . '/1/01_desk_1-source.jpg', '<html>HTTP 200</html>');
|
||||
$assertFails(fn() => checkRuntimeSets($config, runtimeLocalReader($fixture), $fixture));
|
||||
file_put_contents($fixture . '/1/01_desk_1-source.jpg', $bytes);
|
||||
$wrong = new Imagick(); $wrong->newImage(1, 1, 'red', 'jpeg'); $wrong->writeImage($fixture . '/1/01_desk_1-source.jpg'); $wrong->clear();
|
||||
$assertFails(fn() => checkRuntimeSets($config, runtimeLocalReader($fixture), $fixture));
|
||||
file_put_contents($fixture . '/1/01_desk_1-source.jpg', $bytes);
|
||||
file_put_contents($fixture . '/1/extra.txt', 'extra');
|
||||
$assertFails(fn() => checkRuntimeSets($config, runtimeLocalReader($fixture), $fixture));
|
||||
unlink($fixture . '/1/extra.txt');
|
||||
unlink($fixture . '/1/05_mob_3-thumb.avif');
|
||||
$assertFails(fn() => checkRuntimeSets($config, runtimeLocalReader($fixture), $fixture));
|
||||
copy($root . '/1/05_mob_3-thumb.avif', $fixture . '/1/05_mob_3-thumb.avif');
|
||||
foreach (['0', '10', '../1', false, null] as $default) {
|
||||
$bad = $config; $bad['utm']['indpic']['default'] = $default;
|
||||
$assertFails(fn() => checkRuntimeSets($bad, runtimeLocalReader($fixture), $fixture));
|
||||
}
|
||||
$bad = $config; $bad['utm']['indpic']['weights']['2'] = 1;
|
||||
$assertFails(fn() => checkRuntimeSets($bad, runtimeLocalReader($fixture), $fixture));
|
||||
$bad = $config; $bad['utm']['indpic']['default'] = '2';
|
||||
$assertFails(fn() => checkRuntimeSets($bad, runtimeLocalReader($fixture), $fixture));
|
||||
checkRuntimeSets([], runtimeLocalReader($fixture), $fixture); // штатный fallback /1/
|
||||
foreach (releaseFiles($root) as $file) if (preg_match('~^(admin/|config\.json$|[0-9]+/)~', $file)) throw new LogicException('Приватный/runtime файл в поставке');
|
||||
echo "OK: runtime replacement, decode, dimensions, missing/extra files, default, active links, release isolation\n";
|
||||
} finally {
|
||||
foreach (glob($fixture . '/1/*') as $file) unlink($file);
|
||||
rmdir($fixture . '/1'); rmdir($fixture);
|
||||
}
|
||||
Reference in new issue
Block a user