mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-04 02:31:36 +00:00
feat(desktop): enhance packaging workflow and add smoke test for desktop app
This commit is contained in:
parent
558d7c3d82
commit
ed83fd3e42
3 changed files with 86 additions and 13 deletions
9
.github/workflows/desktop-packaging.yml
vendored
9
.github/workflows/desktop-packaging.yml
vendored
|
|
@ -11,13 +11,15 @@ permissions: {}
|
|||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
package:
|
||||
name: Build ${{ matrix.label }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 90
|
||||
permissions:
|
||||
contents: read
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
|
@ -63,6 +65,11 @@ jobs:
|
|||
env:
|
||||
CSC_IDENTITY_AUTO_DISCOVERY: 'false'
|
||||
|
||||
- name: Smoke test unpacked desktop bundle
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: node scripts/smoke-unpacked.mjs
|
||||
working-directory: gitnexus-desktop
|
||||
|
||||
- name: Build desktop package
|
||||
run: ${{ matrix.command }}
|
||||
working-directory: gitnexus-desktop
|
||||
|
|
|
|||
|
|
@ -272,14 +272,43 @@ const runNpm = (args, cwd) => {
|
|||
}
|
||||
};
|
||||
|
||||
const overlayDirectoryContents = (sourceDirectory, destinationDirectory) => {
|
||||
const overlayDependencyPackages = (sourceDirectory, destinationDirectory, dependencyMap) => {
|
||||
mkdirSync(destinationDirectory, { recursive: true });
|
||||
|
||||
for (const entry of readdirSync(sourceDirectory, { withFileTypes: true })) {
|
||||
cpSync(path.join(sourceDirectory, entry.name), path.join(destinationDirectory, entry.name), {
|
||||
force: true,
|
||||
recursive: true,
|
||||
});
|
||||
for (const packageName of Object.keys(dependencyMap)) {
|
||||
const sourcePath = path.join(sourceDirectory, ...packageName.split('/'));
|
||||
const destinationPath = path.join(destinationDirectory, ...packageName.split('/'));
|
||||
|
||||
if (!existsSync(sourcePath)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (existsSync(destinationPath)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mkdirSync(path.dirname(destinationPath), { recursive: true });
|
||||
|
||||
try {
|
||||
cpSync(sourcePath, destinationPath, {
|
||||
dereference: true,
|
||||
force: true,
|
||||
recursive: true,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorCode = error?.code;
|
||||
const isLockedPathError =
|
||||
(errorCode === 'EPIPE' || errorCode === 'EBUSY' || errorCode === 'EPERM') &&
|
||||
existsSync(destinationPath);
|
||||
|
||||
if (!isLockedPathError) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
console.warn(
|
||||
`[gitnexus-desktop] Skipping locked dependency path during repair: ${destinationPath}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -313,9 +342,10 @@ const repairGitNexusPackages = (dependencyMap, label) => {
|
|||
runNpm(['install', '--no-package-lock'], repairDirectory);
|
||||
|
||||
replaceDirectGitNexusPackages(dependencyMap);
|
||||
overlayDirectoryContents(
|
||||
overlayDependencyPackages(
|
||||
path.join(repairDirectory, 'node_modules'),
|
||||
path.join(gitnexusRoot, 'node_modules'),
|
||||
dependencyMap,
|
||||
);
|
||||
} finally {
|
||||
rmSync(repairDirectory, { force: true, recursive: true });
|
||||
|
|
@ -331,6 +361,20 @@ const runCommand = (command, args) => {
|
|||
});
|
||||
};
|
||||
|
||||
const getPosixCommandLine = (pid) => {
|
||||
if (!pid) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const lookup = runCommand('ps', ['-p', String(pid), '-o', 'args=']);
|
||||
|
||||
if (lookup.status !== 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return lookup.stdout.trim();
|
||||
};
|
||||
|
||||
const findPortOwner = (port) => {
|
||||
if (process.platform === 'win32') {
|
||||
const lookup = runCommand('powershell.exe', [
|
||||
|
|
@ -357,7 +401,7 @@ const findPortOwner = (port) => {
|
|||
return JSON.parse(lookup.stdout.trim());
|
||||
}
|
||||
|
||||
const lookup = runCommand('lsof', ['-nP', `-iTCP:${port}`, '-sTCP:LISTEN', '-Fpcn']);
|
||||
const lookup = runCommand('lsof', ['-nP', `-iTCP:${port}`, '-sTCP:LISTEN', '-Fpc']);
|
||||
|
||||
if (lookup.status !== 0 || !lookup.stdout.trim()) {
|
||||
return null;
|
||||
|
|
@ -370,11 +414,11 @@ const findPortOwner = (port) => {
|
|||
owner.pid = Number.parseInt(line.slice(1), 10);
|
||||
} else if (line.startsWith('c')) {
|
||||
owner.name = line.slice(1);
|
||||
} else if (line.startsWith('n')) {
|
||||
owner.commandLine = line.slice(1);
|
||||
}
|
||||
}
|
||||
|
||||
owner.commandLine = getPosixCommandLine(owner.pid);
|
||||
|
||||
return owner.pid ? owner : null;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ const GITNEXUS_SERVER_READY_TIMEOUT_MS = 30_000;
|
|||
const GITNEXUS_WEB_READY_TIMEOUT_MS = 60_000;
|
||||
const GITNEXUS_WEB_READY_POLL_MS = 500;
|
||||
const PACKAGED_WEB_SERVER_HOST = '127.0.0.1';
|
||||
const IS_DESKTOP_SMOKE_TEST = process.env.GITNEXUS_DESKTOP_SMOKE_TEST === '1';
|
||||
|
||||
const MIME_TYPES: Record<string, string> = {
|
||||
'.css': 'text/css; charset=utf-8',
|
||||
|
|
@ -409,9 +410,24 @@ const sendStaticResponse = (assetPath: string | null, response: ServerResponse):
|
|||
createReadStream(assetPath).pipe(response);
|
||||
};
|
||||
|
||||
const getRequestedPath = (requestUrl: string): string | null => {
|
||||
try {
|
||||
return decodeURIComponent(new URL(requestUrl, 'http://127.0.0.1').pathname);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const handlePackagedWebRequest = (request: IncomingMessage, response: ServerResponse): void => {
|
||||
const requestUrl = request.url ?? '/';
|
||||
const requestedPath = decodeURIComponent(new URL(requestUrl, 'http://127.0.0.1').pathname);
|
||||
const requestedPath = getRequestedPath(requestUrl);
|
||||
|
||||
if (!requestedPath) {
|
||||
response.writeHead(400, { 'Content-Type': 'text/plain; charset=utf-8' });
|
||||
response.end('Bad request');
|
||||
return;
|
||||
}
|
||||
|
||||
sendStaticResponse(normalizeStaticPath(GITNEXUS_WEB_PACKAGED_DIR, requestedPath), response);
|
||||
};
|
||||
|
||||
|
|
@ -580,7 +596,7 @@ const loadShellRenderer = async (window: BrowserWindow): Promise<void> => {
|
|||
return;
|
||||
}
|
||||
|
||||
const rendererEntry = path.join(__dirname, '../renderer/src/renderer/index.html');
|
||||
const rendererEntry = path.join(__dirname, '../renderer/index.html');
|
||||
console.info(`[gitnexus-desktop] Loading shell renderer file: ${rendererEntry}`);
|
||||
await window.loadFile(rendererEntry);
|
||||
};
|
||||
|
|
@ -732,6 +748,12 @@ async function createWindow(): Promise<void> {
|
|||
|
||||
if (!window.isDestroyed()) {
|
||||
window.show();
|
||||
|
||||
if (IS_DESKTOP_SMOKE_TEST) {
|
||||
setTimeout(() => {
|
||||
app.quit();
|
||||
}, 1_000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue