From ad8a4d861b1aa3115970367aa499b4770943c356 Mon Sep 17 00:00:00 2001 From: F4ilji Date: Sun, 5 Jul 2026 15:06:14 +0500 Subject: [PATCH] fix(vikon): read version from file and update after core update --- .phpunit.result.cache | 2 +- .../Actions/UpdateCoreAction.php | 22 +++++++++++++++++++ .../Providers/VikonServiceProvider.php | 15 +++++++++---- .../UI/WEB/Controllers/VikonController.php | 14 +++++++++++- config/vikon.php | 2 +- vikon_version.txt | 1 + 6 files changed, 49 insertions(+), 7 deletions(-) diff --git a/.phpunit.result.cache b/.phpunit.result.cache index ef1019d..3f1e7dc 100644 --- a/.phpunit.result.cache +++ b/.phpunit.result.cache @@ -1 +1 @@ -{"version":2,"defects":{"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_replaces_existing_entry":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_creates_new_entry_when_not_exists":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_returns_false_on_path_traversal":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_completed_when_status_is_completed":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_failed_when_status_is_failed":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_timeout_after_max_attempts":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_requests_generation_and_polls_status":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_generation_failure":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_poll_failure":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_restore_after_fail_removes_new_and_restores_old":8,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_module_id":8,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_part":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_part":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_module_id":7},"times":{"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_replaces_existing_entry":0.017,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_creates_new_entry_when_not_exists":0.002,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_returns_false_on_path_traversal":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_completed_when_status_is_completed":0.027,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_failed_when_status_is_failed":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_timeout_after_max_attempts":0.002,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_module_id":0.002,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_part":0.011,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_requests_generation_and_polls_status":0.003,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_generation_failure":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_poll_failure":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_restore_after_fail_removes_new_and_restores_old":0.001,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_requires_authentication":0.047,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_module_id":0.021,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_part":0.008,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_completed_when_status_is_1":0.025,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_failed_when_status_is_negative_1":0}} \ No newline at end of file +{"version":2,"defects":{"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_replaces_existing_entry":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_creates_new_entry_when_not_exists":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_returns_false_on_path_traversal":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_completed_when_status_is_completed":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_failed_when_status_is_failed":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_timeout_after_max_attempts":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_requests_generation_and_polls_status":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_generation_failure":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_poll_failure":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_restore_after_fail_removes_new_and_restores_old":8,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_module_id":8,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_part":8,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_part":7,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_module_id":7},"times":{"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_replaces_existing_entry":0.019,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_creates_new_entry_when_not_exists":0.002,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_atomic_swap_returns_false_on_path_traversal":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_completed_when_status_is_completed":0.027,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_failed_when_status_is_failed":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_timeout_after_max_attempts":0.003,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_module_id":0.006,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_rejects_invalid_part":0.011,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_requests_generation_and_polls_status":0.006,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_generation_failure":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\UpdatePartActionTest::test_throws_on_poll_failure":0.001,"App\\Containers\\VikonIntegration\\Tests\\Unit\\FilesystemTaskTest::test_restore_after_fail_removes_new_and_restores_old":0.002,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_requires_authentication":0.051,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_module_id":0.02,"App\\Containers\\VikonIntegration\\Tests\\Feature\\UpdatePartTest::test_update_part_validates_part":0.01,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_completed_when_status_is_1":0.029,"App\\Containers\\VikonIntegration\\Tests\\Unit\\PollPartStatusTaskTest::test_returns_failed_when_status_is_negative_1":0.001}} \ No newline at end of file diff --git a/app/Containers/VikonIntegration/Actions/UpdateCoreAction.php b/app/Containers/VikonIntegration/Actions/UpdateCoreAction.php index 37ff512..67b336f 100644 --- a/app/Containers/VikonIntegration/Actions/UpdateCoreAction.php +++ b/app/Containers/VikonIntegration/Actions/UpdateCoreAction.php @@ -32,6 +32,9 @@ class UpdateCoreAction File::put($modulePath . '/.vikon', date('Y-m-d H:i:s')); + // Update version file from API + $this->updateVersionFile($accessToken); + Log::info('Vikon: full update complete', ['module' => $config['name']]); return 'Модуль "' . $config['name'] . '" полностью обновлён.'; } @@ -333,4 +336,23 @@ class UpdateCoreAction Log::info('Vikon: cleaned up post-sync', ['removed' => $removed]); } } + + private function updateVersionFile(string $accessToken): void + { + try { + $response = $this->http->getWithToken('pull_updates/assist/getUpdateVersionJson', $accessToken); + $body = $response->json(); + $latestVersion = $body['version'] ?? null; + + if ($latestVersion) { + $versionFile = config('vikon.current_version_file'); + if ($versionFile) { + file_put_contents($versionFile, $latestVersion); + Log::info('Vikon: version updated', ['version' => $latestVersion]); + } + } + } catch (\Throwable $e) { + Log::warning('Vikon: failed to update version file', ['error' => $e->getMessage()]); + } + } } diff --git a/app/Containers/VikonIntegration/Providers/VikonServiceProvider.php b/app/Containers/VikonIntegration/Providers/VikonServiceProvider.php index 23c900d..f7d8307 100644 --- a/app/Containers/VikonIntegration/Providers/VikonServiceProvider.php +++ b/app/Containers/VikonIntegration/Providers/VikonServiceProvider.php @@ -69,10 +69,17 @@ class VikonServiceProvider extends ServiceProvider publicPath: public_path(), )); - $this->app->singleton(CheckVersionAction::class, fn ($app) => new CheckVersionAction( - http: $app->make(HttpTask::class), - currentVersion: config('vikon.current_version', '1.0.0'), - )); + $this->app->singleton(CheckVersionAction::class, function ($app) { + $versionFile = config('vikon.current_version_file'); + $version = '1.0.0'; + if ($versionFile && file_exists($versionFile)) { + $version = trim(file_get_contents($versionFile)) ?: '1.0.0'; + } + return new CheckVersionAction( + http: $app->make(HttpTask::class), + currentVersion: $version, + ); + }); $this->app->singleton(UpdateCoreAction::class, fn ($app) => new UpdateCoreAction( http: $app->make(HttpTask::class), diff --git a/app/Containers/VikonIntegration/UI/WEB/Controllers/VikonController.php b/app/Containers/VikonIntegration/UI/WEB/Controllers/VikonController.php index ace3afd..b539126 100644 --- a/app/Containers/VikonIntegration/UI/WEB/Controllers/VikonController.php +++ b/app/Containers/VikonIntegration/UI/WEB/Controllers/VikonController.php @@ -45,7 +45,7 @@ class VikonController extends Controller return inertia()->render('Dashboard/VikonUpdates/Index', [ 'is_authenticated' => $isAuth, - 'current_version' => config('vikon.current_version'), + 'current_version' => $this->getCurrentVersion(), 'modules' => config('vikon.modules'), 'parts' => $parts, 'vikon_api_domain' => config('vikon.api_domain'), @@ -220,4 +220,16 @@ class VikonController extends Controller return response()->json(['url' => $url]); } + + private function getCurrentVersion(): string + { + $versionFile = config('vikon.current_version_file'); + if ($versionFile && file_exists($versionFile)) { + $version = trim(file_get_contents($versionFile)); + if ($version !== '') { + return $version; + } + } + return '1.0.0'; + } } diff --git a/config/vikon.php b/config/vikon.php index 3941101..ff0c250 100644 --- a/config/vikon.php +++ b/config/vikon.php @@ -10,7 +10,7 @@ return [ 'auth_domain' => env('VIKON_AUTH_DOMAIN', 'https://auth.db-nica.ru/'), 'filemanager_domain' => env('VIKON_FILEMANAGER_DOMAIN', 'https://file.db-nica.ru/'), - 'current_version' => env('VIKON_CURRENT_VERSION', '1.0.0'), + 'current_version_file' => env('VIKON_VERSION_FILE', base_path('vikon_version.txt')), 'http_timeout' => env('VIKON_HTTP_TIMEOUT', 60), 'http_retries' => env('VIKON_HTTP_RETRIES', 3), diff --git a/vikon_version.txt b/vikon_version.txt index e69de29..d9c884f 100644 --- a/vikon_version.txt +++ b/vikon_version.txt @@ -0,0 +1 @@ +5.90.8.1 \ No newline at end of file