codesign-helpers.ts 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import * as cp from 'node:child_process';
  2. import * as fs from 'fs-extra';
  3. import * as os from 'node:os';
  4. import * as path from 'node:path';
  5. import { expect } from 'chai';
  6. const features = process._linkedBinding('electron_common_features');
  7. const fixturesPath = path.resolve(__dirname, '..', 'fixtures');
  8. export const shouldRunCodesignTests =
  9. process.platform === 'darwin' &&
  10. !(process.env.CI && process.arch === 'arm64') &&
  11. !process.mas &&
  12. !features.isComponentBuild();
  13. let identity: string | null;
  14. export function getCodesignIdentity () {
  15. if (identity === undefined) {
  16. const result = cp.spawnSync(path.resolve(__dirname, '../../script/codesign/get-trusted-identity.sh'));
  17. if (result.status !== 0 || result.stdout.toString().trim().length === 0) {
  18. identity = null;
  19. } else {
  20. identity = result.stdout.toString().trim();
  21. }
  22. }
  23. return identity;
  24. }
  25. export async function copyApp (newDir: string, fixture: string | null = 'initial') {
  26. const appBundlePath = path.resolve(process.execPath, '../../..');
  27. const newPath = path.resolve(newDir, 'Electron.app');
  28. cp.spawnSync('cp', ['-R', appBundlePath, path.dirname(newPath)]);
  29. if (fixture) {
  30. const appDir = path.resolve(newPath, 'Contents/Resources/app');
  31. await fs.mkdirp(appDir);
  32. await fs.copy(path.resolve(fixturesPath, 'auto-update', fixture), appDir);
  33. }
  34. const plistPath = path.resolve(newPath, 'Contents', 'Info.plist');
  35. await fs.writeFile(
  36. plistPath,
  37. (await fs.readFile(plistPath, 'utf8')).replace('<key>BuildMachineOSBuild</key>', `<key>NSAppTransportSecurity</key>
  38. <dict>
  39. <key>NSAllowsArbitraryLoads</key>
  40. <true/>
  41. <key>NSExceptionDomains</key>
  42. <dict>
  43. <key>localhost</key>
  44. <dict>
  45. <key>NSExceptionAllowsInsecureHTTPLoads</key>
  46. <true/>
  47. <key>NSIncludesSubdomains</key>
  48. <true/>
  49. </dict>
  50. </dict>
  51. </dict><key>BuildMachineOSBuild</key>`)
  52. );
  53. return newPath;
  54. };
  55. export function spawn (cmd: string, args: string[], opts: any = {}) {
  56. let out = '';
  57. const child = cp.spawn(cmd, args, opts);
  58. child.stdout.on('data', (chunk: Buffer) => {
  59. out += chunk.toString();
  60. });
  61. child.stderr.on('data', (chunk: Buffer) => {
  62. out += chunk.toString();
  63. });
  64. return new Promise<{ code: number, out: string }>((resolve) => {
  65. child.on('exit', (code, signal) => {
  66. expect(signal).to.equal(null);
  67. resolve({
  68. code: code!,
  69. out
  70. });
  71. });
  72. });
  73. };
  74. export function signApp (appPath: string, identity: string) {
  75. return spawn('codesign', ['-s', identity, '--deep', '--force', appPath]);
  76. };
  77. export async function withTempDirectory (fn: (dir: string) => Promise<void>, autoCleanUp = true) {
  78. const dir = await fs.mkdtemp(path.resolve(os.tmpdir(), 'electron-update-spec-'));
  79. try {
  80. await fn(dir);
  81. } finally {
  82. if (autoCleanUp) {
  83. cp.spawnSync('rm', ['-r', dir]);
  84. }
  85. }
  86. };