Release scripts: bulletproof test-deploy data preservation + tag/version gate

Local checkpoint - NOT for public release.

Two gaps found reviewing the publish/release scripts:

- deploy-test.ps1: the binary sync (publish -> D:\Dropbox\remsound) used /E with no /MIR,
  so it never DELETES user data - but it could OVERWRITE it if publish\ ever accumulated a
  "user settings and logs" folder. Added /XD/'user settings and logs','recordings','logs',
  'profiles','config' + /XF 'global config.json','remsound.config.json' so the binary sync
  is physically incapable of touching Ed's profiles/logs/config in either direction. Test
  deploys keep ALL of his data current, by construction.

- build-release.ps1: never checked the -Tag against the csproj <Version>. A mismatch ships
  RemSound-<tag>.zip containing a different version's binary, which the in-app updater (it
  downloads by tag name) reads as a perpetual "update available". Now aborts up front if
  tag != csproj <Version> - also catches a forgotten version bump.

The intended split was already correct: test deploy keeps everything; build-release
publishes to a fresh folder, strips pdb, and scans staged files AND the zip for any
profiles/logs/config/recordings, aborting if found.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ednunp
2026-07-12 19:56:34 +01:00
co-authored by Claude Opus 4.8
parent a52f08c188
commit 2a8c608653
2 changed files with 21 additions and 1 deletions
+14
View File
@@ -35,6 +35,20 @@ $distDir = Join-Path $repo 'dist'
$zipPath = Join-Path $distDir "RemSound-$Tag.zip"
$staging = Join-Path ([System.IO.Path]::GetTempPath()) ("remsound-release-" + [guid]::NewGuid().ToString('N'))
# 0z. The -Tag MUST match the csproj <Version>. The in-app updater downloads exactly
# "RemSound-<tag>.zip" and compares the running version to the tag; a mismatch (e.g. tag v5.3 but
# the binary is still 5.2 because the version bump was forgotten) ships a zip whose contents don't
# match its name, which the updater sees as a perpetual "update available". Catch it before any work.
$csprojText = Get-Content -LiteralPath $proj -Raw
$csprojVersion = if ($csprojText -match '<Version>([^<]+)</Version>') { $Matches[1].Trim() } else { '' }
$tagVersion = $Tag.TrimStart('v')
if ($csprojVersion -ne $tagVersion) {
Write-Host "RELEASE ABORTED - tag $Tag ($tagVersion) does not match the csproj <Version> ($csprojVersion)." -ForegroundColor Red
Write-Host "Bump <Version> in RemSound.App.csproj to $tagVersion (and add the About-box changelog entry), or fix the tag, then re-run." -ForegroundColor Red
exit 1
}
Write-Host "Version check: tag $Tag matches csproj <Version> $csprojVersion." -ForegroundColor DarkGray
# 0a. SoundForge drops a .sfk peak file next to every .wav it opens. They're byproducts that must
# never ship (the build only bundles *.wav, so they wouldn't anyway) - clear them from the
# source 'default sounds\' folder so they don't accumulate and clutter the working tree.
+7 -1
View File
@@ -43,7 +43,13 @@ foreach ($loc in $runLocations) {
# Binaries: publish\ already has them from the publish above; copy them to the other location(s).
if (-not $soundOnly -and $loc -ne $publish) {
Write-Host "Deploying program + binaries -> $loc (preserving user settings/logs) ..." -ForegroundColor Cyan
Invoke-Robocopy @($publish, $loc, '/E') # no /MIR: never delete the user's settings/logs/profiles
# /E copies the program + binaries; NO /MIR so we never DELETE the user's data. The /XD
# excludes make the copy incapable of OVERWRITING it either: if publish\ ever accumulated a
# user-data folder (a stray run from there), it must never land on Ed's real Dropbox profiles/
# config/logs. The binary sync only ever carries program files, never user state, both ways.
Invoke-Robocopy @($publish, $loc, '/E',
'/XD', 'user settings and logs', 'recordings', 'logs', 'profiles', 'config',
'/XF', 'global config.json', 'remsound.config.json')
}
# THE point of this script: the whole source 'default sounds' folder, force-copied over THIS
# location's copy, every time. /IS = copy even files robocopy thinks are identical; /IT = copy