diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1d843b4..fc240c7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,8 +1,5 @@ name: 'Action to test the action locally with act' -on: - push: - branches: - - branch-that-does-not-exist +on: [pull_request] jobs: test-json: @@ -85,8 +82,8 @@ jobs: skip-on-empty: 'false' - run: test -f pre-commit.test.json || (echo should be here && exit 1) - - run: cat pre-commit.test.json - + - run: cat pre-commit.test.json && echo "" + - run: cat ./package.json test-pre-changelog-generation: runs-on: ubuntu-latest @@ -105,9 +102,14 @@ jobs: github-token: ${{ secrets.github_token }} pre-changelog-generation: test/pre-changelog-generation.js version-file: './test-file.toml' + version-path: 'package.version' + + - run: test -f pre-changelog-generation.version.test.json || (echo should be here && exit 1) + - run: test -f pre-changelog-generation.tag.test.json || (echo should be here && exit 1) + - run: cat pre-changelog-generation.version.test.json && echo "" + - run: cat pre-changelog-generation.tag.test.json && echo "" + - run: cat ./test-file.toml - - run: test -f pre-changelog-generation.test.json || (echo should be here && exit 1) - - run: cat pre-changelog-generation.test.json test-git: runs-on: ubuntu-latest steps: @@ -132,7 +134,7 @@ jobs: uses: actions/checkout@v2 with: path: "./" - + - run: git tag | xargs git tag -d - name: Generate changelog diff --git a/README.md b/README.md index bf4ddce..25163fd 100644 --- a/README.md +++ b/README.md @@ -58,17 +58,16 @@ A bunch of useful environment variables are available to the script with `proces > Function in a specified file will be run right before the changelog generation phase, when the next > version is already known, but it was not used anywhere yet. It can be useful if you want to manually update version or tag. -Same restrictions as for the pre-commit hook, but exported function name should be `preChangelogGeneration` +Same restrictions as for the pre-commit hook, but exported functions names should be `preVersionGeneration` for modifications to the version and `preTagGeneration` for modifications to the git tag. Following props will be passed to the function as a single parameter and same output is expected: ```typescript -interface Props { - tag: string; // Next tag e.g. v1.12.3 - version: string; // Next version e.g. 1.12.3 -} +// Next version e.g. 1.12.3 +export function preVersionGeneration(version: string): string {} -export function preChangelogGeneration(props: Props): Props {} +// Next tag e.g. v1.12.3 +export function preTagGeneration(tag: string): string {} ``` ### Config-File-Path diff --git a/src/helpers/bumpVersion.js b/src/helpers/bumpVersion.js index b7a5882..e2f478f 100644 --- a/src/helpers/bumpVersion.js +++ b/src/helpers/bumpVersion.js @@ -1,6 +1,8 @@ const core = require('@actions/core') const semverValid = require('semver').valid +const requireScript = require('./requireScript') + /** * Bumps the given version with the given release type * @@ -44,5 +46,22 @@ module.exports = (releaseType, version) => { core.info(`The version could not be detected, using fallback version '${major}.${minor}.${patch}'.`) } - return `${major}.${minor}.${patch}` + const preChangelogGenerationFile = core.getInput('pre-changelog-generation') + + let newVersion = `${major}.${minor}.${patch}` + + if (preChangelogGenerationFile) { + const preChangelogGenerationScript = requireScript(preChangelogGenerationFile) + + // Double check if we want to update / do something with the version + if (preChangelogGenerationScript && preChangelogGenerationScript.preVersionGeneration) { + const modifiedVersion = preChangelogGenerationScript.preVersionGeneration(newVersion) + + if (modifiedVersion) { + newVersion = modifiedVersion + } + } + } + + return newVersion } diff --git a/src/helpers/requireScript.js b/src/helpers/requireScript.js new file mode 100644 index 0000000..8127b6d --- /dev/null +++ b/src/helpers/requireScript.js @@ -0,0 +1,23 @@ +const core = require('@actions/core') +const path = require('path') +const fs = require('fs') + +/** + * Requires an script + * + * @param file + */ +module.exports = (file) => { + const fileLocation = path.resolve(process.cwd(), file) + + // Double check the script exists before loading it + if (fs.existsSync(fileLocation)) { + core.info(`Loading "${fileLocation}" script`) + + return require(fileLocation) + } + + core.error(`Tried to load "${fileLocation}" script but it does not exists!`) + + return undefined +} diff --git a/src/index.js b/src/index.js index 429084a..95a8118 100644 --- a/src/index.js +++ b/src/index.js @@ -5,6 +5,7 @@ const path = require('path') const getVersioning = require('./version') const git = require('./helpers/git') const changelog = require('./helpers/generateChangelog') +const requireScript = require('./helpers/requireScript') async function handleVersioningByExtension(ext, file, versionPath, releaseType) { const versioning = getVersioning(ext) @@ -29,7 +30,7 @@ async function run() { const gitUserEmail = core.getInput('git-user-email') const tagPrefix = core.getInput('tag-prefix') const preset = !core.getInput('config-file-path') ? core.getInput('preset') : '' - const preCommit = core.getInput('pre-commit') + const preCommitFile = core.getInput('pre-commit') const outputFile = core.getInput('output-file') const releaseCount = core.getInput('release-count') const versionFile = core.getInput('version-file') @@ -38,7 +39,7 @@ async function run() { const skipCommit = core.getInput('skip-commit').toLowerCase() === 'true' const skipEmptyRelease = core.getInput('skip-on-empty').toLowerCase() === 'true' const conventionalConfigFile = core.getInput('config-file-path') - const preChangelogGeneration = core.getInput('pre-changelog-generation') + const preChangelogGenerationFile = core.getInput('pre-changelog-generation') core.info(`Using "${preset}" preset`) core.info(`Using "${gitCommitMessage}" as commit message`) @@ -51,12 +52,12 @@ async function run() { core.info(`Using "${outputFile}" as output file`) core.info(`Using "${conventionalConfigFile}" as config file`) - if (preCommit) { - core.info(`Using "${preCommit}" as pre-commit script`) + if (preCommitFile) { + core.info(`Using "${preCommitFile}" as pre-commit script`) } - if (preChangelogGeneration) { - core.info(`Using "${preChangelogGeneration}" as pre-changelog-generation script`) + if (preChangelogGenerationFile) { + core.info(`Using "${preChangelogGenerationFile}" as pre-changelog-generation script`) } core.info(`Skipping empty releases is "${skipEmptyRelease ? 'enabled' : 'disabled'}"`) @@ -65,9 +66,9 @@ async function run() { core.info('Pull to make sure we have the full git history') await git.pull() - const config = conventionalConfigFile && require(path.resolve(process.cwd(), conventionalConfigFile)) + const config = conventionalConfigFile && requireScript(conventionalConfigFile) - conventionalRecommendedBump({ preset, tagPrefix, config }, async (error, recommendation) => { + conventionalRecommendedBump({ preset, tagPrefix, config }, async(error, recommendation) => { if (error) { core.setFailed(error.message) return @@ -91,9 +92,11 @@ async function run() { 'git', versionFile, versionPath, - recommendation.releaseType + recommendation.releaseType, ) + newVersion = versioning.newVersion + } else { const files = versionFile.split(',').map((f) => f.trim()) core.info(`Files to bump: ${files.join(', ')}`) @@ -102,8 +105,9 @@ async function run() { files.map((file) => { const fileExtension = file.split('.').pop() core.info(`Bumping version to file "${file}" with extension "${fileExtension}"`) + return handleVersioningByExtension(fileExtension, file, versionPath, recommendation.releaseType) - }) + }), ) newVersion = versioning[0].newVersion @@ -111,15 +115,16 @@ async function run() { let gitTag = `${tagPrefix}${newVersion}` - if (preChangelogGeneration) { - const newVersionAndTag = await require(path.resolve(process.cwd(), preChangelogGeneration)).preChangelogGeneration({ - tag: gitTag, - version: newVersion, - }) + if (preChangelogGenerationFile) { + const preChangelogGenerationScript = requireScript(preChangelogGenerationFile) - if (newVersionAndTag) { - if (newVersionAndTag.tag) gitTag = newVersionAndTag.tag - if (newVersionAndTag.version) newVersion = newVersionAndTag.version + // Double check if we want to update / do something with the tag + if (preChangelogGenerationScript && preChangelogGenerationScript.preTagGeneration) { + const modifiedTag = preChangelogGenerationScript.preTagGeneration(gitTag) + + if (modifiedTag) { + gitTag = modifiedTag + } } } @@ -147,12 +152,18 @@ async function run() { if (!skipCommit) { // Add changed files to git - if (preCommit) { - await require(path.resolve(process.cwd(), preCommit)).preCommit({ - tag: gitTag, - version: newVersion, - }) + if (preCommitFile) { + const preCommitScript = await requireScript(preCommitFile) + + // Double check if the file exists and the export exists + if (preCommitScript && preCommitScript.preCommit) { + preCommitScript.preCommit({ + tag: gitTag, + version: newVersion, + }) + } } + await git.add('.') await git.commit(gitCommitMessage.replace('{version}', gitTag)) } @@ -163,6 +174,7 @@ async function run() { core.info('Push all changes') try { await git.push() + } catch (error) { core.setFailed(error.message) } diff --git a/test/pre-changelog-generation.js b/test/pre-changelog-generation.js index 762518e..b5e75ea 100644 --- a/test/pre-changelog-generation.js +++ b/test/pre-changelog-generation.js @@ -1,22 +1,29 @@ const fs = require('fs') const t = require('assert') -exports.preChangelogGeneration = (props) => { +exports.preVersionGeneration = (version) => { const { GITHUB_WORKSPACE } = process.env t.ok(GITHUB_WORKSPACE, 'GITHUB_WORKSPACE should not be empty') - t.ok(props.tag, 'tag should not be empty') - t.ok(props.version, 'version should not be empty') + t.ok(version, 'version should not be empty') const newVersion = '1.0.100' - const newTag = 'v1.0.100' - const body = { - version: newVersion, - tag: newTag, - } + fs.writeFileSync('pre-changelog-generation.version.test.json', newVersion) - fs.writeFileSync('pre-changelog-generation.test.json', JSON.stringify(body, null, 2)) - - return body + return newVersion +} + +exports.preTagGeneration = (tag) => { + const { GITHUB_WORKSPACE } = process.env + + t.ok(GITHUB_WORKSPACE, 'GITHUB_WORKSPACE should not be empty') + t.ok(tag, 'tag should not be empty') + t.strictEqual(tag, 'v1.0.100') + + const newTag = 'v1.0.100-alpha' + + fs.writeFileSync('pre-changelog-generation.tag.test.json', newTag) + + return newTag }