All files / packages/sds-release-manager/src/orchestrators audit-v1-gitcore-drift.ts

97.05% Statements 33/34
95.83% Branches 23/24
100% Functions 5/5
100% Lines 30/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103                                                                  6x 5x 2x               6x 6x     6x 3x 3x       3x   21x 21x       1x   20x 21x 21x 6x   14x                           14x 14x     2x           2x 2x 2x 2x 2x 2x 2x 2x 2x 2x    
/**
 * Audit orchestrator for V1 Core CSS drift (read-only).
 *
 * Pins the target branch to its current base SHA, fetches the seven CSS
 * artifacts from gitcore at that SHA (hydrating the LFS-tracked ones), then
 * hands the baseline bytes to the design-system preparation step, which builds
 * the candidate, classifies drift, and writes the evidence packet. This command
 * only reads gitcore — it never writes. Its packet is the input to publish.
 */
import { coreRepo, type GitcoreFileBuffer } from '../services/gitcore-service.js';
import type {
  CoreCssArtifact,
  CoreCssArtifactProvenance,
  CoreCssPreparationResult,
  ICoreCssPreparationService,
} from '../services/core-css-preparation-service.js';
import { parseLfsPointer } from '../services/git-lfs-service.js';
 
export type AuditV1GitcoreDriftArgs = { release: string; target: string };
// The read-only subset of gitcore operations the audit needs.
type GitCoreReads = {
  getRefSha(repo: string, branch: string): Promise<string>;
  getFileBuffer(repo: string, path: string, ref: string): Promise<GitcoreFileBuffer>;
};
type GitLfsHydrator = { hydrate(pointerBytes: Buffer): Promise<Buffer> };
export type AuditV1GitcoreDriftDeps = {
  gitcore: GitCoreReads;
  lfs: GitLfsHydrator;
  preparation: ICoreCssPreparationService;
};
 
// release is a bare core release number; target must be its main or patch branch.
function validateArgs({ release, target }: AuditV1GitcoreDriftArgs): void {
  if (!/^\d+$/.test(release)) throw new Error('release must contain digits only');
  if (target !== `p4/${release}-main` && target !== `p4/${release}-patch`) {
    throw new Error(`target must be p4/${release}-main or p4/${release}-patch`);
  }
}
 
export async function runAuditV1GitcoreDrift(
  args: AuditV1GitcoreDriftArgs,
  { gitcore, lfs, preparation }: AuditV1GitcoreDriftDeps,
): Promise<CoreCssPreparationResult> {
  validateArgs(args);
  const repo = coreRepo(args.release);
  // Pin to the branch's current SHA so every artifact is read at one immutable
  // point even if the branch moves during the audit.
  const baseSha = await gitcore.getRefSha(repo, args.target);
  const manifest = await preparation.getManifest();
  Iif (manifest.length !== 7) throw new Error('Core CSS manifest must contain exactly seven artifacts');
 
  // Fetch each baseline file at baseSha. Verify sizes agree, hydrate LFS files
  // from their pointer, and record provenance (blob SHA/size, API size, LFS oid).
  const artifactResults = await Promise.all(
    manifest.map(async (artifact) => {
      const file = await gitcore.getFileBuffer(repo, `core/${artifact.gitcorePath}`, baseSha);
      if (
        artifact.storage === 'git' &&
        (file.content.length !== file.apiSize || file.content.length !== file.blobSize)
      ) {
        throw new Error(`Core CSS size mismatch for ${artifact.gitcorePath}`);
      }
      const pointer = artifact.storage === 'lfs' ? parseLfsPointer(file.content) : undefined;
      const content = pointer ? await lfs.hydrate(file.content) : file.content;
      if (pointer && (content.length !== pointer.size || content.length !== file.apiSize)) {
        throw new Error(`Core CSS size mismatch for ${artifact.gitcorePath}`);
      }
      return {
        baselineArtifact: { id: artifact.id, path: artifact.gitcorePath, content } satisfies CoreCssArtifact,
        provenanceArtifact: {
          id: artifact.id,
          path: artifact.gitcorePath,
          storage: artifact.storage,
          gitBlobSha: file.sha,
          gitBlobSize: file.blobSize,
          apiSize: file.apiSize,
          ...(pointer ? { lfsOid: pointer.oid, lfsSize: pointer.size } : {}),
        } satisfies CoreCssArtifactProvenance,
      };
    }),
  );
  const baselineArtifacts = artifactResults.map(({ baselineArtifact }) => baselineArtifact);
  const provenanceArtifacts = artifactResults.map(({ provenanceArtifact }) => provenanceArtifact);
 
  // Build the candidate, classify drift against the baseline, and write the packet.
  const result = await preparation.prepare(baselineArtifacts, {
    repo,
    target: args.target,
    baseSha,
    artifacts: provenanceArtifacts,
  });
  console.log();
  console.log('=== audit-v1-gitcore-drift summary ===');
  console.log(`version:     ${result.version}`);
  console.log(`source SHA:  ${result.sourceSha}`);
  console.log(`repo:        ${repo}`);
  console.log(`target:      ${args.target}`);
  console.log(`base SHA:    ${baseSha}`);
  console.log(`verdict:     ${result.verdict}`);
  console.log(`result:      ${result.reportDir}/result.json`);
  return result;
}