2022-11-30 16:19:45 +01:00
|
|
|
const path = require('path');
|
2021-10-06 19:44:48 +02:00
|
|
|
const semver = require('semver');
|
2023-04-25 16:32:51 +02:00
|
|
|
const { loadBuildTypesConfig } = require('../lib/build-type');
|
Add validation to production build script (#15468)
Validation has been added to the build script when the "prod" target is
selected. We now ensure that all expected environment variables are
set, and that no extra environment variables are present (which might
indicate that the wrong configuration file is being used).
The `prod` target uses a new `.metamaskprodrc` configuration file. Each
required variable can be specified either via environment variable or
via this config file. CI will continue set these via environment
variable, but for local manual builds we can use the config file to
simplify the build process and ensure consistency.
A new "dist" target has been added to preserve the ability to build a
"production-like" build without this validation.
The config validation is invoked early in the script, in the CLI
argument parsing step, so that it would fail more quickly. Otherwise
we'd have to wait a few minutes longer for the validation to run.
This required some refactoring, moving functions to the utility module
and moving the config to a dedicated module.
Additionally, support has been added for all environment variables to
be set via the config file. Previously the values `PUBNUB_PUB_KEY`,
`PUBNUB_SUB_KEY`, `SENTRY_DSN`, and `SWAPS_USE_DEV_APIS` could only be
set via environment variable. Now, all of these variables can be set
either way.
Closes #15003
2022-08-19 20:16:18 +02:00
|
|
|
const { BUILD_TARGETS, ENVIRONMENT } = require('./constants');
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether the current build is a development build or not.
|
|
|
|
*
|
|
|
|
* @param {BUILD_TARGETS} buildTarget - The current build target.
|
|
|
|
* @returns Whether the current build is a development build.
|
|
|
|
*/
|
|
|
|
function isDevBuild(buildTarget) {
|
|
|
|
return (
|
|
|
|
buildTarget === BUILD_TARGETS.DEV || buildTarget === BUILD_TARGETS.TEST_DEV
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether the current build is an e2e test build or not.
|
|
|
|
*
|
|
|
|
* @param {BUILD_TARGETS} buildTarget - The current build target.
|
|
|
|
* @returns Whether the current build is an e2e test build.
|
|
|
|
*/
|
|
|
|
function isTestBuild(buildTarget) {
|
|
|
|
return (
|
|
|
|
buildTarget === BUILD_TARGETS.TEST || buildTarget === BUILD_TARGETS.TEST_DEV
|
|
|
|
);
|
|
|
|
}
|
2021-10-06 19:44:48 +02:00
|
|
|
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
/**
|
2021-10-06 19:44:48 +02:00
|
|
|
* Map the current version to a format that is compatible with each browser.
|
|
|
|
*
|
|
|
|
* The given version number is assumed to be a SemVer version number. Additionally, if the version
|
|
|
|
* has a prerelease component, it is assumed to have the format "<build type>.<build version",
|
|
|
|
* where the build version is a positive integer.
|
|
|
|
*
|
|
|
|
* @param {string[]} platforms - A list of browsers to generate versions for.
|
2022-03-10 17:01:50 +01:00
|
|
|
* @param {string} version - The current version.
|
2022-07-27 15:28:05 +02:00
|
|
|
* @returns {object} An object with the browser as the key and the browser-specific version object
|
2021-10-06 19:44:48 +02:00
|
|
|
* as the value. For example, the version `9.6.0-beta.1` would return the object
|
2022-01-03 15:00:13 +01:00
|
|
|
* `{ firefox: { version: '9.6.0.beta1' }, chrome: { version: '9.6.0.1', version_name: '9.6.0-beta.1' } }`.
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
*/
|
2022-03-10 17:01:50 +01:00
|
|
|
function getBrowserVersionMap(platforms, version) {
|
2021-10-06 19:44:48 +02:00
|
|
|
const major = semver.major(version);
|
|
|
|
const minor = semver.minor(version);
|
|
|
|
const patch = semver.patch(version);
|
|
|
|
const prerelease = semver.prerelease(version);
|
2023-03-04 13:51:04 +01:00
|
|
|
let buildType, buildVersionSummary, buildVersion;
|
2021-10-06 19:44:48 +02:00
|
|
|
if (prerelease) {
|
2023-03-04 13:51:04 +01:00
|
|
|
[buildType, buildVersionSummary] = prerelease;
|
2023-04-25 16:32:51 +02:00
|
|
|
// TODO(ritave): Figure out why the version 10.25.0-beta.1-flask.0 in the below comment is even possible
|
|
|
|
// since those are two different build types
|
2023-03-04 13:51:04 +01:00
|
|
|
// The version could be version: '10.25.0-beta.1-flask.0',
|
|
|
|
// That results in buildVersionSummary becomes 1-flask
|
|
|
|
// And we only want 1 from this string
|
|
|
|
buildVersion =
|
|
|
|
typeof buildVersionSummary === 'string'
|
|
|
|
? Number(buildVersionSummary.match(/\d+(?:\.\d+)?/u)[0])
|
|
|
|
: buildVersionSummary;
|
2021-10-06 19:44:48 +02:00
|
|
|
if (!String(buildVersion).match(/^\d+$/u)) {
|
|
|
|
throw new Error(`Invalid prerelease build version: '${buildVersion}'`);
|
2023-04-25 16:32:51 +02:00
|
|
|
} else if (!loadBuildTypesConfig().buildTypes[buildType].isPrerelease) {
|
2021-10-06 19:44:48 +02:00
|
|
|
throw new Error(`Invalid prerelease build type: ${buildType}`);
|
|
|
|
}
|
|
|
|
}
|
2021-09-08 22:08:23 +02:00
|
|
|
|
|
|
|
return platforms.reduce((platformMap, platform) => {
|
2021-10-06 19:44:48 +02:00
|
|
|
const versionParts = [major, minor, patch];
|
|
|
|
const browserSpecificVersion = {};
|
|
|
|
if (prerelease) {
|
|
|
|
if (platform === 'firefox') {
|
2022-01-03 17:18:10 +01:00
|
|
|
versionParts[2] = `${versionParts[2]}${buildType}${buildVersion}`;
|
2021-10-06 19:44:48 +02:00
|
|
|
} else {
|
|
|
|
versionParts.push(buildVersion);
|
2022-01-03 15:00:13 +01:00
|
|
|
browserSpecificVersion.version_name = version;
|
2021-10-06 19:44:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
browserSpecificVersion.version = versionParts.join('.');
|
|
|
|
platformMap[platform] = browserSpecificVersion;
|
2021-09-08 22:08:23 +02:00
|
|
|
return platformMap;
|
|
|
|
}, {});
|
|
|
|
}
|
|
|
|
|
Add validation to production build script (#15468)
Validation has been added to the build script when the "prod" target is
selected. We now ensure that all expected environment variables are
set, and that no extra environment variables are present (which might
indicate that the wrong configuration file is being used).
The `prod` target uses a new `.metamaskprodrc` configuration file. Each
required variable can be specified either via environment variable or
via this config file. CI will continue set these via environment
variable, but for local manual builds we can use the config file to
simplify the build process and ensure consistency.
A new "dist" target has been added to preserve the ability to build a
"production-like" build without this validation.
The config validation is invoked early in the script, in the CLI
argument parsing step, so that it would fail more quickly. Otherwise
we'd have to wait a few minutes longer for the validation to run.
This required some refactoring, moving functions to the utility module
and moving the config to a dedicated module.
Additionally, support has been added for all environment variables to
be set via the config file. Previously the values `PUBNUB_PUB_KEY`,
`PUBNUB_SUB_KEY`, `SENTRY_DSN`, and `SWAPS_USE_DEV_APIS` could only be
set via environment variable. Now, all of these variables can be set
either way.
Closes #15003
2022-08-19 20:16:18 +02:00
|
|
|
/**
|
|
|
|
* Get the environment of the current build.
|
|
|
|
*
|
|
|
|
* @param {object} options - Build options.
|
|
|
|
* @param {BUILD_TARGETS} options.buildTarget - The target of the current build.
|
|
|
|
* @returns {ENVIRONMENT} The current build environment.
|
|
|
|
*/
|
|
|
|
function getEnvironment({ buildTarget }) {
|
|
|
|
// get environment slug
|
|
|
|
if (buildTarget === BUILD_TARGETS.PROD) {
|
|
|
|
return ENVIRONMENT.PRODUCTION;
|
|
|
|
} else if (isDevBuild(buildTarget)) {
|
|
|
|
return ENVIRONMENT.DEVELOPMENT;
|
|
|
|
} else if (isTestBuild(buildTarget)) {
|
|
|
|
return ENVIRONMENT.TESTING;
|
|
|
|
} else if (
|
|
|
|
/^Version-v(\d+)[.](\d+)[.](\d+)/u.test(process.env.CIRCLE_BRANCH)
|
|
|
|
) {
|
|
|
|
return ENVIRONMENT.RELEASE_CANDIDATE;
|
|
|
|
} else if (process.env.CIRCLE_BRANCH === 'develop') {
|
|
|
|
return ENVIRONMENT.STAGING;
|
|
|
|
} else if (process.env.CIRCLE_PULL_REQUEST) {
|
|
|
|
return ENVIRONMENT.PULL_REQUEST;
|
|
|
|
}
|
|
|
|
return ENVIRONMENT.OTHER;
|
|
|
|
}
|
|
|
|
|
2022-08-06 09:33:35 +02:00
|
|
|
/**
|
|
|
|
* Log an error to the console.
|
|
|
|
*
|
|
|
|
* This function includes a workaround for a SES bug that results in errors
|
|
|
|
* being printed to the console as `{}`. The workaround is to print the stack
|
|
|
|
* instead, which does work correctly.
|
|
|
|
*
|
|
|
|
* @see {@link https://github.com/endojs/endo/issues/944}
|
|
|
|
* @param {Error} error - The error to print
|
|
|
|
*/
|
|
|
|
function logError(error) {
|
|
|
|
console.error(error.stack || error);
|
|
|
|
}
|
|
|
|
|
2023-01-24 18:00:35 +01:00
|
|
|
/**
|
|
|
|
* This function wrapAgainstScuttling() tries to generically wrap given code
|
|
|
|
* with an environment that allows it to still function under a scuttled environment.
|
|
|
|
*
|
|
|
|
* It's only (current) use is for sentry code which runs before scuttling happens but
|
|
|
|
* later on still leans on properties of the global object which at that point are scuttled.
|
|
|
|
*
|
|
|
|
* To accomplish that, we wrap the entire provided code with the good old with-proxy trick,
|
|
|
|
* which helps us capture access attempts like (1) window.fetch/globalThis.fetch and (2) fetch.
|
|
|
|
*
|
|
|
|
* wrapAgainstScuttling() function also accepts a bag of the global object's properties the
|
|
|
|
* code needs in order to properly function, and within our proxy we make sure to
|
|
|
|
* return those whenever the code goes through our proxy asking for them.
|
|
|
|
*
|
|
|
|
* Specifically when the code tries to set properties to the global object,
|
|
|
|
* in addition to the preconfigured properties, we also accept any property
|
|
|
|
* starting with on to support global event handlers settings.
|
|
|
|
*
|
|
|
|
* Also, sentry invokes functions dynamically using Function.prototype's call and apply,
|
|
|
|
* and our proxy messes with their this when that happens, so these two required a tailor-made patch.
|
|
|
|
*
|
|
|
|
* @param content - contents of the js code to wrap
|
|
|
|
* @param bag - bag of global object properties to provide to the wrapped js code
|
|
|
|
* @returns {string} wrapped js code
|
|
|
|
*/
|
|
|
|
function wrapAgainstScuttling(content, bag = {}) {
|
|
|
|
return `
|
|
|
|
{
|
|
|
|
function setupProxy(global) {
|
|
|
|
// bag of properties to allow vetted shim to access,
|
|
|
|
// mapped to their correct this value if needed
|
|
|
|
const bag = ${JSON.stringify(bag)};
|
|
|
|
// setup vetted shim bag of properties
|
|
|
|
for (const prop in bag) {
|
|
|
|
const that = bag[prop];
|
|
|
|
let api = global[prop];
|
|
|
|
if (that) api = api.bind(global[that]);
|
|
|
|
bag[prop] = api;
|
|
|
|
}
|
|
|
|
// setup proxy for the vetted shim to go through
|
|
|
|
const proxy = new Proxy(bag, {
|
|
|
|
set: function set(target, prop, value) {
|
|
|
|
if (bag.hasOwnProperty(prop) || prop.startsWith('on')) {
|
2023-02-28 12:29:24 +01:00
|
|
|
return (bag[prop] = global[prop] = value) || true;
|
2023-01-24 18:00:35 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
});
|
|
|
|
// make sure bind() and apply() are applied with
|
|
|
|
// proxy target rather than proxy receiver
|
|
|
|
(function(target, receiver) {
|
|
|
|
'use strict'; // to work with ses lockdown
|
|
|
|
function wrap(obj, prop, target, receiver) {
|
|
|
|
const real = obj[prop];
|
|
|
|
obj[prop] = function(that) {
|
|
|
|
if (that === receiver) that = target;
|
|
|
|
const args = [].slice.call(arguments, 1);
|
|
|
|
return real.call(this, that, ...args);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
wrap(Function.prototype, 'bind', target, receiver);
|
|
|
|
wrap(Function.prototype, 'apply', target, receiver);
|
|
|
|
} (global, proxy));
|
|
|
|
return proxy;
|
|
|
|
}
|
|
|
|
const proxy = setupProxy(globalThis);
|
|
|
|
with (proxy) {
|
|
|
|
with ({window: proxy, self: proxy, globalThis: proxy}) {
|
|
|
|
${content}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
`;
|
|
|
|
}
|
|
|
|
|
2022-11-30 16:19:45 +01:00
|
|
|
/**
|
|
|
|
* Get the path of a file or folder inside the node_modules folder
|
|
|
|
*
|
|
|
|
* require.resolve was causing errors on Windows, once the paths were fed into fast-glob
|
|
|
|
* (The backslashes had to be converted to forward-slashes)
|
|
|
|
* This helper function was written to fix the Windows problem, and also end reliance on writing paths that start with './node_modules/'
|
|
|
|
*
|
|
|
|
* @see {@link https://github.com/MetaMask/metamask-extension/pull/16550}
|
|
|
|
* @param {string} packageName - The name of the package, such as '@lavamoat/lavapack'
|
|
|
|
* @param {string} pathToFiles - The path of the file or folder inside the package, optionally starting with /
|
|
|
|
*/
|
|
|
|
function getPathInsideNodeModules(packageName, pathToFiles) {
|
|
|
|
let targetPath = path.dirname(require.resolve(`${packageName}/package.json`));
|
|
|
|
|
|
|
|
targetPath = path.join(targetPath, pathToFiles);
|
|
|
|
|
|
|
|
// Force POSIX separators
|
|
|
|
targetPath = targetPath.split(path.sep).join(path.posix.sep);
|
|
|
|
|
|
|
|
return targetPath;
|
|
|
|
}
|
|
|
|
|
2021-09-08 22:08:23 +02:00
|
|
|
module.exports = {
|
2021-10-06 19:44:48 +02:00
|
|
|
getBrowserVersionMap,
|
Add validation to production build script (#15468)
Validation has been added to the build script when the "prod" target is
selected. We now ensure that all expected environment variables are
set, and that no extra environment variables are present (which might
indicate that the wrong configuration file is being used).
The `prod` target uses a new `.metamaskprodrc` configuration file. Each
required variable can be specified either via environment variable or
via this config file. CI will continue set these via environment
variable, but for local manual builds we can use the config file to
simplify the build process and ensure consistency.
A new "dist" target has been added to preserve the ability to build a
"production-like" build without this validation.
The config validation is invoked early in the script, in the CLI
argument parsing step, so that it would fail more quickly. Otherwise
we'd have to wait a few minutes longer for the validation to run.
This required some refactoring, moving functions to the utility module
and moving the config to a dedicated module.
Additionally, support has been added for all environment variables to
be set via the config file. Previously the values `PUBNUB_PUB_KEY`,
`PUBNUB_SUB_KEY`, `SENTRY_DSN`, and `SWAPS_USE_DEV_APIS` could only be
set via environment variable. Now, all of these variables can be set
either way.
Closes #15003
2022-08-19 20:16:18 +02:00
|
|
|
getEnvironment,
|
|
|
|
isDevBuild,
|
|
|
|
isTestBuild,
|
2022-08-06 09:33:35 +02:00
|
|
|
logError,
|
2022-11-30 16:19:45 +01:00
|
|
|
getPathInsideNodeModules,
|
2023-01-24 18:00:35 +01:00
|
|
|
wrapAgainstScuttling,
|
2021-09-08 22:08:23 +02:00
|
|
|
};
|