version-utils.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. const semver = require('semver');
  2. const { GitProcess } = require('dugite');
  3. const { ELECTRON_DIR } = require('../lib/utils');
  4. const preType = {
  5. NONE: 'none',
  6. PARTIAL: 'partial',
  7. FULL: 'full'
  8. };
  9. const getCurrentDate = () => {
  10. const d = new Date();
  11. const dd = `${d.getDate()}`.padStart(2, '0');
  12. const mm = `${d.getMonth() + 1}`.padStart(2, '0');
  13. const yyyy = d.getFullYear();
  14. return `${yyyy}${mm}${dd}`;
  15. };
  16. const isNightly = v => v.includes('nightly');
  17. const isAlpha = v => v.includes('alpha');
  18. const isBeta = v => v.includes('beta');
  19. const isStable = v => {
  20. const parsed = semver.parse(v);
  21. return !!(parsed && parsed.prerelease.length === 0);
  22. };
  23. const makeVersion = (components, delim, pre = preType.NONE) => {
  24. let version = [components.major, components.minor, components.patch].join(delim);
  25. if (pre === preType.PARTIAL) {
  26. version += `${delim}${components.pre[1] || 0}`;
  27. } else if (pre === preType.FULL) {
  28. version += `-${components.pre[0]}${delim}${components.pre[1]}`;
  29. }
  30. return version;
  31. };
  32. async function nextAlpha (v) {
  33. const next = semver.coerce(semver.clean(v));
  34. const tagBlob = await GitProcess.exec(['tag', '--list', '-l', `v${next}-alpha.*`], ELECTRON_DIR);
  35. const tags = tagBlob.stdout.split('\n').filter(e => e !== '');
  36. tags.sort((t1, t2) => {
  37. const a = parseInt(t1.split('.').pop(), 10);
  38. const b = parseInt(t2.split('.').pop(), 10);
  39. return a - b;
  40. });
  41. // increment the latest existing alpha tag or start at alpha.1 if it's a new alpha line
  42. return tags.length === 0 ? `${next}-alpha.1` : semver.inc(tags.pop(), 'prerelease');
  43. }
  44. async function nextBeta (v) {
  45. const next = semver.coerce(semver.clean(v));
  46. const tagBlob = await GitProcess.exec(['tag', '--list', '-l', `v${next}-beta.*`], ELECTRON_DIR);
  47. const tags = tagBlob.stdout.split('\n').filter(e => e !== '');
  48. tags.sort((t1, t2) => {
  49. const a = parseInt(t1.split('.').pop(), 10);
  50. const b = parseInt(t2.split('.').pop(), 10);
  51. return a - b;
  52. });
  53. // increment the latest existing beta tag or start at beta.1 if it's a new beta line
  54. return tags.length === 0 ? `${next}-beta.1` : semver.inc(tags.pop(), 'prerelease');
  55. }
  56. async function nextNightly (v) {
  57. let next = semver.valid(semver.coerce(v));
  58. const pre = `nightly.${getCurrentDate()}`;
  59. const branch = (await GitProcess.exec(['rev-parse', '--abbrev-ref', 'HEAD'], ELECTRON_DIR)).stdout.trim();
  60. if (branch === 'main') {
  61. next = semver.inc(await getLastMajorForMain(), 'major');
  62. } else if (isStable(v)) {
  63. next = semver.inc(next, 'patch');
  64. }
  65. return `${next}-${pre}`;
  66. }
  67. async function getLastMajorForMain () {
  68. let branchNames;
  69. const result = await GitProcess.exec(['branch', '-a', '--remote', '--list', 'origin/[0-9]*-x-y'], ELECTRON_DIR);
  70. if (result.exitCode === 0) {
  71. branchNames = result.stdout.trim().split('\n');
  72. const filtered = branchNames.map(b => b.replace('origin/', ''));
  73. return getNextReleaseBranch(filtered);
  74. } else {
  75. throw new Error('Release branches could not be fetched.');
  76. }
  77. }
  78. function getNextReleaseBranch (branches) {
  79. const converted = branches.map(b => b.replace(/-/g, '.').replace('x', '0').replace('y', '0'));
  80. return converted.reduce((v1, v2) => semver.gt(v1, v2) ? v1 : v2);
  81. }
  82. module.exports = {
  83. isStable,
  84. isAlpha,
  85. isBeta,
  86. isNightly,
  87. nextAlpha,
  88. nextBeta,
  89. makeVersion,
  90. nextNightly,
  91. preType
  92. };