Skip to content

Commit

Permalink
Add getNextVersionFromTags
Browse files Browse the repository at this point in the history
Summary:
Changelog: [Internal] - Add getNextVersionFromTags to determine next release version off a release branch

In more detail - this work is part of an effort to automate the release process by using a push to a release branch as a trigger to prepare, package and deploy react-native to npm from CircleCI

This function is later used in `prepare-package-for-release` script in D32556610 to bump the version

Reviewed By: cortinico, ShikaSD

Differential Revision: D32556609

fbshipit-source-id: 7d93ead0b34318a58ffeb876715fbd34d6041f4e
  • Loading branch information
Luna Wei committed Dec 6, 2021
1 parent 87592fb commit 9faa42e
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
30 changes: 29 additions & 1 deletion scripts/__tests__/version-utils-test.js
Expand Up @@ -7,9 +7,37 @@
* @format
*/

const {parseVersion} = require('../version-utils');
const {parseVersion, getNextVersionFromTags} = require('../version-utils');

let execResult = null;
jest.mock('shelljs', () => ({
exec: () => {
return {
stdout: execResult,
};
},
}));

describe('version-utils', () => {
describe('getNextVersionFromTags', () => {
it('should increment last stable tag', () => {
execResult =
'v0.66.3\nv0.66.2\nv0.66.1\nv0.66.0-rc.4\nv0.66.0-rc.3\nv0.66.0-rc.2\nv0.66.0-rc.1\nv0.66.0-rc.0';
expect(getNextVersionFromTags('0.66-stable')).toBe('0.66.4');
});

it('should find last prerelease tag and increment', () => {
execResult =
'v0.66.0-rc.4\nv0.66.0-rc.3\nv0.66.0-rc.2\nv0.66.0-rc.1\nv0.66.0-rc.0';
expect(getNextVersionFromTags('0.66-stable')).toBe('0.66.0-rc.5');
});

it('should return rc.0 version if no previous tags', () => {
execResult = '\n';
expect(getNextVersionFromTags('0.66-stable')).toBe('0.66.0-rc.0');
});
});

describe('parseVersion', () => {
it('should throw error if invalid match', () => {
function testInvalidVersion() {
Expand Down
45 changes: 45 additions & 0 deletions scripts/version-utils.js
Expand Up @@ -7,6 +7,8 @@
* @format
*/

const {exec} = require('shelljs');

function parseVersion(versionStr) {
const match = versionStr.match(/^v?((\d+)\.(\d+)\.(\d+)(?:-(.+))?)$/);
if (!match) {
Expand All @@ -24,6 +26,49 @@ function parseVersion(versionStr) {
};
}

function getLatestVersionTag(branchVersion) {
// Returns list of tags like ["v0.67.2", "v0.67.1", "v0.67.0-rc.3", "v0.67.0-rc.2", ...] in reverse lexical order
const tags = exec(`git tag --list "v${branchVersion}*" --sort=-refname`, {
silent: true,
})
.stdout.trim()
.split('\n')
.filter(tag => tag.length > 0);

// If there are no tags, return null
if (tags.length === 0) {
return null;
}

// Return most recent tag (with the "v" prefix)
return tags[0];
}

function getNextVersionFromTags(branch) {
// Assumption that branch names will follow pattern `{major}.{minor}-stable`
// Ex. "0.67-stable" -> "0.67"
const branchVersion = branch.replace('-stable', '');

// Get the latest version tag of the release branch
const versionTag = getLatestVersionTag(branchVersion);

// If there are no tags , we assume this is the first pre-release
if (versionTag == null) {
return `${branchVersion}.0-rc.0`;
}

const {major, minor, patch, prerelease} = parseVersion(versionTag);
if (prerelease != null) {
// prelease is of the form "rc.X"
const prereleasePatch = parseInt(prerelease.slice(3), 10);
return `${major}.${minor}.${patch}-rc.${prereleasePatch + 1}`;
}

// If not prerelease, increment the patch version
return `${major}.${minor}.${parseInt(patch, 10) + 1}`;
}

module.exports = {
parseVersion,
getNextVersionFromTags,
};

0 comments on commit 9faa42e

Please sign in to comment.