收敛客户端静态发布链路

This commit is contained in:
2026-08-10 17:04:29 +08:00
parent 2e737dee31
commit 4df047708b
37 changed files with 604 additions and 3071 deletions

View File

@@ -0,0 +1,130 @@
import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
import { afterEach, describe, expect, it, vi } from 'vitest';
import {
createWorksSubmissionBindingStore,
readWorksSubmissionBinding,
} from '@electron/services/works-submission-binding';
import type { OpencodeProject } from '@electron/opencode/project-store';
import {
WORKS_SUBMISSION_BINDING_FILE_NAME,
WORKS_SUBMISSION_BINDING_SCHEMA_VERSION,
} from '../../shared/works-submission-binding';
const temporaryDirectories: string[] = [];
async function createProject(): Promise<OpencodeProject> {
const projectPath = await mkdtemp(join(tmpdir(), 'makelore-submission-binding-'));
temporaryDirectories.push(projectPath);
return {
id: 'project-1',
path: projectPath,
name: 'submission binding test',
createdAt: '2026-08-10T00:00:00.000Z',
updatedAt: '2026-08-10T00:00:00.000Z',
lastOpenedAt: '2026-08-10T00:00:00.000Z',
};
}
function createStore(project: OpencodeProject) {
return { listProjects: vi.fn(async () => [project]) };
}
afterEach(async () => {
await Promise.all(temporaryDirectories.splice(0).map((directory) => (
rm(directory, { recursive: true, force: true })
)));
});
describe('Works Square submission binding store', () => {
it('records the exact one-click submitted version without owning upload behavior', async () => {
const project = await createProject();
const store = createWorksSubmissionBindingStore(createStore(project));
const record = await store.recordSubmitted(project.id, {
appId: 'planet-game',
versionId: 'version-7',
versionName: 'v0.7.0',
reviewStatus: 'building',
zipSha256: 'a'.repeat(64),
});
expect(record).toMatchObject({
schema_version: WORKS_SUBMISSION_BINDING_SCHEMA_VERSION,
project_id: project.id,
status: 'submitted',
app_id: 'planet-game',
version_id: 'version-7',
version_name: 'v0.7.0',
review_status: 'building',
zip_sha256: 'a'.repeat(64),
});
await expect(store.get(project.id)).resolves.toEqual(record);
await expect(readWorksSubmissionBinding(project.path)).resolves.toEqual(record);
});
it.each(['armed', 'waiting_for_package', 'waiting_for_login', 'uploading', 'failed'])(
'retires a legacy %s task with an understandable next step',
async (status) => {
const project = await createProject();
await writeFile(
join(project.path, WORKS_SUBMISSION_BINDING_FILE_NAME),
`${JSON.stringify({
schema_version: 1,
project_id: project.id,
status,
requested_at: '2026-08-01T00:00:00.000Z',
updated_at: '2026-08-01T00:05:00.000Z',
})}\n`,
'utf8',
);
const store = createWorksSubmissionBindingStore(createStore(project));
await store.start();
const record = await store.get(project.id);
expect(record).toMatchObject({
schema_version: WORKS_SUBMISSION_BINDING_SCHEMA_VERSION,
project_id: project.id,
status: 'legacy_retired',
error_code: 'LEGACY_AUTO_DEPLOY_RETIRED',
message: '旧版自动部署任务已停用,请在项目配置中点击“提交审核”重新提交。',
});
expect(JSON.parse(await readFile(
join(project.path, WORKS_SUBMISSION_BINDING_FILE_NAME),
'utf8',
))).toEqual(record);
},
);
it('preserves a submitted legacy version binding while upgrading its schema', async () => {
const project = await createProject();
await writeFile(
join(project.path, WORKS_SUBMISSION_BINDING_FILE_NAME),
`${JSON.stringify({
schema_version: 1,
project_id: project.id,
status: 'submitted',
requested_at: '2026-08-01T00:00:00.000Z',
updated_at: '2026-08-01T00:05:00.000Z',
app_id: 'planet-game',
version_id: 'version-6',
version_name: 'v0.6.0',
review_status: 'approved',
})}\n`,
'utf8',
);
const record = await readWorksSubmissionBinding(project.path);
expect(record).toMatchObject({
schema_version: WORKS_SUBMISSION_BINDING_SCHEMA_VERSION,
status: 'submitted',
app_id: 'planet-game',
version_id: 'version-6',
version_name: 'v0.6.0',
review_status: 'approved',
});
});
});