All files / packages/design-system/scripts/scs scs-helpers.js

98.14% Statements 53/54
87.5% Branches 7/8
100% Functions 5/5
100% Lines 52/52

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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120                        2x 2x   2x         6x 6x       6x 6x   1x 1x   6x 6x 6x 18x         6x 6x 6x 6x       12x     12x 12x 12x   12x       6x 6x 6x 15x 15x               3x 3x 6x 6x             2x     3x 2x   3x   3x 3x 3x 3x         3x 3x 3x       3x   3x 3x 2x 2x 2x         2x 2x   1x 1x      
/**
 * Shared helpers for the SCS release pipeline.
 * Extracted from scs.js to enable unit testing and reduce duplication.
 */
import execa from './exec-adapter.js';
import fs from 'node:fs';
import path from 'node:path';
 
import * as autoVersion from './version-utils.js';
import { writeProtectedFile } from './artifact-provenance.js';
 
const NEXUS_NPM_REGISTRY =
  'https://nexus-proxy.repo.local.sfdc.net/nexus/content/repositories/npmjs-internal/';
const SCS_PACKAGE_NAME = 'slds-modules';
 
export const releaseCommitMessage = (subject) => `release: ${subject}`;
 
// Keep committed npm and Maven versions aligned so publish needs no POM mutation.
export function bumpScsVersionFromNexus({ monorepoRoot, scsPackageDir, gitAdd, exec = execa }) {
  let packageVersion;
  try {
    const { stdout } = exec.commandSync(
      `npm view ${SCS_PACKAGE_NAME} version --registry=${NEXUS_NPM_REGISTRY}`,
      { cwd: monorepoRoot },
    );
    packageVersion = stdout.trim();
    console.log(`\nLatest ${SCS_PACKAGE_NAME} on Nexus: ${packageVersion}`);
  } catch {
    packageVersion = autoVersion.getVersion(scsPackageDir);
    console.log(`\nCould not reach Nexus — using seeded version: ${packageVersion}`);
  }
  const newPackageVersion = autoVersion.patch(packageVersion);
  const packagePath = path.join(scsPackageDir, 'package.json');
  const originals = new Map(
    [packagePath, path.join(scsPackageDir, 'pom.xml'), path.join(monorepoRoot, 'pom.xml')].map((file) => [
      file,
      fs.readFileSync(file, 'utf8'),
    ]),
  );
  const pkg = JSON.parse(originals.get(packagePath));
  pkg.version = newPackageVersion;
  const updates = new Map([[packagePath, JSON.stringify(pkg, null, 2)]]);
  for (const [file, artifactId] of [
    [path.join(scsPackageDir, 'pom.xml'), 'slds-scs'],
    [path.join(monorepoRoot, 'pom.xml'), 'sds-maven-aggregator'],
  ]) {
    const projectVersion = new RegExp(
      `(<artifactId>${artifactId}</artifactId>\\s*<version>)[^<]+(</version>)`,
    );
    const pom = originals.get(file);
    Iif (!projectVersion.test(pom)) throw new Error(`Unable to read project version from ${file}`);
    updates.set(
      file,
      pom.replace(projectVersion, (_, before, after) => `${before}${newPackageVersion}${after}`),
    );
  }
  // Roll back a failed write before staging any part of the version update.
  const attempted = [];
  try {
    for (const [file, content] of updates) {
      attempted.push(file);
      writeProtectedFile({
        destinationRoot: path.dirname(monorepoRoot),
        destinationPath: file,
        trustedRoot: path.dirname(monorepoRoot),
        contents: content,
      });
    }
  } catch (error) {
    const failedRestores = [];
    for (const file of attempted) {
      try {
        writeProtectedFile({
          destinationRoot: path.dirname(monorepoRoot),
          destinationPath: file,
          trustedRoot: path.dirname(monorepoRoot),
          contents: originals.get(file),
        });
      } catch (restoreError) {
        failedRestores.push(`${file}: ${restoreError.message}`);
      }
    }
    if (failedRestores.length) {
      error.message += `; failed to restore ${failedRestores.join(', ')}`;
    }
    throw error;
  }
  gitAdd('package.json');
  gitAdd('pom.xml');
  console.log(`Bumped slds-scs: ${packageVersion} → ${newPackageVersion}`);
  return { from: packageVersion, to: newPackageVersion };
}
 
// Include the root reactor version in the same commit as the SCS payload.
export function commitInMonorepo(message, { monorepoRoot, gitInMonorepo, exec = execa }) {
  gitInMonorepo('git add packages/slds-scs/');
  gitInMonorepo('git add pom.xml');
  exec.commandSync(
    'npx prettier --write packages/slds-scs/package.json packages/slds-scs/scs/files.json',
    { cwd: monorepoRoot },
  );
  gitInMonorepo('git add packages/slds-scs/package.json packages/slds-scs/scs/files.json');
 
  const { stdout: diffIndex } = exec.commandSync('git diff --cached --name-only', { cwd: monorepoRoot });
  if (diffIndex.trim()) {
    const commitEnv = { ...process.env };
    delete commitEnv.SCS_EXPECTED_SOURCE_SHA;
    exec.sync('git', ['commit', '-m', message], {
      cwd: monorepoRoot,
      env: commitEnv,
      extendEnv: false,
    });
    console.log('Committed in monorepo');
    return true;
  } else {
    console.log('No changes to commit in monorepo (already up to date)');
    return false;
  }
}