feat(v20): 版本纪律 + 发版自动化(对齐「做好版本功能 + GitHub 同步资产」)
## 一、版本功能(防新旧混用) 1. **单一版本源 + 构建注入**:根 package.json 的 version、git sha、构建时间经 esbuild `--define` 注入 agent;`system.info.build` 新增 `version/commit/built_at`(原有 `hash` 指纹不变)。 开发态用 typeof 探测(未注入也不崩)。 2. **握手携带版本**:`auth_ok` 新增可选字段 `agent_version` / `build` / `protocol`(只增不减 → 旧控制端忽略即可)。 3. **能力级兼容比对**:新增纯函数 `capabilityDiff(local, remote)` —— - `missingOnRemote`:本地有远端没有 → **远端较旧**,提示更新被控端 - `unknownLocally`:远端有本地没有 → **本控制端较旧**(不影响既有功能) 控制端不比版本号而比**能力集合**:版本号可能相同而内容不同,能力集合不会骗人。 4. **CLI 体检**:`nodeagent info` / `connect` 直接显示被控端版本与能力对齐情况, 把"调用时才炸"变成一句人话提示。 ## 二、发版自动化(GitHub 资产同步) `pnpm release <x.y.z|patch|minor|major>`:前置检查(干净/在 main/与远端同步)→ 改 7 个 package.json → 构建+打包 → 生成资产 → 提交打标签推送 → `gh release create` 上传。 - 资产:`agent.mjs`(**自更新载荷**)、`nodeagent-win-x64.zip`(人工安装包)、 `latest.json`(version/commit/能力数 + 两个资产的 url 与 sha256)、`SHA256SUMS` - `--dry-run` 无副作用演练;`--no-publish` 只到本地标签 - 能力数从 dist 动态取(避免写死漂移);刻意排除 `.github/`(缺 workflow 权限推不了) ## 三、兼容性契约文档 新增 `docs/VERSIONING.md`:semver 各位的含义、**只增不改**六条硬规则、 升级顺序建议(**先被控端**:新被控端向后兼容旧 CLI)、两条更新路径、发版流程、排查手册。 ## 验证 - 单测 147 → **149**(新增 capabilityDiff 用例:远端过旧 / 本机过旧 / 完全一致 / 真实清单自比无差异) - e2e 28 全绿;`node scripts/release.mjs 1.0.0 --dry-run` 演练通过且工作区无副作用
This commit is contained in:
1 parent
aa72241080
commit
cedc46d090
20 files changed
+1262
-17
No files matched your search
@@ -0,0 +1,110 @@
|
||||
@echo off
|
||||
REM ============================================================================
|
||||
REM nodeagent - one-click installer launcher (Windows)
|
||||
REM
|
||||
REM Double-click this file. It will:
|
||||
REM 1) self-elevate to Administrator (UAC prompt) if not already elevated
|
||||
REM 2) make sure a pre-shared key exists in PSK.txt (generate one if absent)
|
||||
REM 3) run install.ps1, which registers the scheduled task, opens the
|
||||
REM firewall and starts the agent
|
||||
REM
|
||||
REM Usage: install.cmd [port]
|
||||
REM port defaults to 8765. Pass a port only when the default is taken.
|
||||
REM
|
||||
REM IMPORTANT - why this file is pure ASCII:
|
||||
REM The CMD.exe code page (936/GBK on Chinese Windows) can NOT round-trip
|
||||
REM UTF-8 Chinese reliably. Any non-ASCII byte here risks mojibake or a
|
||||
REM broken command. All Chinese-facing text is delegated to install.ps1,
|
||||
REM which is saved as UTF-8 **with BOM** so Windows PowerShell 5.1 reads
|
||||
REM it correctly. Keep this launcher ASCII-only.
|
||||
REM
|
||||
REM NOTE - install.ps1 MUST keep its UTF-8 BOM. PowerShell 5.1 parses
|
||||
REM BOM-less .ps1 as ANSI/GBK, and the Chinese comments then break the
|
||||
REM string boundaries -> a cascade of bogus syntax errors.
|
||||
REM ============================================================================
|
||||
setlocal EnableExtensions
|
||||
|
||||
set "HERE=%~dp0"
|
||||
set "PS1=%HERE%install.ps1"
|
||||
set "PSKFILE=%HERE%PSK.txt"
|
||||
set "PORT=%~1"
|
||||
if not defined PORT set "PORT=8765"
|
||||
|
||||
if not exist "%PS1%" (
|
||||
echo [x] install.ps1 not found next to this file.
|
||||
echo Folder: "%HERE%"
|
||||
echo Keep install.ps1, node.exe, agent.mjs and this launcher together.
|
||||
if not defined CI pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM --- 1) elevate to Administrator -------------------------------------------
|
||||
REM fltmc is used instead of `net session` because the latter depends on the
|
||||
REM Server service, which is disabled on some builds - that would make an
|
||||
REM already-elevated shell look unelevated and trigger a pointless UAC loop.
|
||||
fltmc >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo [*] Requesting Administrator rights...
|
||||
echo A new window will open. Continue there; this one closes by itself.
|
||||
REM Start-Process re-launches this .cmd elevated. %PORT% (already resolved to
|
||||
REM its default) is forwarded so "install.cmd 18770" survives the elevation.
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
|
||||
"Start-Process -FilePath '%~f0' -ArgumentList '%PORT%' -Verb RunAs" >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo [x] Elevation was declined - cannot register a scheduled task.
|
||||
if not defined CI pause
|
||||
exit /b 1
|
||||
)
|
||||
exit /b 0
|
||||
)
|
||||
|
||||
REM --- 2) make sure the pre-shared key exists ---------------------------------
|
||||
set "PSK="
|
||||
if exist "%PSKFILE%" (
|
||||
REM Read + Trim in one shot: a stray CR from CRLF or an editor-added trailing
|
||||
REM space would otherwise end up inside -Key and break authentication.
|
||||
for /f "delims=" %%K in ('powershell -NoProfile -ExecutionPolicy Bypass -Command ^
|
||||
"if (Test-Path -LiteralPath '%PSKFILE%') { (Get-Content -LiteralPath '%PSKFILE%' -Raw).Trim() }"') do set "PSK=%%K"
|
||||
)
|
||||
|
||||
if not defined PSK (
|
||||
echo [*] No usable PSK.txt found - generating a new pre-shared key...
|
||||
REM 32 random bytes via .NET, hex-encoded to 64 chars.
|
||||
for /f "delims=" %%K in ('powershell -NoProfile -ExecutionPolicy Bypass -Command ^
|
||||
"$b=New-Object byte[] 32; [System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($b); ($b ^| ForEach-Object { $_.ToString('x2') }) -join ''"') do set "PSK=%%K"
|
||||
|
||||
if not defined PSK (
|
||||
echo [x] Failed to generate a key. Aborting.
|
||||
if not defined CI pause
|
||||
exit /b 1
|
||||
)
|
||||
REM Plain hex, no BOM: the file is read with `set /p` / Get-Content, and a
|
||||
REM leading U+FEFF would corrupt the first byte of the key.
|
||||
>"%PSKFILE%" echo %PSK%
|
||||
echo [+] New key written to "%PSKFILE%"
|
||||
) else (
|
||||
echo [+] Using key from PSK.txt
|
||||
)
|
||||
|
||||
REM --- 3) install -------------------------------------------------------------
|
||||
echo.
|
||||
echo [*] Installing nodeagent ^(node: %COMPUTERNAME%, port %PORT%, input control ON^)...
|
||||
echo.
|
||||
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File "%PS1%" -NodeId "%COMPUTERNAME%" -Key "%PSK%" -AllowInput -Port %PORT%
|
||||
set "RC=%ERRORLEVEL%"
|
||||
|
||||
echo.
|
||||
if "%RC%"=="0" (
|
||||
echo [+] Done. The agent now starts automatically at every logon.
|
||||
echo To manage it later, double-click control.cmd in this folder.
|
||||
) else (
|
||||
echo [x] install.ps1 exited with code %RC%.
|
||||
echo If the error mentions a missing file, re-extract the whole package.
|
||||
echo If Windows Firewall or a security suite blocked something, allow it and retry.
|
||||
)
|
||||
echo.
|
||||
REM Keep the window open so the user can read the output. CI sets CI=true,
|
||||
REM where `pause` would hang forever waiting for a keypress.
|
||||
if not defined CI pause
|
||||
exit /b %RC%
|
||||
Reference in new issue
Block a user