From d022b0d7e98b6b13ce0af3e6c44a550256b0ca59 Mon Sep 17 00:00:00 2001 From: Tycho Bokdam Date: Sun, 28 Jun 2020 20:23:58 +0200 Subject: [PATCH] feat: Added version-file, version-path, skip-version-file options package-json is renamed to version-file to be more generic so we can support other formats version-path is the location of the string version skip-version-file is a option to prevent updating the version file --- action.yml | 16 ++++++++-- src/index.js | 64 ++++++++++++++++++++++++++++----------- src/version/index.js | 21 +++++++++++++ src/version/json.js | 72 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 154 insertions(+), 19 deletions(-) create mode 100644 src/version/index.js create mode 100644 src/version/json.js diff --git a/action.yml b/action.yml index 7bd9c2c..6429d9a 100644 --- a/action.yml +++ b/action.yml @@ -54,13 +54,25 @@ inputs: default: '5' required: false - package-json: - description: 'The path to the package.json to use' + version-file: + description: 'The path to the file that contains the version to bump' default: './package.json' required: false + version-path: + description: 'The place inside the version file to bump' + default: 'version' + required: false + skip-on-empty: description: 'Do nothing when the changelog from the latest release is empty' + default: 'true' + required: false + + skip-version-file: + description: 'Do not update the version file' + default: 'false' + required: false skip-commit: description: 'Do create a release commit' diff --git a/src/index.js b/src/index.js index ddac99a..e7a0452 100644 --- a/src/index.js +++ b/src/index.js @@ -1,66 +1,96 @@ const core = require('@actions/core') const conventionalRecommendedBump = require('conventional-recommended-bump') +const path = require('path') +const getVersioning = require('./version') const git = require('./helpers/git') -const packageJson = require('./helpers/packageJson') const changelog = require('./helpers/generateChangelog') async function run() { try { - const commitMessage = core.getInput('git-message') + const gitCommitMessage = core.getInput('git-message') + const gitUserName = core.getInput('git-user-name') + const gitUserEmail = core.getInput('git-user-email') const tagPrefix = core.getInput('tag-prefix') const preset = core.getInput('preset') const outputFile = core.getInput('output-file') const releaseCount = core.getInput('release-count') - const packageJsonToUse = core.getInput('package-json') - const skipOnEmptyRelease = core.getInput('skip-on-empty').toLowerCase() === 'true' + const versionFile = core.getInput('version-file') + const versionPath = core.getInput('version-path') + const skipVersionFile = core.getInput('skip-version-file').toLowerCase() === 'true' + const skipTag = core.getInput('skip-tag').toLowerCase() === 'true' + const skipCommit = core.getInput('skip-commit').toLowerCase() === 'true' + const skipEmptyRelease = core.getInput('skip-on-empty').toLowerCase() === 'true' core.info(`Using "${preset}" preset`) - core.info(`Using "${commitMessage}" as commit message`) + core.info(`Using "${gitCommitMessage}" as commit message`) + core.info(`Using "${gitUserName}" as git user.name`) + core.info(`Using "${gitUserEmail}" as git user.email`) core.info(`Using "${releaseCount}" release count`) - core.info(`Using "${packageJsonToUse}"`) + core.info(`Using "${versionFile}" as version file`) + core.info(`Using "${versionPath}" as version path`) core.info(`Using "${tagPrefix}" as tag prefix`) core.info(`Using "${outputFile}" as output file`) + core.info(`Skipping empty releases is "${skipEmptyRelease ? 'enabled' : 'disabled'}"`) + core.info(`Skipping the update of the version file is "${skipVersionFile ? 'enabled' : 'disabled'}"`) + core.info(`Skipping the creation of the GIT tag is "${skipTag ? 'enabled' : 'disabled'}"`) + core.info('Pull to make sure we have the full git history') await git.pull() - conventionalRecommendedBump({ preset, tagPrefix }, async (error, recommendation) => { + conventionalRecommendedBump({ preset, tagPrefix }, async(error, recommendation) => { if (error) { core.setFailed(error.message) return } core.info(`Recommended release type: ${recommendation.releaseType}`) - recommendation.reason && core.info(`because: ${recommendation.reason}`) + + // If we have a reason also log it + if (recommendation.reason) { + core.info(`Because: ${recommendation.reason}`) + } + + // If skipVersionFile is true we use GIT to determine the new version + const fileExtension = skipVersionFile + ? 'git' + : versionFile.split('.').pop() + + const versioning = getVersioning(fileExtension) + + // File type not supported + if (versioning === null) { + throw new Error(`File extension "${fileExtension}" from file "${versionFile}" is not supported`) + } + + versioning.init(path.resolve(versionFile), versionPath) // Bump the version in the package.json - const jsonPackage = packageJson.bump( - packageJson.get(), + versioning.bump( recommendation.releaseType, ) - const stringChangelog = await changelog.generateStringChangelog(tagPrefix, preset, jsonPackage, 1) + // Generate the string changelog + const stringChangelog = await changelog.generateStringChangelog(tagPrefix, preset, versioning.newVersion, 1) core.info('Changelog generated') core.info(stringChangelog) + // Removes the version number from the changelog const cleanChangelog = stringChangelog.split('\n').slice(3).join('\n').trim() - if (skipOnEmptyRelease && cleanChangelog === '') { + if (skipEmptyRelease && cleanChangelog === '') { core.info('Generated changelog is empty and skip-on-empty has been activated so we skip this step') core.setOutput('skipped', 'true') return } - // Update the package.json file - packageJson.update(jsonPackage) - - core.info(`New version: ${jsonPackage.version}`) + core.info(`New version: ${versioning.newVersion}`) // If output file === 'false' we don't write it to file if (outputFile !== 'false') { // Generate the changelog - await changelog.generateFileChangelog(tagPrefix, preset, jsonPackage, outputFile, releaseCount) + await changelog.generateFileChangelog(tagPrefix, preset, versioning.newVersion, outputFile, releaseCount) } const gitTag = `${tagPrefix}${versioning.newVersion}` diff --git a/src/version/index.js b/src/version/index.js new file mode 100644 index 0000000..142805a --- /dev/null +++ b/src/version/index.js @@ -0,0 +1,21 @@ +const JSON = require('./json') + +module.exports = (fileExtension) => { + switch (fileExtension.toLowerCase()) { + case 'json': + return JSON + + // case 'yaml': + // case 'yml': + // return Yaml + // + // case 'toml': + // return Toml + // + // case 'git': + // return Git + + default: + return null + } +} diff --git a/src/version/json.js b/src/version/json.js new file mode 100644 index 0000000..51c684a --- /dev/null +++ b/src/version/json.js @@ -0,0 +1,72 @@ +const fs = require('fs') + +module.exports = new (class JSON { + + fileLocation = null + + versionPath = null + + newVersion = null + + init = (fileLocation, versionPath) => { + this.fileLocation = fileLocation + this.versionPath = versionPath + } + + /** + * Get's the JSON file + * + * @return {string} + */ + read = () => { + return JSON.parse(fs.readFileSync(this.fileLocation)) + } + + /** + * Bumps the version in the package.json + * + * @param {!string} releaseType - The type of release + * @return {*} + */ + bump = (releaseType) => { + // Read the JSON file + const packageJson = this.read() + + let [major, minor, patch] = packageJson.version.split('.') + + switch (releaseType) { + case 'major': + major = parseInt(major, 10) + 1 + minor = 0 + patch = 0 + break + + case 'minor': + minor = parseInt(minor, 10) + 1 + patch = 0 + break + + default: + patch = parseInt(patch, 10) + 1 + } + + // Update the package.json with the new version + // TODO:: Test and make sure we can use path.to.version + packageJson[this.versionPath] = this.newVersion = `${major}.${minor}.${patch}` + + // Update the JSON file + this.update(packageJson) + } + + /** + * Update JSON file + * + * @param {!string} newJSONContent - New content for the JSON file + * @return {*} + */ + update = (newJSONContent) => ( + fs.writeFileSync(this.fileLocation, JSON.stringify(newJSONContent, null, 2)) + ) + +}) +