Skip to content

Commit

Permalink
Build electron binaries
Browse files Browse the repository at this point in the history
  • Loading branch information
rbuckton committed Nov 5, 2022
1 parent e20c7f0 commit e949770
Show file tree
Hide file tree
Showing 9 changed files with 252 additions and 21 deletions.
19 changes: 12 additions & 7 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,20 +107,22 @@ jobs:
- name: macos
target: macos-latest
node:
- 16
- 18
name: "${{ matrix.os.name }} (node v${{ matrix.node }})"
- version: 16
electron: false
- version: 18
electron: true
name: "${{ matrix.os.name }} (node v${{ matrix.node.version }})"
runs-on: ${{ matrix.os.target }}
needs:
- version
# TODO: Do not build if binary packages not included in changed packages
# TODO: Test binaries
steps:
- uses: actions/checkout@v3
- name: use node v16
- name: use node ${{ matrix.node.version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
node-version: ${{ matrix.node.version }}
registry-url: 'https://registry.npmjs.org'
cache: 'yarn'
- name: sync version
Expand All @@ -130,8 +132,11 @@ jobs:
path: ${{ github.workspace }}
- name: yarn install
run: yarn install --ignore-scripts --frozen-lockfile --non-interactive
- name: build native binaries
run: yarn run build-${{ matrix.os.name }}
- name: build node binaries
run: yarn run package-node-${{ matrix.os.name }}
- name: build electron binaries
if: ${{ matrix.node.electron == true }}
run: yarn run package-electron-${{ matrix.os.name }}
- name: upload build artifacts
uses: actions/upload-artifact@v3
with:
Expand Down
9 changes: 6 additions & 3 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,12 @@ gulp.task("build", build);
const ci = gulp.series(clean, build);
gulp.task("ci", ci);

gulp.task("build-windows", () => exec(process.execPath, ["node_modules/workspaces-foreach", "run", "package-node-win32-x64"]));
gulp.task("build-linux", () => exec(process.execPath, ["node_modules/workspaces-foreach", "run", "package-node-linux-x64"]));
gulp.task("build-macos", () => exec(process.execPath, ["node_modules/workspaces-foreach", "run", "package-node-darwin-x64"]));
gulp.task("package-electron-win32", () => exec(process.execPath, ["node_modules/workspaces-foreach", "run", "package-electron-win32"]));
gulp.task("package-electron-linux", () => exec(process.execPath, ["node_modules/workspaces-foreach", "run", "package-electron-linux"]));
gulp.task("package-electron-darwin", () => exec(process.execPath, ["node_modules/workspaces-foreach", "run", "package-electron-darwin"]));
gulp.task("package-node-win32", () => exec(process.execPath, ["node_modules/workspaces-foreach", "run", "package-node-win32"]));
gulp.task("package-node-linux", () => exec(process.execPath, ["node_modules/workspaces-foreach", "run", "package-node-linux"]));
gulp.task("package-node-darwin", () => exec(process.execPath, ["node_modules/workspaces-foreach", "run", "package-node-darwin"]));
gulp.task("pack", () => exec(process.execPath, ["node_modules/workspaces-foreach", "pack", "--silent", "--json"]));

const test = () => {
Expand Down
10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@
"prebuild": "node node_modules/workspaces-foreach run prebuild",
"ci": "gulp ci",
"pack": "node node_modules/workspaces-foreach pack",
"build-windows": "gulp build-windows",
"build-linux": "gulp build-linux",
"build-macos": "gulp build-macos"
"package-electron-windows": "gulp package-electron-win32",
"package-electron-linux": "gulp package-electron-linux",
"package-electron-macos": "gulp package-electron-darwin",
"package-node-windows": "gulp package-node-win32",
"package-node-linux": "gulp package-node-linux",
"package-node-macos": "gulp package-node-darwin"
},
"bugs": {
"url": "https://github.com/esfx/esfx/issues"
Expand Down Expand Up @@ -65,6 +68,7 @@
"lerna": "^3.22.1",
"node-fetch": "^2.6.1",
"npm-packlist": "^5.1.3",
"npm-run-path": "5.1.0",
"prompts": "^2.4.0",
"ts-jest": "^29.0.1",
"ts-node": "^9.1.1",
Expand Down
6 changes: 4 additions & 2 deletions packages/equatable/.npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
/package.internal.d.ts
/jest*config.js
/tsconfig*.json
binding.gyp_
.vscode
.npmfiles
*.tgz
*.tsbuildinfo
__tests__
__perf__
__perf__
binding.gyp_
configurations.json
gulpfile.js
3 changes: 3 additions & 0 deletions packages/equatable/binding.gyp
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
'variables' : {
'openssl_fips': '',
},
"targets": [{
"target_name": "<(module_name)",
"sources": [ "lib/hashCodeNative.cpp" ],
Expand Down
4 changes: 4 additions & 0 deletions packages/equatable/configurations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[
{ "runtime": "node", "target": null, "target_arch": ["x64"], "target_platform": ["win32", "linux", "darwin"] },
{ "runtime": "electron", "target": ["8.2.0", "8.1.0", "8.0.0", "7.1.0", "7.0.0", "6.1.0", "6.0.0"], "target_arch": ["x86", "x64"], "target_platform": ["win32", "linux", "darwin"], "args": ["--dist-url=https://electronjs.org/headers"] }
]
192 changes: 192 additions & 0 deletions packages/equatable/gulpfile.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
// @ts-check
import gulp from "gulp";
import { exec, ArgsBuilder } from "../../scripts/exec.js";
import { npmRunPathEnv } from "npm-run-path";
import { createRequire } from "module";

/**
* @typedef Matrix
* @property {string|string[]} runtime
* @property {string|string[]|null} [target]
* @property {string|string[]|null} [target_arch]
* @property {string|string[]|null} [target_platform]
* @property {string[]} [args]
*/

/**
* @typedef Configuration
* @property {string} runtime
* @property {string|null} [target]
* @property {string|null} [target_arch]
* @property {string|null} [target_platform]
* @property {string[]} [args]
*/

/**
* @typedef TaskEntry
* @property {"build" | "package" | "clean"} action
* @property {string} runtime
* @property {string|null} target
* @property {string} arch
* @property {string} platform
* @property {gulp.TaskFunction} task
*/

/**
* @typedef TaskFilter
* @property {string} [runtime]
* @property {string} [target]
* @property {string} [arch]
* @property {string} [platform]
*/

/** @type {Matrix[]} */
const matrix = createRequire(import.meta.url)("./configurations.json");
const configurations = computeConfigurations(matrix);
createTasks(configurations);

/**
* @param {Matrix[]} matrix
*/
function computeConfigurations(matrix) {
/** @type {Configuration[]} */
const configurations = [];
for (const { runtime, target, target_platform, target_arch, args } of matrix) {
const runtimes = Array.isArray(runtime) ? runtime : [runtime];
const targets = Array.isArray(target) ? target : [target];
const target_archs = Array.isArray(target_arch) ? target_arch : [target_arch];
const target_platforms = Array.isArray(target_platform) ? target_platform : [target_platform];
for (const runtime of runtimes)
for (const target of targets)
for (const target_arch of target_archs)
for (const target_platform of target_platforms)
configurations.push({ runtime, target, target_arch, target_platform, args });
}
return configurations;
}

/**
* @param {Configuration[]} configurations
*/
function createTasks(configurations) {
const { tasks, runtimes, platforms, archs } = computeTaskEntries(configurations);

createActions("-native", tasks, {});
for (const runtime of runtimes) {
createActions(`-${runtime}`, tasks, { runtime });
createActions(`-${runtime}-current`, tasks, { runtime, platform: process.platform });
for (const platform of platforms) {
createActions(`-${runtime}-${platform}`, tasks, { platform, runtime });
for (const arch of archs) {
createActions(`-${runtime}-${platform}-${arch}`, tasks, { platform, runtime, arch });
}
}
}

for (const platform of platforms) {
createActions(`-${platform}`, tasks, { platform });
}
}

/**
* @param {string} suffix
* @param {TaskEntry[]} tasks
* @param {TaskFilter} filter
*/
function createActions(suffix, tasks, filter) {
const buildTasks = selectTasks(tasks, "build", filter);
const buildTask = buildTasks.length ? gulp.series(buildTasks) : (async () => { console.log("no matching tasks."); });
gulp.task(`build${suffix}`, buildTask);

const packageTasks = selectTasks(tasks, "package", filter);
const packageTask = packageTasks.length ? gulp.series(packageTasks) : (async () => { console.log("no matching tasks."); });
gulp.task(`package${suffix}`, packageTask);

const cleanTasks = selectTasks(tasks, "clean", filter);
const cleanTask = cleanTasks.length ? gulp.series(cleanTasks) : (async () => { console.log("no matching tasks."); });
gulp.task(`clean${suffix}`, cleanTask);
}

/**
* @param {Configuration[]} configurations
*/
function computeTaskEntries(configurations) {
const runtimes = configurations.reduce((set, { runtime }) => set.add(runtime), new Set());
const platforms = configurations.reduce((set, { target_platform }) => target_platform ? set.add(target_platform) : set, new Set());
const archs = configurations.reduce((set, { target_arch }) => target_arch ? set.add(target_arch) : set, new Set());

/** @type {TaskEntry[]} */
const tasks = [];
for (const runtime of runtimes)
for (const platform of platforms)
for (const arch of archs)
for (const config of configurations) {
if (config.runtime !== runtime) continue;
if (config.target_platform !== platform) continue;
if (config.target_arch !== arch) continue;
const packageTaskName = `package-${runtime}-${platform}-${arch}-${config.target ?? "current"}`;
const cleanTaskName = `clean-${runtime}-${platform}-${arch}-${config.target ?? "current"}`;
const buildTaskName = `build-${runtime}-${platform}-${arch}-${config.target ?? "current"}`;

/** @type {gulp.TaskFunction} */
const buildTask = async () => {
const args = new ArgsBuilder();
args.addValue("configure");
args.addValue("rebuild");
args.addValue(`--runtime=${config.runtime}`);
if (config.target) args.addValue(`--target=${config.target}`);
if (config.target_arch) args.addValue(`--target_arch=${config.target_arch}`);
if (config.target_platform) args.addValue(`--target_platform=${config.target_platform}`);
const configArgs = config.args ?? [];
await exec("node-pre-gyp", [...args, ...configArgs], { verbose: true, env: npmRunPathEnv() });
};
gulp.task(buildTask.displayName = buildTaskName, buildTask);
tasks.push({ action: "build", runtime, target: config.target ?? null, platform: platform, arch: arch, task: buildTask });

/** @type {gulp.TaskFunction} */
const packageTask = async () => {
const args = new ArgsBuilder();
args.addValue("configure");
args.addValue("rebuild");
args.addValue("package");
args.addValue(`--runtime=${config.runtime}`);
if (config.target) args.addValue(`--target=${config.target}`);
if (config.target_arch) args.addValue(`--target_arch=${config.target_arch}`);
if (config.target_platform) args.addValue(`--target_platform=${config.target_platform}`);
const configArgs = config.args ?? [];
await exec("node-pre-gyp", [...args, ...configArgs], { verbose: true, env: npmRunPathEnv() });
};
gulp.task(packageTask.displayName = packageTaskName, packageTask);
tasks.push({ action: "package", runtime, target: config.target ?? null, platform: platform, arch: arch, task: packageTask });

/** @type {gulp.TaskFunction} */
const cleanTask = async () => {
const args = new ArgsBuilder();
args.addValue("clean");
args.addValue(`--runtime=${config.runtime}`);
if (config.target) args.addValue(`--target=${config.target}`);
if (config.target_arch) args.addValue(`--target_arch=${config.target_arch}`);
if (config.target_platform) args.addValue(`--target_platform=${config.target_platform}`);
const configArgs = config.args ?? [];
await exec("node-pre-gyp", [...args, ...configArgs], { verbose: true, env: npmRunPathEnv() });
};
gulp.task(cleanTask.displayName = cleanTaskName, cleanTask);
tasks.push({ action: "clean", runtime, target: config.target ?? null, platform: platform, arch: arch, task: cleanTask });
}
return { tasks, runtimes, platforms, archs };
}

/**
* @param {TaskEntry[]} tasks
* @param {TaskEntry["action"]} action
* @param {TaskFilter} filter
*/
function selectTasks(tasks, action, filter = {}) {
return tasks.filter(entry =>
entry.action === action &&
(!filter.runtime || entry.runtime === filter.runtime) &&
(!filter.target || entry.target === filter.target) &&
(!filter.arch || entry.arch === filter.arch) &&
(!filter.platform || entry.platform === filter.platform))
.map(entry => entry.task);
}
10 changes: 8 additions & 2 deletions packages/equatable/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,13 @@
"build-node-darwin-x64": "node-pre-gyp configure rebuild --runtime=node --target_arch=x64 --target_platform=darwin",
"package-node-win32-x64": "node-pre-gyp configure rebuild package --runtime=node --target_arch=x64 --target_platform=win32",
"package-node-linux-x64": "node-pre-gyp configure rebuild package --runtime=node --target_arch=x64 --target_platform=linux",
"package-node-darwin-x64": "node-pre-gyp configure rebuild package --runtime=node --target_arch=x64 --target_platform=darwin"
"package-node-darwin-x64": "node-pre-gyp configure rebuild package --runtime=node --target_arch=x64 --target_platform=darwin",
"package-node-win32": "gulp package-node-win32",
"package-node-linux": "gulp package-node-linux",
"package-node-darwin": "gulp package-node-darwin",
"package-electron-win32": "gulp package-electron-win32",
"package-electron-linux": "gulp package-electron-linux",
"package-electron-darwin": "gulp package-electron-darwin"
},
"repository": {
"type": "git",
Expand All @@ -79,7 +85,7 @@
"url": "https://github.com/esfx/esfx/issues"
},
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.9"
"@mapbox/node-pre-gyp": "^1.0.10"
},
"devDependencies": {
"@esfx/internal-guards": "^1.1.0-alpha.202210252139",
Expand Down
20 changes: 16 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1442,10 +1442,10 @@
npmlog "^4.1.2"
write-file-atomic "^2.3.0"

"@mapbox/node-pre-gyp@^1.0.9":
version "1.0.9"
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz#09a8781a3a036151cdebbe8719d6f8b25d4058bc"
integrity sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==
"@mapbox/node-pre-gyp@^1.0.10":
version "1.0.10"
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c"
integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==
dependencies:
detect-libc "^2.0.0"
https-proxy-agent "^5.0.0"
Expand Down Expand Up @@ -6463,6 +6463,13 @@ npm-pick-manifest@^3.0.0:
npm-package-arg "^6.0.0"
semver "^5.4.1"

npm-run-path@5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00"
integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==
dependencies:
path-key "^4.0.0"

npm-run-path@^2.0.0:
version "2.0.2"
resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz"
Expand Down Expand Up @@ -6876,6 +6883,11 @@ path-key@^3.0.0, path-key@^3.1.0:
resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==

path-key@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18"
integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==

path-parse@^1.0.6:
version "1.0.6"
resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz"
Expand Down

0 comments on commit e949770

Please sign in to comment.