fix(release): harden updater status and cutter layout
Windows CI / verify (push) Failing after 3m37s

Ignore malformed update notifications that do not carry a version, preventing unusable release prompts in installed builds.

Keep the loaded cutter workspace free of the source selector and give cutter export selects an explicit non-repeating indicator after workspace styling.

Add regression coverage, bump the patch release to 1.0.10, and update public installation documentation.
This commit is contained in:
Sucukdeluxe
2026-08-12 21:30:08 +02:00
parent 7d4ba91543
commit aa28a0b870
14 changed files with 137 additions and 20 deletions
+1 -1
View File
@@ -93,7 +93,7 @@ if (process.platform === 'win32') {
sourcePath: electronSourceExecutable,
destinationPath: resolve(rootDirectory, 'node_modules', 'electron', 'dist', 'Twitch VOD Manager.exe'),
iconPath: resolve(rootDirectory, 'build', 'icon.ico'),
version: '1.0.9',
version: '1.0.10',
});
}
+2
View File
@@ -132,6 +132,7 @@
"src/renderer-command-palette.ts",
"src/renderer-cutter.ts",
"src/renderer-cutter.production-path.test.ts",
"src/cutter-workspace-styles.production-path.test.ts",
"src/renderer-globals.d.ts",
"src/renderer-locale-de.ts",
"src/renderer-locale-en.ts",
@@ -146,6 +147,7 @@
"src/renderer-streamers.ts",
"src/renderer-texts.ts",
"src/renderer-updates.ts",
"src/renderer-updates.production-path.test.ts",
"src/renderer-vod-hover.ts",
"src/renderer.ts",
"src/styles.css",
+29 -1
View File
@@ -200,6 +200,34 @@ async function run() {
await win.setViewportSize({ width: 1440, height: 900 });
await win.emulateMedia({ reducedMotion: 'reduce' });
await win.evaluate(() => window.showTab('cutter'));
await win.evaluate(() => {
document.getElementById('cutterWorkspace').classList.add('shown');
document.getElementById('cutterExportProfile').disabled = false;
});
await win.locator('#cutterExportProfile').waitFor({ state: 'visible' });
const cutterExportProfileBox = await win.locator('#cutterExportProfile').boundingBox();
if (!cutterExportProfileBox) throw new Error('Export profile is not visible');
await win.mouse.move(cutterExportProfileBox.x + cutterExportProfileBox.width / 2, cutterExportProfileBox.y + cutterExportProfileBox.height / 2);
const cutterExportProfilePresentation = await win.evaluate(() => {
const style = getComputedStyle(document.getElementById('cutterExportProfile'));
return {
backgroundImage: style.backgroundImage,
backgroundRepeat: style.backgroundRepeat,
backgroundPosition: style.backgroundPosition,
sourceDisplay: getComputedStyle(document.querySelector('.cutter-source-bar')).display,
};
});
check(
cutterExportProfilePresentation.backgroundImage !== 'none'
&& cutterExportProfilePresentation.backgroundRepeat === 'no-repeat'
&& cutterExportProfilePresentation.backgroundPosition.includes('8px')
&& cutterExportProfilePresentation.sourceDisplay === 'none',
`Export profile indicator is tiled or misplaced: ${JSON.stringify(cutterExportProfilePresentation)}`
);
await win.evaluate(() => {
document.getElementById('cutterWorkspace').classList.remove('shown');
document.getElementById('cutterExportProfile').disabled = true;
});
const additionalContainerCapabilities = await Promise.all(Object.entries(additionalContainerFiles).map(async ([extension, filePath]) => ({
extension,
capability: await createCutterCapability(win, filePath),
@@ -316,7 +344,7 @@ async function run() {
`Disabled empty-player volume control still expands on hover: ${JSON.stringify({ emptyVolumeBefore, emptyVolumeAfter })}`
);
if (process.env.TWITCH_VOD_MANAGER_CUTTER_EMPTY_ONLY === '1') {
console.log(JSON.stringify({ failures, runtimeIssues, emptyLayout, emptyFullscreenLayout, emptyVolumeBefore, emptyVolumeAfter }, null, 2));
console.log(JSON.stringify({ failures, runtimeIssues, cutterExportProfilePresentation, emptyLayout, emptyFullscreenLayout, emptyVolumeBefore, emptyVolumeAfter }, null, 2));
if (failures.length > 0) process.exitCode = 1;
return;
}
+4 -4
View File
@@ -15,9 +15,9 @@ function check(condition, message) {
if (!condition) failures.push(message);
}
check(packageJson.version === '1.0.9', `package version is ${packageJson.version}`);
check(packageLock.version === '1.0.9', `lockfile version is ${packageLock.version}`);
check(packageLock.packages?.['']?.version === '1.0.9', `lockfile root package version is ${packageLock.packages?.['']?.version}`);
check(packageJson.version === '1.0.10', `package version is ${packageJson.version}`);
check(packageLock.version === '1.0.10', `lockfile version is ${packageLock.version}`);
check(packageLock.packages?.['']?.version === '1.0.10', `lockfile root package version is ${packageLock.packages?.['']?.version}`);
check(packageJson.build?.appId === 'io.github.sucukdeluxe.twitch-vod-manager', `appId is ${packageJson.build?.appId}`);
check(packageJson.build?.publish?.provider === 'generic', `publish provider is ${packageJson.build?.publish?.provider}`);
check(packageJson.build?.publish?.url === 'https://github.com/Sucukdeluxe/Twitch-VOD-Manager/releases/latest/download/', `publish URL is ${packageJson.build?.publish?.url}`);
@@ -62,7 +62,7 @@ check(mainSource.includes('GITHUB_RELEASES_DOWNLOAD_BASE_URL'), 'GitHub releases
check(mainSource.includes('https://api.github.com/repos/Sucukdeluxe/Twitch-VOD-Manager/releases/latest'), 'GitHub latest release API URL is missing');
check(mainSource.includes('https://github.com/Sucukdeluxe/Twitch-VOD-Manager/releases/download'), 'GitHub release download URL is missing');
check(!/storyboards\/\d{8,12}(?:-|\/)/.test(mainSource), 'numeric Twitch VOD example remains in the public source');
check(indexSource.includes('Version: v1.0.9'), 'initial version label is not 1.0.9');
check(indexSource.includes('Version: v1.0.10'), 'initial version label is not 1.0.10');
check(!indexSource.includes('Version: v4.1.13'), 'legacy version label is still present');
check(fs.existsSync(manifestPath), 'public release manifest is missing');