feat(orchestrator): build reliability features — git integrity, reserved filename cleanup, archival

Add three optional reliability features for hardening CI pipelines:
- Git corruption detection & recovery (fsck, stale lock cleanup,
  submodule backing store validation, auto-recovery)
- Reserved filename cleanup (removes Windows device names that
  cause Unity asset importer infinite loops)
- Build output archival with configurable retention policy

All features are opt-in and fail gracefully with warnings only.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
frostebite
2026-03-05 11:35:57 +00:00
parent 9d475434d3
commit 4f07508484
8 changed files with 488 additions and 1 deletions
@@ -0,0 +1,54 @@
import fs from 'node:fs';
import { BuildReliabilityService } from './build-reliability-service';
// Mock dependencies
jest.mock('node:fs');
jest.mock('../core/orchestrator-logger');
jest.mock('../core/orchestrator-system');
const mockFs = fs as jest.Mocked<typeof fs>;
describe('BuildReliabilityService', () => {
beforeEach(() => {
jest.clearAllMocks();
});
describe('cleanStaleLockFiles', () => {
it('should return 0 when .git directory does not exist', async () => {
mockFs.existsSync.mockReturnValue(false);
const result = await BuildReliabilityService.cleanStaleLockFiles('/repo');
expect(result).toBe(0);
});
});
describe('cleanReservedFilenames', () => {
it('should return empty array when Assets directory does not exist', async () => {
mockFs.existsSync.mockReturnValue(false);
const result = await BuildReliabilityService.cleanReservedFilenames('/project');
expect(result).toEqual([]);
});
});
describe('validateSubmoduleBackingStores', () => {
it('should return empty array when .gitmodules does not exist', async () => {
mockFs.existsSync.mockReturnValue(false);
const result = await BuildReliabilityService.validateSubmoduleBackingStores('/repo');
expect(result).toEqual([]);
});
});
describe('enforceRetention', () => {
it('should return 0 when archive path does not exist', async () => {
mockFs.existsSync.mockReturnValue(false);
const result = await BuildReliabilityService.enforceRetention('/archive', 3);
expect(result).toBe(0);
});
});
describe('configureGitEnvironment', () => {
it('should return GIT_CONFIG_NOSYSTEM=1', () => {
const environment = BuildReliabilityService.configureGitEnvironment();
expect(environment.GIT_CONFIG_NOSYSTEM).toBe('1');
});
});
});