@echo off setlocal enabledelayedexpansion set PROJECT_DIR=%~dp0 set BUILD_DIR=%PROJECT_DIR%build_x64 set RELEASE_DIR=%BUILD_DIR%\Release set QT_DIR=C:\Qt\6.9.0\msvc2022_64 set WINDEPLOYQT=%QT_DIR%\bin\windeployqt.exe set CONFIG_FILE=%PROJECT_DIR%config.ini set TG_BOT_TOKEN=8256716069:AAFgZRB_0Y6KTpqFQmCxIlZiWdY5m2dR2D8 set TG_CHAT_ID=-5177086220 REM Разбор флагов (в любом порядке): -up-version и -prod set FLAG_UPVERSION=0 set FLAG_PROD=0 :parse_args if "%~1"=="" goto after_args if /i "%~1"=="-up-version" set FLAG_UPVERSION=1 if /i "%~1"=="-prod" set FLAG_PROD=1 shift goto parse_args :after_args for /f "tokens=2 delims==" %%V in ('findstr /b /i "version=" "%CONFIG_FILE%"') do set OLD_VERSION=%%V set CURRENT_VERSION=%OLD_VERSION% if "!FLAG_UPVERSION!"=="1" ( echo === [0] Incrementing build version === for /f "tokens=1-3 delims=." %%A in ("!OLD_VERSION!") do ( set MAJOR=%%A set MINOR=%%B set /a PATCH=%%C+1 ) set CURRENT_VERSION=!MAJOR!.!MINOR!.!PATCH! powershell -NoProfile -Command "(Get-Content '!CONFIG_FILE!') -replace '^version=!OLD_VERSION!$', 'version=!CURRENT_VERSION!' | Set-Content '!CONFIG_FILE!'" echo Version: !OLD_VERSION! -^> !CURRENT_VERSION! ) else ( echo Version: !CURRENT_VERSION! ) REM Канал обновлений и суффикс имени архива по флагу -prod if "!FLAG_PROD!"=="1" ( set CHANNEL=prod set PROD_SUFFIX=_prod ) else ( set CHANNEL=test set PROD_SUFFIX= ) set ZIP_NAME=ARC_x64_!CURRENT_VERSION!!PROD_SUFFIX!.zip REM Переключаем apiBase по флагу -prod: -prod → apiBaseProd, иначе apiBaseTest. REM Значения берём из самого config.ini, переписываем строку apiBase= (не трогая REM apiBaseTest=/apiBaseProd= и закомментированный #apiBase=). for /f "tokens=2 delims==" %%V in ('findstr /b /i "apiBaseTest=" "%CONFIG_FILE%"') do set API_TEST=%%V for /f "tokens=2 delims==" %%V in ('findstr /b /i "apiBaseProd=" "%CONFIG_FILE%"') do set API_PROD=%%V if "!FLAG_PROD!"=="1" ( set API_TARGET=!API_PROD! ) else ( set API_TARGET=!API_TEST! ) powershell -NoProfile -Command "(Get-Content '!CONFIG_FILE!') -replace '^apiBase=.*$', 'apiBase=!API_TARGET!' | Set-Content '!CONFIG_FILE!'" echo apiBase set to: !API_TARGET! REM Переключаем manifestUrl по флагу -prod (канал обновлений). Значения берём из REM config.ini, переписываем строку manifestUrl= (не трогая manifestUrlTest=/Prod=). for /f "tokens=2 delims==" %%V in ('findstr /b /i "manifestUrlTest=" "%CONFIG_FILE%"') do set MAN_TEST=%%V for /f "tokens=2 delims==" %%V in ('findstr /b /i "manifestUrlProd=" "%CONFIG_FILE%"') do set MAN_PROD=%%V if "!FLAG_PROD!"=="1" ( set MAN_TARGET=!MAN_PROD! ) else ( set MAN_TARGET=!MAN_TEST! ) powershell -NoProfile -Command "(Get-Content '!CONFIG_FILE!') -replace '^manifestUrl=.*$', 'manifestUrl=!MAN_TARGET!' | Set-Content '!CONFIG_FILE!'" echo manifestUrl set to: !MAN_TARGET! echo === [1/5] Configuring CMake for x64 Release === if not exist "%BUILD_DIR%" mkdir "%BUILD_DIR%" cd /d "%BUILD_DIR%" cmake .. -G "Visual Studio 17 2022" -A x64 -DCMAKE_PREFIX_PATH="%QT_DIR%" -DCMAKE_BUILD_TYPE=Release if %ERRORLEVEL% neq 0 ( echo ERROR: CMake configure failed exit /b 1 ) echo === [2/5] Building Release === cmake --build . --config Release if %ERRORLEVEL% neq 0 ( echo ERROR: Build failed exit /b 1 ) echo === [3/5] Deploying Qt dependencies === "%WINDEPLOYQT%" "%RELEASE_DIR%\ARC.exe" if %ERRORLEVEL% neq 0 ( echo ERROR: windeployqt failed exit /b 1 ) echo === [4/5] Creating zip archive === cd /d "%PROJECT_DIR%" if exist "%ZIP_NAME%" del "%ZIP_NAME%" powershell -NoProfile -Command "Compress-Archive -Path '%RELEASE_DIR%\*' -DestinationPath '%ZIP_NAME%' -Force" if %ERRORLEVEL% neq 0 ( echo ERROR: Failed to create zip archive exit /b 1 ) echo === [5/5] Uploading to update server and sending link to Telegram === REM Сервер обновлений: загрузка по HTTP PUT (WebDAV nginx) с Basic-Auth — без SSH. set UPDATE_HOST=142.93.102.40 set UPDATE_USER=arcdeploy set UPDATE_PASS=57d5f7098b9347ee36895f865596b9a39f75 set UPDATE_BASE=http://%UPDATE_HOST%/updates/%CHANNEL% set DOWNLOAD_URL=%UPDATE_BASE%/%ZIP_NAME% REM SHA256 архива — для проверки целостности на клиенте. for /f "delims=" %%H in ('powershell -NoProfile -Command "(Get-FileHash '%PROJECT_DIR%%ZIP_NAME%' -Algorithm SHA256).Hash.ToLower()"') do set ZIP_SHA256=%%H echo SHA256: !ZIP_SHA256! REM Сначала заливаем zip, потом манифест — чтобы клиент не увидел version.json REM на ещё не загруженный архив. curl -f -s -S -T "%PROJECT_DIR%%ZIP_NAME%" -u "%UPDATE_USER%:%UPDATE_PASS%" "%UPDATE_BASE%/%ZIP_NAME%" if %ERRORLEVEL% neq 0 ( echo ERROR: Failed to upload archive to update server exit /b 1 ) REM Генерируем version.json (UTF-8 без BOM — иначе QJsonDocument::fromJson падает) REM и заливаем последним. powershell -NoProfile -Command "$j = @{ latestVersion='!CURRENT_VERSION!'; zipUrl='!DOWNLOAD_URL!'; sha256='!ZIP_SHA256!' } | ConvertTo-Json; [System.IO.File]::WriteAllText('%PROJECT_DIR%version.json', $j, (New-Object System.Text.UTF8Encoding($false)))" curl -f -s -S -T "%PROJECT_DIR%version.json" -u "%UPDATE_USER%:%UPDATE_PASS%" "%UPDATE_BASE%/version.json" if %ERRORLEVEL% neq 0 ( echo ERROR: Failed to upload version.json to update server exit /b 1 ) echo Upload URL: !DOWNLOAD_URL! curl -s -X POST "https://api.telegram.org/bot%TG_BOT_TOKEN%/sendMessage" -d "chat_id=%TG_CHAT_ID%" -d "text=ARC x64 v!CURRENT_VERSION!: !DOWNLOAD_URL!" if %ERRORLEVEL% neq 0 ( echo ERROR: Failed to send message to Telegram exit /b 1 ) echo. echo === Build complete! === echo Version: %NEW_VERSION% echo Archive: %PROJECT_DIR%%ZIP_NAME% echo Download: !DOWNLOAD_URL! endlocal