2020-03-20 20:28:31 +00:00
|
|
|
const path = require('path');
|
|
|
|
const fs = require('fs');
|
|
|
|
const semver = require('semver');
|
|
|
|
const { GitProcess } = require('dugite');
|
|
|
|
const { promisify } = require('util');
|
2018-12-06 19:00:10 +00:00
|
|
|
|
2020-03-20 20:28:31 +00:00
|
|
|
const { ELECTRON_DIR } = require('../lib/utils');
|
2019-06-24 17:18:04 +00:00
|
|
|
|
2020-03-20 20:28:31 +00:00
|
|
|
const readFile = promisify(fs.readFile);
|
2018-12-06 19:00:10 +00:00
|
|
|
|
2019-01-07 21:41:07 +00:00
|
|
|
const preType = {
|
|
|
|
NONE: 'none',
|
|
|
|
PARTIAL: 'partial',
|
|
|
|
FULL: 'full'
|
2020-03-20 20:28:31 +00:00
|
|
|
};
|
2019-01-07 21:41:07 +00:00
|
|
|
|
2018-12-06 19:00:10 +00:00
|
|
|
const getCurrentDate = () => {
|
2020-03-20 20:28:31 +00:00
|
|
|
const d = new Date();
|
|
|
|
const dd = `${d.getDate()}`.padStart(2, '0');
|
|
|
|
const mm = `${d.getMonth() + 1}`.padStart(2, '0');
|
|
|
|
const yyyy = d.getFullYear();
|
|
|
|
return `${yyyy}${mm}${dd}`;
|
|
|
|
};
|
|
|
|
|
|
|
|
const isNightly = v => v.includes('nightly');
|
2021-07-20 00:58:15 +00:00
|
|
|
const isAlpha = v => v.includes('alpha');
|
2020-03-20 20:28:31 +00:00
|
|
|
const isBeta = v => v.includes('beta');
|
2018-12-06 19:00:10 +00:00
|
|
|
const isStable = v => {
|
2020-03-20 20:28:31 +00:00
|
|
|
const parsed = semver.parse(v);
|
|
|
|
return !!(parsed && parsed.prerelease.length === 0);
|
|
|
|
};
|
2018-12-06 19:00:10 +00:00
|
|
|
|
2019-01-07 21:41:07 +00:00
|
|
|
const makeVersion = (components, delim, pre = preType.NONE) => {
|
2020-03-20 20:28:31 +00:00
|
|
|
let version = [components.major, components.minor, components.patch].join(delim);
|
2019-01-07 21:41:07 +00:00
|
|
|
if (pre === preType.PARTIAL) {
|
2020-03-20 20:28:31 +00:00
|
|
|
version += `${delim}${components.pre[1] || 0}`;
|
2019-01-07 21:41:07 +00:00
|
|
|
} else if (pre === preType.FULL) {
|
2020-03-20 20:28:31 +00:00
|
|
|
version += `-${components.pre[0]}${delim}${components.pre[1]}`;
|
2018-12-06 19:00:10 +00:00
|
|
|
}
|
2020-03-20 20:28:31 +00:00
|
|
|
return version;
|
|
|
|
};
|
2018-12-06 19:00:10 +00:00
|
|
|
|
2021-07-20 00:58:15 +00:00
|
|
|
async function nextAlpha (v) {
|
2020-03-20 20:28:31 +00:00
|
|
|
const next = semver.coerce(semver.clean(v));
|
2021-07-20 00:58:15 +00:00
|
|
|
const tagBlob = await GitProcess.exec(['tag', '--list', '-l', `v${next}-alpha.*`], ELECTRON_DIR);
|
|
|
|
const tags = tagBlob.stdout.split('\n').filter(e => e !== '');
|
|
|
|
tags.sort((t1, t2) => {
|
|
|
|
const a = parseInt(t1.split('.').pop(), 10);
|
|
|
|
const b = parseInt(t2.split('.').pop(), 10);
|
|
|
|
return a - b;
|
|
|
|
});
|
|
|
|
|
|
|
|
// increment the latest existing alpha tag or start at alpha.1 if it's a new alpha line
|
|
|
|
return tags.length === 0 ? `${next}-alpha.1` : semver.inc(tags.pop(), 'prerelease');
|
|
|
|
}
|
2018-12-06 19:00:10 +00:00
|
|
|
|
2021-07-20 00:58:15 +00:00
|
|
|
async function nextBeta (v) {
|
|
|
|
const next = semver.coerce(semver.clean(v));
|
2020-03-20 20:28:31 +00:00
|
|
|
const tagBlob = await GitProcess.exec(['tag', '--list', '-l', `v${next}-beta.*`], ELECTRON_DIR);
|
|
|
|
const tags = tagBlob.stdout.split('\n').filter(e => e !== '');
|
2020-03-24 13:04:12 +00:00
|
|
|
tags.sort((t1, t2) => {
|
|
|
|
const a = parseInt(t1.split('.').pop(), 10);
|
|
|
|
const b = parseInt(t2.split('.').pop(), 10);
|
|
|
|
return a - b;
|
|
|
|
});
|
2018-12-06 19:00:10 +00:00
|
|
|
|
|
|
|
// increment the latest existing beta tag or start at beta.1 if it's a new beta line
|
2020-03-20 20:28:31 +00:00
|
|
|
return tags.length === 0 ? `${next}-beta.1` : semver.inc(tags.pop(), 'prerelease');
|
2018-12-06 19:00:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async function nextNightly (v) {
|
2020-03-20 20:28:31 +00:00
|
|
|
let next = semver.valid(semver.coerce(v));
|
|
|
|
const pre = `nightly.${getCurrentDate()}`;
|
2018-12-06 19:00:10 +00:00
|
|
|
|
2020-03-20 20:28:31 +00:00
|
|
|
const branch = (await GitProcess.exec(['rev-parse', '--abbrev-ref', 'HEAD'], ELECTRON_DIR)).stdout.trim();
|
2021-05-28 00:32:37 +00:00
|
|
|
// TODO(main-migration): Simplify once main branch is renamed
|
|
|
|
if (branch === 'master' || branch === 'main') {
|
|
|
|
next = semver.inc(await getLastMajorForMain(), 'major');
|
2018-12-06 19:00:10 +00:00
|
|
|
} else if (isStable(v)) {
|
2020-03-20 20:28:31 +00:00
|
|
|
next = semver.inc(next, 'patch');
|
2018-12-06 19:00:10 +00:00
|
|
|
}
|
|
|
|
|
2020-03-20 20:28:31 +00:00
|
|
|
return `${next}-${pre}`;
|
2018-12-06 19:00:10 +00:00
|
|
|
}
|
|
|
|
|
2021-05-28 00:32:37 +00:00
|
|
|
async function getLastMajorForMain () {
|
2020-03-20 20:28:31 +00:00
|
|
|
let branchNames;
|
|
|
|
const result = await GitProcess.exec(['branch', '-a', '--remote', '--list', 'origin/[0-9]*-x-y'], ELECTRON_DIR);
|
2019-06-24 17:18:04 +00:00
|
|
|
if (result.exitCode === 0) {
|
2020-03-20 20:28:31 +00:00
|
|
|
branchNames = result.stdout.trim().split('\n');
|
|
|
|
const filtered = branchNames.map(b => b.replace('origin/', ''));
|
|
|
|
return getNextReleaseBranch(filtered);
|
2019-06-24 17:18:04 +00:00
|
|
|
} else {
|
2020-03-20 20:28:31 +00:00
|
|
|
throw new Error('Release branches could not be fetched.');
|
2019-06-24 17:18:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getNextReleaseBranch (branches) {
|
2020-03-20 20:28:31 +00:00
|
|
|
const converted = branches.map(b => b.replace(/-/g, '.').replace('x', '0').replace('y', '0'));
|
|
|
|
return converted.reduce((v1, v2) => semver.gt(v1, v2) ? v1 : v2);
|
2019-06-24 17:18:04 +00:00
|
|
|
}
|
|
|
|
|
2018-12-06 19:00:10 +00:00
|
|
|
module.exports = {
|
|
|
|
isStable,
|
2021-07-20 00:58:15 +00:00
|
|
|
isAlpha,
|
2018-12-06 19:00:10 +00:00
|
|
|
isBeta,
|
|
|
|
isNightly,
|
2021-07-20 00:58:15 +00:00
|
|
|
nextAlpha,
|
2018-12-06 19:00:10 +00:00
|
|
|
nextBeta,
|
|
|
|
makeVersion,
|
2019-01-08 20:04:27 +00:00
|
|
|
nextNightly,
|
|
|
|
preType
|
2020-03-20 20:28:31 +00:00
|
|
|
};
|