* feat(electron): add Linux AppImage releases * ci: cache Linux OpenCode CLI artifacts * fix(ci): await Linux release inventory check * fix(electron): add frameless window controls on Linux desktop Linux AppImages were created without native WM decorations and without in-app controls, leaving users unable to close the window with a mouse. Treat Linux like Windows: frameless BrowserWindow plus the existing WindowsWindowControls header buttons and app-menu entry. macOS keeps hidden title bar with traffic lights unchanged. Shared usesFramelessElectronChrome() helper drives main window, mini chat, header insets, and titlebar controls. Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com> * feat(desktop): add configurable window controls position by OS Add desktopWindowControlsPosition setting (auto/left/right) with OS-aware defaults: Linux left, Windows right. Wire frameless chrome controls in Header, TitlebarLeftControls, and MiniChatLayout, plus a Sessions settings control for Windows and Linux desktop shells. Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com> * fix(desktop): address Linux AppImage release review findings Propagate updater capability errors to the UI, treat missing latest-linux.yml feeds as no-update, stop installed-apps IPC spam on Linux, document FUSE/AppImage limits, add CHANGELOG entry, migrate remaining btriapitsyn URLs, and run Electron Linux unit tests on PRs. Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com> --------- Co-authored-by: jibanez-staticduo <staticduo@gmail.com> Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
75 lines
2.4 KiB
JavaScript
75 lines
2.4 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
|
|
import {
|
|
PRODUCTION_UPDATER_FEED,
|
|
parseLoopbackUpdaterUrl,
|
|
resolveUpdaterFeed,
|
|
} from './updater-feed.mjs';
|
|
|
|
const overrideEnvironment = {
|
|
OPENCHAMBER_E2E: '1',
|
|
OPENCHAMBER_UPDATER_E2E_URL: 'http://127.0.0.1:49152/updates/',
|
|
};
|
|
|
|
test('production updater feed is immutable GitHub configuration', () => {
|
|
assert.equal(Object.isFrozen(PRODUCTION_UPDATER_FEED), true);
|
|
assert.deepEqual(PRODUCTION_UPDATER_FEED, {
|
|
provider: 'github',
|
|
owner: 'openchamber',
|
|
repo: 'openchamber',
|
|
});
|
|
});
|
|
|
|
test('requires the complete E2E environment and embedded build-marker conjunction', () => {
|
|
const cases = [
|
|
{},
|
|
{ environment: overrideEnvironment },
|
|
{ environment: { OPENCHAMBER_E2E: '1' }, testBuild: true },
|
|
{
|
|
environment: { OPENCHAMBER_UPDATER_E2E_URL: overrideEnvironment.OPENCHAMBER_UPDATER_E2E_URL },
|
|
testBuild: true,
|
|
},
|
|
{ environment: overrideEnvironment, testBuild: false },
|
|
];
|
|
for (const input of cases) assert.equal(resolveUpdaterFeed(input), PRODUCTION_UPDATER_FEED);
|
|
});
|
|
|
|
test('accepts only credential-free loopback HTTP(S) URLs', () => {
|
|
assert.equal(parseLoopbackUpdaterUrl('http://127.0.0.1:8080/feed'), 'http://127.0.0.1:8080/feed');
|
|
assert.equal(parseLoopbackUpdaterUrl('https://127.255.0.1/feed/'), 'https://127.255.0.1/feed/');
|
|
assert.equal(parseLoopbackUpdaterUrl('http://[::1]:8080/feed'), 'http://[::1]:8080/feed');
|
|
|
|
for (const value of [
|
|
'http://localhost:8080/feed',
|
|
'http://0.0.0.0:8080/feed',
|
|
'http://192.168.1.5:8080/feed',
|
|
'https://example.com/feed',
|
|
'file:///tmp/feed',
|
|
'ftp://127.0.0.1/feed',
|
|
'http://user:secret@127.0.0.1/feed',
|
|
'http://127.0.0.1/feed?token=secret',
|
|
'http://127.0.0.1/feed#fragment',
|
|
'not-a-url',
|
|
]) assert.equal(parseLoopbackUpdaterUrl(value), null, value);
|
|
});
|
|
|
|
test('uses a generic feed only when every test-only gate is valid', () => {
|
|
assert.deepEqual(resolveUpdaterFeed({
|
|
environment: overrideEnvironment,
|
|
testBuild: true,
|
|
}), {
|
|
provider: 'generic',
|
|
url: 'http://127.0.0.1:49152/updates/',
|
|
});
|
|
});
|
|
|
|
test('invalid URLs fall back to the production feed even with both test gates', () => {
|
|
for (const url of ['https://example.com/feed', 'http://localhost/feed', '']) {
|
|
assert.equal(resolveUpdaterFeed({
|
|
environment: { ...overrideEnvironment, OPENCHAMBER_UPDATER_E2E_URL: url },
|
|
testBuild: true,
|
|
}), PRODUCTION_UPDATER_FEED);
|
|
}
|
|
});
|