git-release-manager
Version:
A tool to generate release notes from git commit history
439 lines • 19.4 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FlowManager = void 0;
const simple_git_1 = __importDefault(require("simple-git"));
const semver_1 = __importDefault(require("semver"));
class FlowManager {
constructor(config) {
var _a, _b, _c, _d;
this.git = (0, simple_git_1.default)();
this.defaultBaseVersion = '1.0.0';
this.config = {
tagPrefix: 'v',
releasePrefix: 'release/',
defaultDevChannel: 'dev',
defaultReleaseChannel: 'alpha',
strictTagBranch: true,
phases: {
dev: {
channels: {
dev: {
startBuildNumber: 1
},
}
},
qa: {
channels: {
alpha: {
startBuildNumber: 1
},
}
},
stage: {
channels: {
beta: {
startBuildNumber: 1
},
}
},
prod: {
channels: {
stabil: {
startBuildNumber: 1
},
}
}
}
};
if (config) {
this.config = {
...this.config,
...config,
phases: {
...this.config.phases,
...config.phases,
dev: {
channels: {
...this.config.phases.dev.channels,
...(_a = config.phases) === null || _a === void 0 ? void 0 : _a.dev.channels
}
},
qa: {
channels: {
...this.config.phases.qa.channels,
...(_b = config.phases) === null || _b === void 0 ? void 0 : _b.qa.channels
}
},
stage: {
channels: {
...this.config.phases.stage.channels,
...(_c = config.phases) === null || _c === void 0 ? void 0 : _c.stage.channels
}
},
prod: {
channels: {
...this.config.phases.prod.channels,
...(_d = config.phases) === null || _d === void 0 ? void 0 : _d.prod.channels
}
}
}
};
}
}
getVersionPart(version, options) {
var _a;
const parsedVersion = semver_1.default.parse(version);
if (!parsedVersion) {
return '';
}
if (options.print) {
switch (options.print) {
case 'base':
return `${parsedVersion.major}.${parsedVersion.minor}.${parsedVersion.patch}`;
case 'channel':
return `${parsedVersion.prerelease.join('.')}`;
case 'build':
return `${(_a = parsedVersion.prerelease[1]) === null || _a === void 0 ? void 0 : _a.toString()}` || '';
default:
return parsedVersion.version;
}
}
return parsedVersion.version;
}
async listBranchTags(branch, channel = null) {
try {
let tagArgs = [];
if (this.config.strictTagBranch) {
tagArgs.push("--merged");
tagArgs.push(branch);
}
const tags = await this.git.raw(['tag', ...tagArgs]);
let tagPattern = `${this.config.tagPrefix}[0-9]*\\.[0-9]*\\.[0-9]*`;
if (channel) {
tagPattern += `-${channel}\\.[0-9]*`;
}
const regexPattern = tagPattern.replace(/\\\*/g, '.*').replace(/\\\./g, '\\.');
const regex = new RegExp(`^${regexPattern}$`);
const tagList = tags
.split('\n')
.map((tag) => tag.trim())
.filter(tag => regex.test(tag));
return tagList;
}
catch (error) {
if (error instanceof Error) {
console.error(`Tag listing error: ${error.message}`);
}
else {
console.error('Tag listing error: Unknown error type');
}
return [];
}
}
async latestTagVersion(branch, channel = null, baseVersion = null) {
try {
const channelVersion = channel ? `${baseVersion}-${channel}` : baseVersion;
const tagList = await this.listBranchTags(branch, channel);
if (!tagList) {
return '';
}
let filteredTags = tagList;
if (channelVersion) {
filteredTags = (tagList === null || tagList === void 0 ? void 0 : tagList.filter(tag => tag.startsWith(channelVersion))) || [];
}
const latestTag = filteredTags.sort(semver_1.default.rcompare)[0];
if (!latestTag) {
return '';
}
const parsedVersion = semver_1.default.parse(latestTag);
return parsedVersion ? latestTag : '';
}
catch (error) {
console.error('Could not retrieve tags:', error instanceof Error ? error.message : error);
return '';
}
}
async listReleaseBranches(channel = null) {
try {
let branchPattern = `${this.config.releasePrefix}${this.config.tagPrefix}[0-9]*\\.[0-9]*\\.[0-9]*`;
if (channel) {
branchPattern += `-${channel}`;
}
const result = await this.git.raw(['branch', '--list', branchPattern]);
const regexPattern = branchPattern.replace(/\\\*/g, '.*').replace(/\\\./g, '\\.');
const regex = new RegExp(`^${regexPattern}$`);
const branches = result
.split('\n')
.map(line => line.replace('*', '').trim())
.filter(line => regex.test(line));
return branches;
}
catch (error) {
console.error(`Error listing branches: ${error}`);
return [];
}
}
async latestReleaseBranchVersion(channel = null) {
try {
const branches = await this.listReleaseBranches(channel);
const latestBranch = branches
.map(branch => branch.replace(this.config.releasePrefix, ''))
.map(branch => branch.replace(this.config.tagPrefix, ''))
.filter(version => semver_1.default.valid(version))
.sort(semver_1.default.rcompare)[0];
if (!latestBranch) {
return '';
}
const parsedVersion = semver_1.default.parse(latestBranch);
if (!parsedVersion) {
return '';
}
return latestBranch ? `${this.config.tagPrefix}${latestBranch}` : '';
}
catch (error) {
console.error('Could not retrieve tags:', error);
return '';
}
}
async DetermineDevPhaseVersion(branch, options) {
try {
const channel = this.config.defaultDevChannel;
let hasAnyDefaultReleaseChannelVersion = true;
let latestReleaseBranchVersion = await this.latestReleaseBranchVersion(this.config.defaultReleaseChannel);
if (!latestReleaseBranchVersion) {
latestReleaseBranchVersion = this.defaultBaseVersion;
hasAnyDefaultReleaseChannelVersion = false;
}
else {
latestReleaseBranchVersion = this.getVersionPart(latestReleaseBranchVersion, { print: 'base' });
}
const baseVersion = `${this.config.tagPrefix}${latestReleaseBranchVersion}`;
const latestChannelTagVersion = await this.latestTagVersion(branch, channel, baseVersion);
let result = '';
if (options.next) {
if (!hasAnyDefaultReleaseChannelVersion) {
if (!latestChannelTagVersion) {
result = `${this.config.tagPrefix}${this.defaultBaseVersion}-${channel}.${this.config.phases.dev.channels[channel].startBuildNumber}`;
}
else {
const incrementedVersion = semver_1.default.inc(latestChannelTagVersion, 'prerelease', channel);
result = `${this.config.tagPrefix}${incrementedVersion}`;
}
}
else {
// Compare release version with dev version
if (!latestChannelTagVersion || semver_1.default.gt(latestReleaseBranchVersion, latestChannelTagVersion)) {
// If release version is greater, bump the minor version from release version
const newBaseVersion = semver_1.default.inc(latestReleaseBranchVersion, 'minor');
result = `${this.config.tagPrefix}${newBaseVersion}-${channel}.${this.config.phases.dev.channels[channel].startBuildNumber}`;
}
else {
// Otherwise increment the channel number of the latest dev version
const incrementedDevVersion = semver_1.default.inc(latestChannelTagVersion, 'prerelease', channel);
result = `${this.config.tagPrefix}${incrementedDevVersion}`;
}
}
}
else if (options.current) {
if (!latestChannelTagVersion) {
result = `${baseVersion}-${channel}.${this.config.phases.dev.channels[channel].startBuildNumber}`;
}
else {
result = latestChannelTagVersion;
}
}
return `${this.config.tagPrefix}${this.getVersionPart(result, options)}`;
}
catch (error) {
if (error instanceof Error) {
console.error(`Tag listeleme hatası: ${error.message}`);
}
else {
console.error('Tag listeleme hatası: Bilinmeyen hata türü');
}
}
}
async DetermineQAPhaseVersion(channel, baseVersion, options) {
try {
if (!baseVersion) {
let latestReleaseBranchBaseVersion = await this.latestReleaseBranchVersion(channel);
if (!latestReleaseBranchBaseVersion) {
latestReleaseBranchBaseVersion = this.defaultBaseVersion;
}
else {
latestReleaseBranchBaseVersion = this.getVersionPart(latestReleaseBranchBaseVersion, { print: 'base' });
}
baseVersion = `${this.config.tagPrefix}${latestReleaseBranchBaseVersion}`;
}
const latestChannelTagVersion = await this.latestTagVersion(`${this.config.releasePrefix}${baseVersion}-${channel}`, channel, baseVersion);
let result = '';
if (options.next) {
if (!latestChannelTagVersion) {
result = `${baseVersion}-${channel}.${this.config.phases.qa.channels[channel].startBuildNumber}`;
}
else {
const incrementedVersion = semver_1.default.inc(latestChannelTagVersion, 'prerelease', channel);
result = `${this.config.tagPrefix}${incrementedVersion}`;
}
}
else if (options.nextRelease) {
if (!latestChannelTagVersion) {
result = `${baseVersion}-${channel}.${this.config.phases.qa.channels[channel].startBuildNumber}`;
}
else {
const incrementedVersion = semver_1.default.inc(baseVersion, 'minor');
result = `${this.config.tagPrefix}${incrementedVersion}-${channel}.${this.config.phases.qa.channels[channel].startBuildNumber}`;
}
}
else if (options.current) {
if (!latestChannelTagVersion) {
result = `${baseVersion}-${channel}.${this.config.phases.qa.channels[channel].startBuildNumber}`;
}
else {
result = latestChannelTagVersion;
}
}
return `${this.config.tagPrefix}${this.getVersionPart(result, options)}`;
}
catch (error) {
if (error instanceof Error) {
console.error(`Tag listeleme hatası: ${error.message}`);
}
else {
console.error('Tag listeleme hatası: Bilinmeyen hata türü');
}
}
}
async DetermineStagePhaseVersion(channel, baseVersion, options) {
try {
if (!baseVersion) {
let latestReleaseBranchBaseVersion = await this.latestReleaseBranchVersion(channel);
if (!latestReleaseBranchBaseVersion) {
latestReleaseBranchBaseVersion = this.defaultBaseVersion;
}
else {
latestReleaseBranchBaseVersion = this.getVersionPart(latestReleaseBranchBaseVersion, { print: 'base' });
}
baseVersion = `${this.config.tagPrefix}${latestReleaseBranchBaseVersion}`;
}
const latestChannelTagVersion = await this.latestTagVersion(`${this.config.releasePrefix}${baseVersion}-${channel}`, channel, baseVersion);
let result = '';
if (options.next) {
if (!latestChannelTagVersion) {
result = `${baseVersion}-${channel}.${this.config.phases.stage.channels[channel].startBuildNumber}`;
}
else {
const incrementedVersion = semver_1.default.inc(latestChannelTagVersion, 'prerelease', channel);
result = `${this.config.tagPrefix}${incrementedVersion}`;
}
}
else if (options.nextRelease) {
if (!latestChannelTagVersion) {
result = `${baseVersion}-${channel}.${this.config.phases.stage.channels[channel].startBuildNumber}`;
}
else {
const incrementedVersion = semver_1.default.inc(baseVersion, 'minor');
result = `${this.config.tagPrefix}${incrementedVersion}-${channel}.${this.config.phases.stage.channels[channel].startBuildNumber}`;
}
}
else if (options.current) {
if (!latestChannelTagVersion) {
result = `${baseVersion}-${channel}.${this.config.phases.stage.channels[channel].startBuildNumber}`;
}
else {
result = latestChannelTagVersion;
}
}
return `${this.config.tagPrefix}${this.getVersionPart(result, options)}`;
}
catch (error) {
if (error instanceof Error) {
console.error(`Tag listeleme hatası: ${error.message}`);
}
else {
console.error('Tag listeleme hatası: Bilinmeyen hata türü');
}
}
}
async DetermineProductionPhaseVersion(channelName, baseVersion, options) {
try {
let latestStableReleaseBranchBaseVersion = null;
if (!baseVersion) {
// let latestReleaseBranchBaseVersion = await this.latestReleaseBranchVersion(channelName)
// latestReleaseBranchBaseVersion = this.getVersionPart(latestReleaseBranchBaseVersion, { print: 'base' })
// if (!latestReleaseBranchBaseVersion) {
// latestReleaseBranchBaseVersion = this.defaultBaseVersion
// }
latestStableReleaseBranchBaseVersion = await this.latestReleaseBranchVersion();
latestStableReleaseBranchBaseVersion = this.getVersionPart(latestStableReleaseBranchBaseVersion, { print: 'base' });
if (!latestStableReleaseBranchBaseVersion) {
baseVersion = this.defaultBaseVersion;
}
else {
baseVersion = `${this.config.tagPrefix}${latestStableReleaseBranchBaseVersion}`;
}
}
const latestChannelTagVersion = await this.latestTagVersion(`${this.config.releasePrefix}${baseVersion}`, null, baseVersion);
let result = '';
if (options.next) {
if (!latestChannelTagVersion) {
result = `${baseVersion}`;
}
else {
result = `${latestChannelTagVersion}`;
}
}
else if (options.nextRelease) {
if (!latestChannelTagVersion && !latestStableReleaseBranchBaseVersion) {
result = `${baseVersion}`;
}
else {
const incrementedVersion = semver_1.default.inc(baseVersion, 'minor');
result = `${this.config.tagPrefix}${incrementedVersion}`;
}
}
else if (options.nextFix) {
if (!latestChannelTagVersion && !latestStableReleaseBranchBaseVersion) {
result = `${baseVersion}`;
}
else {
const incrementedVersion = semver_1.default.inc(baseVersion, 'patch');
result = `${this.config.tagPrefix}${incrementedVersion}`;
}
}
else if (options.current) {
if (!latestChannelTagVersion) {
result = `${baseVersion}`;
}
else {
result = latestChannelTagVersion;
}
}
else if (options.previous) {
result = await this.latestTagVersion('main');
}
else if (options.previousFix) {
const latestMainVersion = await this.latestTagVersion(`main`);
const incrementedVersion = semver_1.default.inc(latestMainVersion, 'patch');
result = `${this.config.tagPrefix}${incrementedVersion}`;
}
return `${this.config.tagPrefix}${this.getVersionPart(result, options)}`;
}
catch (error) {
if (error instanceof Error) {
console.error(`Tag listeleme hatası: ${error.message}`);
}
else {
console.error('Tag listeleme hatası: Bilinmeyen hata türü');
}
}
}
escapeForRegex(input) {
return input.replace(/\./g, '\\.');
}
}
exports.FlowManager = FlowManager;
//# sourceMappingURL=FlowManager.js.map