build: publish desktop installer via Gitea releases
Some checks failed
Build and tests / test (push) Has been cancelled
Some checks failed
Build and tests / test (push) Has been cancelled
This commit is contained in:
@@ -91,6 +91,25 @@ test('生产部署统一使用 Vite dist 且不会删除 lock 文件', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('桌面安装包由 Gitea Release 发布且不会再次提交到 Git', () => {
|
||||
const gitignore = fs.readFileSync(path.join(projectRoot, '.gitignore'), 'utf8');
|
||||
const release = JSON.parse(fs.readFileSync(
|
||||
path.join(projectRoot, 'frontend', 'desktop-release.json'),
|
||||
'utf8'
|
||||
));
|
||||
const installer = fs.readFileSync(path.join(projectRoot, 'install.sh'), 'utf8');
|
||||
const compose = fs.readFileSync(path.join(projectRoot, 'docker-compose.yml'), 'utf8');
|
||||
|
||||
assert.ok(gitignore.split(/\r?\n/).includes('/frontend/downloads/*.exe'));
|
||||
assert.strictEqual(gitignore.includes('!/frontend/downloads/'), false);
|
||||
assert.match(release.sha256, /^[a-f0-9]{64}$/);
|
||||
assert.ok(Number.isSafeInteger(release.size) && release.size > 0);
|
||||
assert.strictEqual(release.tag, `v${release.version}`);
|
||||
assert.strictEqual(release.publicPath, `/downloads/${release.asset}`);
|
||||
assert.ok(installer.includes('sync_desktop_release'));
|
||||
assert.ok(compose.includes('desktop-release:'));
|
||||
});
|
||||
|
||||
test('Docker 构建上下文排除依赖、环境配置和运行时数据', () => {
|
||||
const dockerIgnore = fs.readFileSync(path.join(projectRoot, 'backend', '.dockerignore'), 'utf8');
|
||||
for (const requiredEntry of ['node_modules', '.env', 'data/*', 'storage/*']) {
|
||||
|
||||
73
backend/tests/release-sync-tests.js
Normal file
73
backend/tests/release-sync-tests.js
Normal file
@@ -0,0 +1,73 @@
|
||||
const assert = require('assert');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const projectRoot = path.resolve(__dirname, '..', '..');
|
||||
const syncScript = path.join(projectRoot, 'frontend', 'scripts', 'sync-desktop-release.js');
|
||||
const results = { passed: 0, failed: 0 };
|
||||
|
||||
function test(name, fn) {
|
||||
try {
|
||||
fn();
|
||||
results.passed += 1;
|
||||
console.log(` [PASS] ${name}`);
|
||||
} catch (error) {
|
||||
results.failed += 1;
|
||||
console.error(` [FAIL] ${name}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n========== 桌面安装包发布同步测试 ==========\n');
|
||||
|
||||
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'wanwanyun-release-sync-'));
|
||||
try {
|
||||
const destinationDirectory = path.join(tempRoot, 'downloads');
|
||||
const asset = 'wanwan-cloud-desktop_v9.9.9_x64-setup.exe';
|
||||
const assetContent = Buffer.from('verified desktop release fixture');
|
||||
const sha256 = crypto.createHash('sha256').update(assetContent).digest('hex');
|
||||
const metadataPath = path.join(tempRoot, 'desktop-release.json');
|
||||
fs.mkdirSync(destinationDirectory, { recursive: true });
|
||||
fs.writeFileSync(path.join(destinationDirectory, asset), assetContent);
|
||||
fs.writeFileSync(metadataPath, JSON.stringify({
|
||||
version: '9.9.9',
|
||||
tag: 'v9.9.9',
|
||||
asset,
|
||||
downloadUrl: `https://example.test/releases/download/v9.9.9/${asset}`,
|
||||
publicPath: `/downloads/${asset}`,
|
||||
sha256,
|
||||
size: assetContent.length
|
||||
}));
|
||||
|
||||
const runCheck = () => spawnSync(process.execPath, [
|
||||
syncScript,
|
||||
'--metadata', metadataPath,
|
||||
'--destination-dir', destinationDirectory,
|
||||
'--check-only'
|
||||
], { encoding: 'utf8' });
|
||||
|
||||
test('已缓存安装包通过大小与 SHA256 校验', () => {
|
||||
const result = runCheck();
|
||||
assert.strictEqual(result.status, 0, result.stderr);
|
||||
assert.match(result.stdout, /Desktop release verified/);
|
||||
});
|
||||
|
||||
test('损坏的安装包会让只读校验失败', () => {
|
||||
fs.appendFileSync(path.join(destinationDirectory, asset), 'corrupt');
|
||||
const result = runCheck();
|
||||
assert.notStrictEqual(result.status, 0);
|
||||
assert.match(result.stderr, /Desktop release check failed/);
|
||||
});
|
||||
} finally {
|
||||
fs.rmSync(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
console.log('\n========================================');
|
||||
console.log('测试总结');
|
||||
console.log('========================================');
|
||||
console.log(`通过: ${results.passed}`);
|
||||
console.log(`失败: ${results.failed}`);
|
||||
|
||||
process.exit(results.failed > 0 ? 1 : 0);
|
||||
@@ -11,6 +11,7 @@ const testFiles = [
|
||||
'domain-utils-tests.js',
|
||||
'middleware-tests.js',
|
||||
'architecture-tests.js',
|
||||
'release-sync-tests.js',
|
||||
'archive-tests.js',
|
||||
'network-concurrent-tests.js',
|
||||
'state-consistency-tests.js'
|
||||
|
||||
Reference in New Issue
Block a user