in tools/js-sdk-release-tools/src/common/changlog/automaticGenerateChangeLogAndBumpVersion.ts [27:124]
export async function generateChangelogAndBumpVersion(packageFolderPath: string) {
logger.info(`Start to generate changelog and bump version in ${packageFolderPath}`);
const jsSdkRepoPath = String(shell.pwd());
packageFolderPath = path.join(jsSdkRepoPath, packageFolderPath);
const ApiType = await getApiVersionType(packageFolderPath);
const isStableRelease = ApiType != ApiVersionType.Preview;
const packageName = getNpmPackageName(packageFolderPath);
const npmViewResult = await tryGetNpmView(packageName);
const stableVersion = getVersion(npmViewResult, "latest");
const nextVersion = getVersion(npmViewResult, "next");
if (!npmViewResult || (!!stableVersion && isBetaVersion(stableVersion) && isStableRelease)) {
logger.info(`Package ${packageName} is first ${!npmViewResult ? ' ': ' stable'} release, start to generate changelogs and set version for first ${!npmViewResult ? ' ': ' stable'} release.`);
makeChangesForFirstRelease(packageFolderPath, isStableRelease);
logger.info(`Generated changelogs and setting version for first${!npmViewResult ? ' ': ' stable'} release successfully`);
} else {
if (!stableVersion) {
logger.error(`Invalid latest version ${stableVersion}`);
process.exit(1);
}
logger.info(`Package ${packageName} has been released before, start to check whether previous release is track2 sdk.`)
const usedVersions = Object.keys(npmViewResult['versions']);
// in our rule, we always compare to stableVersion. But here wo should pay attention to the some stableVersion which contains beta, which means the package has not been GA.
try {
shell.mkdir(path.join(packageFolderPath, 'changelog-temp'));
shell.cd(path.join(packageFolderPath, 'changelog-temp'));
shell.exec(`npm pack ${packageName}@${stableVersion}`, { silent: true});
const files = shell.ls('*.tgz');
shell.exec(`tar -xzf ${files[0]}`);
shell.cd(packageFolderPath);
// only track2 sdk includes sdk-type with value mgmt
const sdkType = JSON.parse(fs.readFileSync(path.join(packageFolderPath, 'changelog-temp', 'package', 'package.json'), {encoding: 'utf-8'}))['sdk-type'];
const clientType = getSDKType(packageFolderPath);
if (sdkType && sdkType === 'mgmt' || clientType === SDKType.RestLevelClient) {
logger.info(`Package ${packageName} released before is track2 sdk.`);
logger.info('Start to generate changelog by comparing api.md.');
const npmPackageRoot = path.join(packageFolderPath, 'changelog-temp', 'package');
const apiMdFileNPM = getApiReviewPath(npmPackageRoot);
const apiMdFileLocal = getApiReviewPath(packageFolderPath);
const oldSDKType = getSDKType(npmPackageRoot);
const newSDKType = getSDKType(packageFolderPath);
const changelog: Changelog = await extractExportAndGenerateChangelog(apiMdFileNPM, apiMdFileLocal, oldSDKType, newSDKType);
const changelogPath = path.join(npmPackageRoot, 'CHANGELOG.md');
let originalChangeLogContent = tryReadNpmPackageChangelog(changelogPath);
if(nextVersion){
shell.cd(path.join(packageFolderPath, 'changelog-temp'));
shell.mkdir(path.join(packageFolderPath, 'changelog-temp', 'next'));
shell.cd(path.join(packageFolderPath,'changelog-temp', 'next'));
shell.exec(`npm pack ${packageName}@${nextVersion}`, { silent: true});
const files = shell.ls('*.tgz');
shell.exec(`tar -xzf ${files[0]}`);
shell.cd(packageFolderPath);
logger.info("Created next folder successfully.")
const latestDate = getversionDate(npmViewResult, stableVersion);
const nextDate = getversionDate(npmViewResult,nextVersion);
if (latestDate && nextDate && latestDate <= nextDate){
const nextChangelogPath = path.join(packageFolderPath,'changelog-temp', 'next', 'package', 'CHANGELOG.md');
originalChangeLogContent = tryReadNpmPackageChangelog(nextChangelogPath);
logger.info('Keep previous preview changelog.');
}
}
if(originalChangeLogContent.includes("https://aka.ms/js-track2-quickstart")){
originalChangeLogContent=originalChangeLogContent.replace("https://aka.ms/js-track2-quickstart","https://aka.ms/azsdk/js/mgmt/quickstart");
}
originalChangeLogContent = fixChangelogFormat(originalChangeLogContent);
if (!changelog.hasBreakingChange && !changelog.hasFeature) {
logger.warn('Failed to generate changelog because the codes of local and npm may be the same.');
logger.info('Start to bump a fix version.');
const oriPackageJson = execSync(`git show HEAD:${path.relative(jsSdkRepoPath, path.join(packageFolderPath, 'package.json')).replace(/\\/g, '/')}`, {encoding: 'utf-8'});
const oriVersion = JSON.parse(oriPackageJson).version;
const oriVersionReleased = !usedVersions? false : usedVersions.includes(oriVersion);
let newVersion = oriVersion;
if (oriVersionReleased) {
newVersion = isBetaVersion(oriVersion)? bumpPreviewVersion(oriVersion, usedVersions) : bumpPatchVersion(oriVersion, usedVersions);
}
makeChangesForPatchReleasingTrack2(packageFolderPath, newVersion);
} else {
await changelog.postProcess(npmPackageRoot, packageFolderPath, clientType)
const newVersion = getNewVersion(stableVersion, usedVersions, changelog.hasBreakingChange, isStableRelease);
makeChangesForReleasingTrack2(packageFolderPath, newVersion, changelog, originalChangeLogContent,stableVersion);
logger.info('Generated changelogs and set version for track2 release successfully.');
return changelog;
}
} else {
logger.info(`Package ${packageName} released before is track1 sdk.`);
logger.info('Start to generate changelog of migrating track1 to track2 sdk.');
const newVersion = getNewVersion(stableVersion, usedVersions, true, isStableRelease);
makeChangesForMigrateTrack1ToTrack2(packageFolderPath, newVersion);
logger.info('Generated changelogs and setting version for migrating track1 to track2 successfully.');
}
} finally {
shell.rm('-r', `${path.join(packageFolderPath, 'changelog-temp')}`);
shell.cd(jsSdkRepoPath);
}
}
}