This commit is contained in:
NuklearRabbit
2026-07-24 20:29:23 +02:00
commit 66060348da
107 changed files with 14771 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import preflightModule from '../src/main/preflight-service.cjs';
const { PreflightService, summarize, check } = preflightModule;
test('only required failed checks block readiness', () => {
const summary = summarize([
check('required-pass', 'Required pass', 'pass', 'ok', { required: true }),
check('optional-warning', 'Optional warning', 'warning', 'notice'),
check('optional-fail', 'Optional fail', 'fail', 'not blocking'),
check('required-fail', 'Required fail', 'fail', 'blocked', { required: true })
]);
assert.equal(summary.ready, false);
assert.deepEqual(summary.blocking, ['required-fail']);
assert.equal(summary.counts.warning, 1);
});
test('system preflight can pass before credentials are entered', async (t) => {
const root = await mkdtemp(path.join(os.tmpdir(), 'forgeflow-preflight-system-'));
t.after(() => rm(root, { recursive: true, force: true }));
const service = new PreflightService({
store: { data: { gitea: { baseUrl: '' } }, getToken: () => '' },
git: { isAvailable: async () => ({ available: true, version: 'git version test' }) },
gitea: {}, deployments: {},
diagnostics: { logDirectory: path.join(root, 'diagnostics'), info: async () => {} },
userDataPath: path.join(root, 'data'),
secureStorageAvailable: () => true
});
service.gitIdentity = async () => ({ name: 'Jens', email: 'jens@example.test' });
const result = await service.runSystem({ roots: [root] });
assert.equal(result.summary.ready, true);
assert.equal(result.checks.find((item) => item.id === 'gitea.connection').status, 'warning');
assert.equal(result.checks.find((item) => item.id === 'storage.credentials').status, 'pass');
});
test('deployment preflight verifies exact Git, workflow, Actions and server prerequisites', async (t) => {
const root = await mkdtemp(path.join(os.tmpdir(), 'forgeflow-preflight-deploy-'));
t.after(() => rm(root, { recursive: true, force: true }));
await mkdir(path.join(root, '.gitea', 'workflows'), { recursive: true });
await writeFile(path.join(root, '.gitea', 'workflows', 'deploy.yml'), 'name: deploy\n');
await writeFile(path.join(root, '.gitea', 'workflows', 'rollback.yml'), 'name: rollback\n');
const sha = 'a'.repeat(40);
const profile = { id: 'production', name: 'Production', environment: 'production', branch: 'main', workflowFile: 'deploy.yml', rollbackWorkflowFile: 'rollback.yml', statusUrl: 'https://app.example.test/status', healthcheckUrl: 'https://app.example.test/health' };
const service = new PreflightService({
store: { getDeploymentProfile: () => profile },
git: {
status: async () => ({ root, head: sha, clean: true, counts: { changed: 0 }, branch: { head: 'main', upstream: 'origin/main', ahead: 0, behind: 0 } }),
verifyCommitOnRemoteBranch: async () => true
},
gitea: { repositoryFileExists: async () => true, listWorkflowRuns: async () => ({ runs: [] }) },
deployments: {
readStatusEndpoint: async () => ({ configured: true, reachable: true, ok: true, liveSha: sha, status: 200 }),
checkHealth: async () => ({ configured: true, healthy: true, status: 200, latencyMs: 12 })
},
diagnostics: { info: async () => {} }, userDataPath: root
});
const result = await service.runDeployment({ repository: { fullName: 'jens/app', localPath: root }, profileId: profile.id });
assert.equal(result.summary.ready, true);
assert.equal(result.checks.filter((item) => item.status === 'fail').length, 0);
assert.equal(result.head, sha);
});