Files
aia-website/www/tools/deploy.test.mjs
T

36 lines
2.2 KiB
JavaScript

import assert from 'node:assert/strict';
import { createHash } from 'node:crypto';
import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { spawnSync } from 'node:child_process';
import test from 'node:test';
import { releaseManifest, rsyncArguments, sshTarget } from './deploy.mjs';
test('site manifest follows the Contabo schema and detects unsafe public output', async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'aia-deploy-manifest-'));
try {
await fs.mkdir(path.join(root, '_astro'));
await fs.writeFile(path.join(root, 'index.html'), '<title>Synthetic</title>');
await fs.writeFile(path.join(root, '_astro', 'entry.abcdefgh.js'), 'export {}');
const manifest = await releaseManifest(root, 'a'.repeat(40));
assert.deepEqual(Object.keys(manifest).sort(), ['directories','files','immutableAssets','schema','sourceCommit','treeSha256']);
assert.equal(manifest.schema, 1);
assert.equal(manifest.immutableAssets[0], '_astro/entry.abcdefgh.js');
const expected = createHash('sha256').update(Object.entries(manifest.files).sort(([a], [b]) => a.localeCompare(b)).map(([name, meta]) => `${name}\0${meta.sha256}\n`).join('')).digest('hex');
assert.equal(manifest.treeSha256, expected);
const serverTool = path.resolve(process.cwd(), '../../contabo/scripts/website-release.py');
const parity = spawnSync('python3', [serverTool, 'manifest', root, 'a'.repeat(40)], { encoding: 'utf8' });
assert.equal(parity.status, 0, parity.stderr);
assert.deepEqual(manifest, JSON.parse(parity.stdout));
await fs.mkdir(path.join(root, 'private'));
await assert.rejects(releaseManifest(root, 'a'.repeat(40)), /Unexpected private artifact/);
} finally { await fs.rm(root, { recursive: true, force: true }); }
});
test('deployment transfer uses the Contabo ownership and mode interface', () => {
assert.deepEqual(rsyncArguments('/tmp/source', 'host:/srv/stage', { remove: true }).slice(0, 6), ['-rlt','--delete','--links','--chown=root:root','--chmod=Du=rwx,Dgo=,Fu=rw,Fgo=','/tmp/source/']);
assert.deepEqual(sshTarget('root@host.example', '/absolute/key').slice(0, 3), ['ssh','-i','/absolute/key']);
assert.throws(() => sshTarget('host;rm -rf /', '/absolute/key'), /invalid/);
});