diff --git a/action.yml b/action.yml index 974c1c8..3dfdd86 100644 --- a/action.yml +++ b/action.yml @@ -1,5 +1,5 @@ -name: "Semantic Version" -description: "Determines version of a repo" +name: "Git Semantic Version" +description: "Determines version of a repo based on git history" branding: icon: "layers" color: "blue" diff --git a/dist/index.js b/dist/index.js index 65b5ce4..7daec53 100644 --- a/dist/index.js +++ b/dist/index.js @@ -652,6 +652,22 @@ const cmd = async (command, ...args) => { return output; }; +const setOutput = (major, minor, patch, increment) => { + const format = core.getInput('format', { required: true }); + var version = format + .replace('${major}', major) + .replace('${minor}', minor) + .replace('${patch}', patch) + .replace('${increment}', increment); + + core.info(`Version is ${major}.${minor}.${patch}+${increment}`); + core.setOutput("version", version); + core.setOutput("major", major.toString()); + core.setOutput("minor", minor.toString()); + core.setOutput("patch", patch.toString()); + core.setOutput("increment", increment.toString()); +}; + async function run() { try { const remote = await cmd('git', 'remote'); @@ -666,30 +682,29 @@ async function run() { const releasePattern = `refs/tags/${tagPrefix}*`; let major = 0, minor = 0, patch = 0, increment = 0; + let lastCommitAll = (await cmd('git', 'rev-list', '-n1', '--all')).trim(); + + if (lastCommitAll === '') { + // empty repo + setOutput('0', '0', '0', '0'); + return; + } + + let commit = (await cmd('git', 'rev-parse', 'HEAD')).trim(); + let tag = (await cmd( 'git', `for-each-ref`, `--format='%(refname:short)'`, `--sort=-committerdate`, + `--no-contains`, commit, releasePattern )).split(eol)[0].trim().replace(/'/g, ""); let root; if (tag === '') { - const isEmpty = (await cmd('git', `status`)).includes('No commits yet'); - if (isEmpty) { - // empty repo - core.info('Version is 0.0.0+0'); - core.setOutput("version", '0.0.0+0'); - core.setOutput("major", '0'); - core.setOutput("minor", '0'); - core.setOutput("patch", '0'); - core.setOutput("increment", '0'); - return; - } else { - // no release tags yet, use the initial commit as the root - root = ''; - } + // no release tags yet, use the initial commit as the root + root = ''; } else { // parse the version tag let tagParts = tag.split('/'); @@ -741,13 +756,7 @@ async function run() { patch++; } - let version = `${major}.${minor}.${patch}`; - core.info(`Version is ${version}+${increment}`); - core.setOutput("version", version); - core.setOutput("major", major.toString()); - core.setOutput("minor", minor.toString()); - core.setOutput("patch", patch.toString()); - core.setOutput("increment", increment.toString()); + setOutput(major, minor, patch, increment); } catch (error) { core.error(error); diff --git a/index.js b/index.js index 69117c0..ab0310a 100644 --- a/index.js +++ b/index.js @@ -46,25 +46,29 @@ async function run() { const releasePattern = `refs/tags/${tagPrefix}*`; let major = 0, minor = 0, patch = 0, increment = 0; + let lastCommitAll = (await cmd('git', 'rev-list', '-n1', '--all')).trim(); + + if (lastCommitAll === '') { + // empty repo + setOutput('0', '0', '0', '0'); + return; + } + + let commit = (await cmd('git', 'rev-parse', 'HEAD')).trim(); + let tag = (await cmd( 'git', `for-each-ref`, `--format='%(refname:short)'`, `--sort=-committerdate`, + `--no-contains`, commit, releasePattern )).split(eol)[0].trim().replace(/'/g, ""); let root; if (tag === '') { - const isEmpty = (await cmd('git', `status`)).includes('No commits yet'); - if (isEmpty) { - // empty repo - setOutput('0', '0', '0', '0'); - return; - } else { - // no release tags yet, use the initial commit as the root - root = ''; - } + // no release tags yet, use the initial commit as the root + root = ''; } else { // parse the version tag let tagParts = tag.split('/'); diff --git a/index.test.js b/index.test.js index 2506620..ac8b8c4 100644 --- a/index.test.js +++ b/index.test.js @@ -74,6 +74,19 @@ test('Repository with commits shows increment', () => { repo.clean(); }); +test('Tagging does not break version', () => { + const repo = createTestRepo(); // 0.0.0+0 + + repo.makeCommit('Initial Commit'); // 0.0.1+0 + repo.makeCommit(`Second Commit`); // 0.0.1+1 + repo.exec('git tag v0.0.1') + const result = repo.runAction(); + + expect(result).toMatch('Version is 0.0.1+1'); + + repo.clean(); +}); + test('Minor update bumps minor version and resets increment', () => { const repo = createTestRepo(); // 0.0.0+0 @@ -126,7 +139,7 @@ test('Minor commits after a major commit are ignored', () => { repo.clean(); }); -test('Release branches start new version', () => { +test('Tags start new version', () => { const repo = createTestRepo(); // 0.0.0+0 repo.makeCommit('Initial Commit'); // 0.0.1+0 @@ -184,32 +197,6 @@ test('Tags on branches are used', () => { repo.clean(); }); -test('Merged tags do not affect version', () => { - - // This test checks that merges are counted correctly - // master o--o--o--o---o <- expecting v0.0.2+1 - // \ / - // release o--o <- taged v0.0.1 - - - const repo = createTestRepo(); // 0.0.0+0 - - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.makeCommit('Second Commit'); // 0.0.1+1 - repo.makeCommit('Third Commit'); // 0.1.1+2 - repo.exec('git checkout -b release/0.0.1') - repo.makeCommit('Fourth Commit'); // 0.1.1+3 - repo.exec('git tag v0.0.1'); - repo.exec('git checkout master'); - repo.makeCommit('Fifth Commit'); // 0.0.2+1 - repo.exec('git merge release/0.0.1'); - const result = repo.runAction(); - - expect(result).toMatch('Version is 0.0.2+1'); - - repo.clean(); -}); - test('Merged tags do not affect version', () => { // This test checks that merges don't override tags