isFile()) { $hashes[$file->getPathname()] = hash_file('sha256', $file->getPathname()); } } ksort($hashes); return $hashes; }; $before = $snapshot(); $test = new Process([PHP_BINARY, 'artisan', 'test', '--compact', '--filter=PurchasingReleaseTest|PurchasingEconomicsTest|SupplierQuotationTest|PurchaseAwardOrderTest|ProposalOpeningTest|SupplyPlanningTest|SupplyHistoryTest|InventoryLotsTest|SupplyCoordinationTest|SupplySuggestionsTest|InventoryReversalsTest|InventoryCountsTest'], dirname(__DIR__), timeout: 120); $test->run(); if (! $test->isSuccessful() || $snapshot() !== $before) { throw new RuntimeException('Publicação recusada: testes falharam ou a origem mudou durante a verificação.'); } $validation = sys_get_temp_dir().'/sgc-purchasing-validation-'.bin2hex(random_bytes(8)); mkdir($validation, 0700); $candidate = Release::publish($source, $validation); $probe = new Process([PHP_BINARY, 'scripts/purchasing-probe.php', $validation.'/'.$candidate['archive'], $candidate['manifest_sha256']], dirname(__DIR__), timeout: 30); $probe->mustRun(); if ($snapshot() !== $before) { throw new RuntimeException('A origem mudou durante a prova candidata.'); } // Publish the exact immutable snapshot exercised by the candidate probe. $checked = Release::inspect($validation.'/'.$candidate['archive'], $candidate['manifest_sha256']); $payload = $validation.'/payload'; mkdir($payload, 0700); foreach ($checked['contents'] as $path => $content) { if (! is_dir(dirname($payload.'/'.$path))) { mkdir(dirname($payload.'/'.$path), 0700, true); } file_put_contents($payload.'/'.$path, $content); } $release = Release::publish($payload, $argv[1]); echo json_encode($release + ['tests' => trim($test->getOutput()), 'staged_source_probe' => json_decode($probe->getOutput(), true, 32, JSON_THROW_ON_ERROR)], JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR)."\n"; } catch (Throwable $error) { fwrite(STDERR, $error->getMessage()."\n"); $exitCode = 1; } finally { if ($validation !== null && is_dir($validation)) { $real = realpath($validation); $temporary = str_replace('\\', '/', realpath(sys_get_temp_dir())); if ($real !== false && str_starts_with(str_replace('\\', '/', $real), $temporary.'/sgc-purchasing-validation-')) { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($real, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $file) { if ($file->isDir() && ! $file->isLink()) { rmdir($file->getPathname()); } else { unlink($file->getPathname()); } } rmdir($real); } } } exit($exitCode);