Migrate beta version to the main version field (#12246)

The main `version` field in `package.json` will now include the beta
version (if present) rather than it being passed in via the CLI when
building. The `version` field is now a fully SemVer-compatible version,
with the added restriction that any prerelease portion of the version
must match the format `<build type>.<build version>`.

This brings the build in-line with the future release process we will
be using for the beta version. The plan is for each future release to
enter a "beta phase" where the version would get updated to reflect
that it's a beta, and we would increment this beta version over time as
we update the beta. The manifest gives us a place to store this beta
version. It was also important to replace the automatic minor bump
logic that was being used previously, because the version in beta might
not be a minor bump.

Additionally, the filename logic used for beta builds was updated to
be generic across all build types rather than beta-specific. This will
be useful for Flask builds in the future.
feature/default_network_editable
Mark Stacey 3 years ago committed by GitHub
parent 822ce5b8b0
commit 3a5538bd50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      app/manifest/_beta_modifications.json
  2. 2
      development/build/README.md
  3. 24
      development/build/etc.js
  4. 24
      development/build/index.js
  5. 28
      development/build/manifest.js
  6. 73
      development/build/utils.js
  7. 10
      lavamoat/node/policy.json
  8. 1
      package.json

@ -22,6 +22,5 @@
"512": "images/icon-512.png"
},
"name": "__MSG_appName__ Beta",
"short_name": "__MSG_appName__ Beta",
"version": ""
"short_name": "__MSG_appName__ Beta"
}

@ -40,8 +40,6 @@ Commands:
e2e tests.
Options:
--beta-version If the build type is "beta", the beta version number.
[number] [default: 0]
--build-type The "type" of build to create. One of: "beta", "main"
[string] [default: "main"]
--lint-fence-files Whether files with code fences should be linted after

@ -5,18 +5,12 @@ const del = require('del');
const pify = require('pify');
const pump = pify(require('pump'));
const { version } = require('../../package.json');
const { createTask, composeParallel } = require('./task');
const { BuildTypes } = require('./utils');
module.exports = createEtcTasks;
function createEtcTasks({
betaVersionsMap,
browserPlatforms,
buildType,
livereload,
}) {
function createEtcTasks({ browserPlatforms, buildType, livereload }) {
const clean = createTask('clean', async function clean() {
await del(['./dist/*']);
await Promise.all(
@ -34,23 +28,19 @@ function createEtcTasks({
const zip = createTask(
'zip',
composeParallel(
...browserPlatforms.map((platform) =>
createZipTask(
platform,
buildType === BuildTypes.beta ? betaVersionsMap[platform] : undefined,
),
),
...browserPlatforms.map((platform) => createZipTask(platform, buildType)),
),
);
return { clean, reload, zip };
}
function createZipTask(platform, betaVersion) {
function createZipTask(platform, buildType) {
return async () => {
const path = betaVersion
? `metamask-BETA-${platform}-${betaVersion}`
: `metamask-${platform}-${version}`;
const path =
buildType === BuildTypes.main
? `metamask-${platform}-${version}`
: `metamask-${buildType}-${platform}-${version}`;
await pump(
gulp.src(`dist/${platform}/**`),
gulpZip(`${path}.zip`),

@ -5,7 +5,6 @@
//
const livereload = require('gulp-livereload');
const minimist = require('minimist');
const { version } = require('../../package.json');
const {
createTask,
composeSeries,
@ -17,7 +16,7 @@ const createScriptTasks = require('./scripts');
const createStyleTasks = require('./styles');
const createStaticAssetTasks = require('./static');
const createEtcTasks = require('./etc');
const { BuildTypes, getNextBetaVersionMap } = require('./utils');
const { BuildTypes, getBrowserVersionMap } = require('./utils');
// packages required dynamically via browserify configuration in dependencies
require('loose-envify');
@ -34,7 +33,6 @@ defineAndRunBuildTasks();
function defineAndRunBuildTasks() {
const {
betaVersion,
buildType,
entryTask,
isLavaMoat,
@ -45,14 +43,7 @@ function defineAndRunBuildTasks() {
const browserPlatforms = ['firefox', 'chrome', 'brave', 'opera'];
let betaVersionsMap;
if (buildType === BuildTypes.beta) {
betaVersionsMap = getNextBetaVersionMap(
version,
betaVersion,
browserPlatforms,
);
}
const browserVersionMap = getBrowserVersionMap(browserPlatforms);
const staticTasks = createStaticAssetTasks({
livereload,
@ -63,7 +54,7 @@ function defineAndRunBuildTasks() {
const manifestTasks = createManifestTasks({
browserPlatforms,
betaVersionsMap,
browserVersionMap,
buildType,
});
@ -80,7 +71,6 @@ function defineAndRunBuildTasks() {
const { clean, reload, zip } = createEtcTasks({
livereload,
browserPlatforms,
betaVersionsMap,
buildType,
});
@ -145,7 +135,6 @@ function defineAndRunBuildTasks() {
function parseArgv() {
const NamedArgs = {
BetaVersion: 'beta-version',
BuildType: 'build-type',
LintFenceFiles: 'lint-fence-files',
OmitLockdown: 'omit-lockdown',
@ -160,7 +149,6 @@ function parseArgv() {
],
string: [NamedArgs.BuildType],
default: {
[NamedArgs.BetaVersion]: 0,
[NamedArgs.BuildType]: BuildTypes.main,
[NamedArgs.LintFenceFiles]: true,
[NamedArgs.OmitLockdown]: false,
@ -179,11 +167,6 @@ function parseArgv() {
throw new Error('MetaMask build: No entry task specified.');
}
const betaVersion = argv[NamedArgs.BetaVersion];
if (!Number.isInteger(betaVersion) || betaVersion < 0) {
throw new Error(`MetaMask build: Invalid beta version: "${betaVersion}"`);
}
const buildType = argv[NamedArgs.BuildType];
if (!(buildType in BuildTypes)) {
throw new Error(`MetaMask build: Invalid build type: "${buildType}"`);
@ -197,7 +180,6 @@ function parseArgv() {
: !/dev/iu.test(entryTask);
return {
betaVersion: String(betaVersion),
buildType,
entryTask,
isLavaMoat: process.argv[0].includes('lavamoat'),

@ -3,7 +3,6 @@ const path = require('path');
const { merge, cloneDeep } = require('lodash');
const baseManifest = require('../../app/manifest/_base.json');
const { version } = require('../../package.json');
const betaManifestModifications = require('../../app/manifest/_beta_modifications.json');
const { createTask, composeSeries } = require('./task');
@ -11,7 +10,11 @@ const { BuildTypes } = require('./utils');
module.exports = createManifestTasks;
function createManifestTasks({ betaVersionsMap, browserPlatforms, buildType }) {
function createManifestTasks({
browserPlatforms,
browserVersionMap,
buildType,
}) {
// merge base manifest with per-platform manifests
const prepPlatforms = async () => {
return Promise.all(
@ -29,9 +32,8 @@ function createManifestTasks({ betaVersionsMap, browserPlatforms, buildType }) {
const result = merge(
cloneDeep(baseManifest),
platformModifications,
buildType === BuildTypes.beta
? getBetaModifications(platform, betaVersionsMap)
: { version },
browserVersionMap[platform],
getBuildModifications(buildType),
);
const dir = path.join('.', 'dist', platform);
await fs.mkdir(dir, { recursive: true });
@ -110,16 +112,10 @@ async function writeJson(obj, file) {
return fs.writeFile(file, JSON.stringify(obj, null, 2));
}
function getBetaModifications(platform, betaVersionsMap) {
if (!betaVersionsMap || typeof betaVersionsMap !== 'object') {
throw new Error('MetaMask build: Expected object beta versions map.');
function getBuildModifications(buildType) {
const buildModifications = {};
if (buildType === BuildTypes.beta) {
Object.assign(buildModifications, betaManifestModifications);
}
const betaVersion = betaVersionsMap[platform];
return {
...betaManifestModifications,
version: betaVersion,
...(platform === 'firefox' ? {} : { version_name: 'beta' }),
};
return buildModifications;
}

@ -1,32 +1,63 @@
const semver = require('semver');
const { version } = require('../../package.json');
const BuildTypes = {
beta: 'beta',
flask: 'flask',
main: 'main',
};
/**
* @returns {Object} An object with browser as key and next version of beta
* as the value. E.g. { firefox: '9.6.0.beta0', chrome: '9.6.0.1' }
* 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} currentVersion - The current version.
* @param {string[]} platforms - A list of browsers to generate versions for.
* @returns {Object} An object with the browser as the key and the browser-specific version object
* as the value. For example, the version `9.6.0-beta.1` would return the object
* `{ firefox: { version: '9.6.0.beta1' }, chrome: { version: '9.6.0.1', version_name: 'beta' } }`.
*/
function getNextBetaVersionMap(currentVersion, betaVersion, platforms) {
const [major, minor] = currentVersion.split('.');
function getBrowserVersionMap(platforms) {
const major = semver.major(version);
const minor = semver.minor(version);
const patch = semver.patch(version);
const prerelease = semver.prerelease(version);
let buildType;
let buildVersion;
if (prerelease) {
if (prerelease.length !== 2) {
throw new Error(`Invalid prerelease version: '${prerelease.join('.')}'`);
}
[buildType, buildVersion] = prerelease;
if (!String(buildVersion).match(/^\d+$/u)) {
throw new Error(`Invalid prerelease build version: '${buildVersion}'`);
} else if (buildType !== BuildTypes.beta) {
throw new Error(`Invalid prerelease build type: ${buildType}`);
}
}
return platforms.reduce((platformMap, platform) => {
platformMap[platform] = [
// Keeps the current major
major,
// Bump the minor version
Number(minor) + 1,
// This isn't typically used
0,
// The beta number
`${platform === 'firefox' ? 'beta' : ''}${betaVersion}`,
].join('.');
const versionParts = [major, minor, patch];
const browserSpecificVersion = {};
if (prerelease) {
if (platform === 'firefox') {
versionParts.push(`${buildType}${buildVersion}`);
} else {
versionParts.push(buildVersion);
browserSpecificVersion.version_name = buildType;
}
}
browserSpecificVersion.version = versionParts.join('.');
platformMap[platform] = browserSpecificVersion;
return platformMap;
}, {});
}
const BuildTypes = {
beta: 'beta',
flask: 'flask',
main: 'main',
};
module.exports = {
BuildTypes,
getNextBetaVersionMap,
getBrowserVersionMap,
};

@ -2940,6 +2940,11 @@
"js-tokens": true
}
},
"lru-cache": {
"packages": {
"yallist": true
}
},
"lru-queue": {
"packages": {
"es5-ext": true
@ -3815,6 +3820,9 @@
"globals": {
"console": true,
"process": true
},
"packages": {
"lru-cache": true
}
},
"set-value": {
@ -4684,4 +4692,4 @@
}
}
}
}
}

@ -316,6 +316,7 @@
"sass": "^1.32.4",
"sass-loader": "^10.1.1",
"selenium-webdriver": "4.0.0-alpha.7",
"semver": "^7.3.5",
"serve-handler": "^6.1.2",
"sinon": "^9.0.0",
"source-map": "^0.7.2",

Loading…
Cancel
Save