Packaging changes

Summary:
This change has a few changes in the way our MacOS app was built and packaged.

- Instead of placing the Node binary inside the MacOS folder, place it inside the Resources folder. This is more in compliance with how an app is bundled. Also, with the added benefit of making it a resource which makes it eligible for code signing.
- Both, Node binary and server bundle are placed in the right location before building the MacOS app. By doing this, we ensure the app is not modified after the built process which messes up with code signing, if in place.

Reviewed By: antonk52

Differential Revision: D51568778

fbshipit-source-id: 0b1b0ad9947550ddf0f6d4b04e5aff41f7edcdee
This commit is contained in:
Lorenzo Blasa
2023-11-27 04:55:05 -08:00
committed by Facebook GitHub Bot
parent d22d362c31
commit 5e26d863f1
3 changed files with 125 additions and 72 deletions

1
.gitignore vendored
View File

@@ -50,6 +50,7 @@ xplat/build
# Mac OS X # Mac OS X
*.DS_Store *.DS_Store
facebook/flipper-server/Resources/
# Automatically generated # Automatically generated
docs/extending/ui-components.mdx docs/extending/ui-components.mdx

View File

@@ -26,6 +26,7 @@ import {
serverDir, serverDir,
staticDir, staticDir,
rootDir, rootDir,
sonarDir,
} from './paths'; } from './paths';
import isFB from './isFB'; import isFB from './isFB';
import yargs from 'yargs'; import yargs from 'yargs';
@@ -650,8 +651,11 @@ async function installNodeBinary(outputPath: string, platform: BuildPlatform) {
console.log(`✅ Node successfully downloaded and unpacked.`); console.log(`✅ Node successfully downloaded and unpacked.`);
} }
console.log(`⚙️ Copying node binary from ${nodePath} to ${outputPath}`); console.log(`⚙️ Moving node binary from ${nodePath} to ${outputPath}`);
await fs.copyFile(nodePath, outputPath); if (await fs.exists(outputPath)) {
await fs.rm(outputPath);
}
await fs.move(nodePath, outputPath);
} else { } else {
console.log(`⚙️ Downloading node version for ${platform} using pkg-fetch`); console.log(`⚙️ Downloading node version for ${platform} using pkg-fetch`);
const nodePath = await pkgFetch({ const nodePath = await pkgFetch({
@@ -660,8 +664,11 @@ async function installNodeBinary(outputPath: string, platform: BuildPlatform) {
nodeRange: SUPPORTED_NODE_PLATFORM, nodeRange: SUPPORTED_NODE_PLATFORM,
}); });
console.log(`⚙️ Copying node binary from ${nodePath} to ${outputPath}`); console.log(`⚙️ Moving node binary from ${nodePath} to ${outputPath}`);
await fs.copyFile(nodePath, outputPath); if (await fs.exists(outputPath)) {
await fs.rm(outputPath);
}
await fs.move(nodePath, outputPath);
} }
if ( if (
@@ -739,35 +746,21 @@ async function setUpWindowsBundle(outputDir: string) {
async function setUpMacBundle( async function setUpMacBundle(
outputDir: string, outputDir: string,
serverDir: string,
platform: BuildPlatform, platform: BuildPlatform,
versionNumber: string, versionNumber: string,
): Promise<{nodePath: string; resourcesPath: string}> { ) {
console.log(`⚙️ Creating Mac bundle in ${outputDir}`); console.log(`⚙️ Creating Mac bundle in ${outputDir}`);
if (isFB) { let serverOutputDir = '';
const {BuildArchitecture, buildFlipperServer} = await import( let nodeBinaryFile = '';
// @ts-ignore only used inside Meta
'./fb/build-flipper-server-macos'
);
const architecture = /**
platform === BuildPlatform.MAC_AARCH64 * Use the most basic template for MacOS.
? BuildArchitecture.MAC_AARCH64 * - Copy the contents of the template into the output directory.
: BuildArchitecture.MAC_X64; * - Replace the version placeholder value with the actual version.
const outputPath = await buildFlipperServer( */
architecture, if (!isFB) {
versionNumber,
false,
);
console.log(
`⚙️ Successfully built platform: ${platform}, output: ${outputPath}`,
);
const appPath = path.join(outputDir, 'Flipper.app');
await fs.emptyDir(appPath);
await fs.copy(outputPath, appPath);
} else {
const template = path.join(staticDir, 'flipper-server-app-template'); const template = path.join(staticDir, 'flipper-server-app-template');
await fs.copy(template, outputDir); await fs.copy(template, outputDir);
@@ -792,7 +785,7 @@ async function setUpMacBundle(
return obj; return obj;
} }
console.log(`⚙️ Writing plist`); console.log(`⚙️ Update plist with build information`);
const plistPath = path.join( const plistPath = path.join(
outputDir, outputDir,
'Flipper.app', 'Flipper.app',
@@ -809,9 +802,8 @@ async function setUpMacBundle(
); );
plist.writeBinaryFileSync(plistPath, pListContents); plist.writeBinaryFileSync(plistPath, pListContents);
/* eslint-enable node/no-sync*/ /* eslint-enable node/no-sync*/
}
const resourcesOutputDir = path.join( serverOutputDir = path.join(
outputDir, outputDir,
'Flipper.app', 'Flipper.app',
'Contents', 'Contents',
@@ -819,21 +811,81 @@ async function setUpMacBundle(
'server', 'server',
); );
if (!(await fs.exists(resourcesOutputDir))) { nodeBinaryFile = path.join(
await fs.mkdir(resourcesOutputDir);
}
const nodeOutputPath = path.join(
outputDir, outputDir,
'Flipper.app', 'Flipper.app',
'Contents', 'Contents',
'MacOS', 'MacOS',
'flipper-runtime', 'flipper-runtime',
); );
return {resourcesPath: resourcesOutputDir, nodePath: nodeOutputPath}; } else {
serverOutputDir = path.join(
sonarDir,
'facebook',
'flipper-server',
'Resources',
'server',
);
nodeBinaryFile = path.join(
sonarDir,
'facebook',
'flipper-server',
'Resources',
'flipper-runtime',
);
}
if (await fs.exists(serverOutputDir)) {
await fs.rm(serverOutputDir, {recursive: true, force: true});
}
await fs.mkdirp(serverOutputDir);
console.log(`⚙️ Copying from ${serverDir} to ${serverOutputDir}`);
// Copy resources instead of moving. This is because we want to keep the original
// files in the right location because they are used whilst bundling for
// other platforms.
await fs.copy(serverDir, serverOutputDir, {
overwrite: true,
dereference: true,
});
console.log(`⚙️ Downloading compatible node version`);
await installNodeBinary(nodeBinaryFile, platform);
if (isFB) {
const {BuildArchitecture, buildFlipperServer} = await import(
// @ts-ignore only used inside Meta
'./fb/build-flipper-server-macos'
);
const architecture =
platform === BuildPlatform.MAC_AARCH64
? BuildArchitecture.MAC_AARCH64
: BuildArchitecture.MAC_X64;
const outputPath = await buildFlipperServer(
architecture,
versionNumber,
false,
);
console.log(
`⚙️ Successfully built platform: ${platform}, output: ${outputPath}`,
);
const appPath = path.join(outputDir, 'Flipper.app');
await fs.emptyDir(appPath);
await fs.copy(outputPath, appPath);
// const appPath = path.join(outputDir, 'Flipper.app');
// if (await fs.exists(appPath)) {
// await fs.rm(appPath, {recursive: true, force: true});
// }
// await fs.move(outputPath, appPath);
}
} }
async function bundleServerReleaseForPlatform( async function bundleServerReleaseForPlatform(
dir: string, bundleDir: string,
versionNumber: string, versionNumber: string,
platform: BuildPlatform, platform: BuildPlatform,
) { ) {
@@ -844,39 +896,38 @@ async function bundleServerReleaseForPlatform(
); );
await fs.mkdirp(outputDir); await fs.mkdirp(outputDir);
let outputPaths = {
nodePath: path.join(outputDir, 'flipper-runtime'),
resourcesPath: outputDir,
};
// On the mac, we need to set up a resource bundle which expects paths // On the mac, we need to set up a resource bundle which expects paths
// to be in different places from Linux/Windows bundles. // to be in different places from Linux/Windows bundles.
if ( if (
platform === BuildPlatform.MAC_X64 || platform === BuildPlatform.MAC_X64 ||
platform === BuildPlatform.MAC_AARCH64 platform === BuildPlatform.MAC_AARCH64
) { ) {
outputPaths = await setUpMacBundle(outputDir, platform, versionNumber); await setUpMacBundle(outputDir, bundleDir, platform, versionNumber);
} else if (platform === BuildPlatform.LINUX) { if (argv.dmg) {
await createMacDMG(platform, outputDir, distDir);
}
} else {
const outputPaths = {
nodePath: path.join(outputDir, 'flipper-runtime'),
resourcesPath: outputDir,
};
if (platform === BuildPlatform.LINUX) {
await setUpLinuxBundle(outputDir); await setUpLinuxBundle(outputDir);
} else if (platform === BuildPlatform.WINDOWS) { } else if (platform === BuildPlatform.WINDOWS) {
await setUpWindowsBundle(outputDir); await setUpWindowsBundle(outputDir);
} }
console.log(`⚙️ Copying from ${dir} to ${outputPaths.resourcesPath}`); console.log(
await fs.copy(dir, outputPaths.resourcesPath, { `⚙️ Copying from ${bundleDir} to ${outputPaths.resourcesPath}`,
);
await fs.copy(bundleDir, outputPaths.resourcesPath, {
overwrite: true, overwrite: true,
dereference: true, dereference: true,
}); });
console.log(`⚙️ Downloading compatible node version`); console.log(`⚙️ Downloading compatible node version`);
await installNodeBinary(outputPaths.nodePath, platform); await installNodeBinary(outputPaths.nodePath, platform);
if (
argv.dmg &&
(platform === BuildPlatform.MAC_X64 ||
platform === BuildPlatform.MAC_AARCH64)
) {
await createMacDMG(platform, outputDir, distDir);
} }
console.log(`✅ Wrote ${platform}-specific server version to ${outputDir}`); console.log(`✅ Wrote ${platform}-specific server version to ${outputDir}`);

View File

@@ -10,6 +10,7 @@
import path from 'path'; import path from 'path';
export const rootDir = path.resolve(__dirname, '..'); export const rootDir = path.resolve(__dirname, '..');
export const sonarDir = path.resolve(__dirname, '..', '..');
export const appDir = path.join(rootDir, 'app'); export const appDir = path.join(rootDir, 'app');
export const browserUiDir = path.join(rootDir, 'flipper-ui-browser'); export const browserUiDir = path.join(rootDir, 'flipper-ui-browser');
export const staticDir = path.join(rootDir, 'static'); export const staticDir = path.join(rootDir, 'static');