feat(release): 정적 프런트엔드와 격리 빌더를 도입한다

Gateway와 프로필 릴리스가 불변 프런트엔드 아티팩트를 원자적으로 게시하고 실패 시 이전 포인터를 복구하도록 한다.

릴리스 빌드는 전용 builder protocol로 분리하고 성공한 Gateway 커밋을 재기동용 Git ref에 고정한다.
This commit is contained in:
2026-08-22 09:32:47 +00:00
parent d74a8e48bb
commit d3e5d12cbf
18 changed files with 991 additions and 48 deletions
@@ -103,6 +103,25 @@ describe('GitWorkspaceManager source resolution', () => {
await expect(manager.resolveCommit('COMMIT', 'HEAD..main')).rejects.toThrow('Invalid git ref');
});
it('atomically publishes only refs below the managed release namespace', async () => {
const fixture = createRepositoryFixture();
const manager = new GitWorkspaceManager({
repoRoot: fixture.checkout,
worktreeRoot: fixture.worktrees,
});
const releaseRef = 'refs/sammo/active-gateway';
await expect(manager.readPersistentReleaseRef(releaseRef)).resolves.toBeNull();
await manager.compareAndSwapPersistentReleaseRef(releaseRef, null, fixture.firstCommit);
await expect(manager.readPersistentReleaseRef(releaseRef)).resolves.toBe(fixture.firstCommit);
await expect(
manager.compareAndSwapPersistentReleaseRef(releaseRef, 'f'.repeat(40), fixture.firstCommit)
).rejects.toThrow(/Failed to update persistent release ref/u);
await manager.compareAndSwapPersistentReleaseRef(releaseRef, fixture.firstCommit, null);
await expect(manager.readPersistentReleaseRef(releaseRef)).resolves.toBeNull();
await expect(manager.readPersistentReleaseRef('refs/heads/main')).rejects.toThrow(/refs\/sammo/u);
});
it('reuses only a clean registered worktree at the requested commit', async () => {
const fixture = createRepositoryFixture();
const manager = new GitWorkspaceManager({