From c50a3c86c6c534489bfdd1895a10d30eaf75ef20 Mon Sep 17 00:00:00 2001 From: Paul Hatcherian <1835615+PaulHatch@users.noreply.github.com> Date: Sat, 25 Jan 2020 11:13:16 -0500 Subject: [PATCH] Add path change detection (MINOR) --- action.yml | 6 ++- dist/index.js | 16 ++++++-- index.js | 16 ++++++-- index.test.js | 105 +++++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 127 insertions(+), 16 deletions(-) diff --git a/action.yml b/action.yml index e4aef50..d2de56c 100644 --- a/action.yml +++ b/action.yml @@ -24,7 +24,9 @@ inputs: description: "Pattern to use when formatting output version" required: true default: "${major}.${minor}.${patch}" - + change_path: + description: "Path to check for changes. If any changes are detected in the path the 'changed' output will true. Enter multiple paths separated by spaces." + required: false outputs: major: description: "Current major number" @@ -36,6 +38,8 @@ outputs: description: "An additional value indicating the number of commits for the current version" version: description: "The version result, in the format {major}.{minor}.{patch}" + changed: + description: "Indicates whether there was a change since the last version if change_path was specified. If no change_path was specified this value will always be false." runs: using: "node12" main: "dist/index.js" diff --git a/dist/index.js b/dist/index.js index f1cad44..17d266f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -652,7 +652,7 @@ const cmd = async (command, ...args) => { return output; }; -const setOutput = (major, minor, patch, increment) => { +const setOutput = (major, minor, patch, increment, changed) => { const format = core.getInput('format', { required: true }); var version = format .replace('${major}', major) @@ -667,6 +667,7 @@ const setOutput = (major, minor, patch, increment) => { core.setOutput("minor", minor.toString()); core.setOutput("patch", patch.toString()); core.setOutput("increment", increment.toString()); + core.setOutput("changed", changed.toString()); }; async function run() { @@ -679,15 +680,18 @@ async function run() { const branch = `${remotePrefix}${core.getInput('branch', { required: true })}`; const majorPattern = core.getInput('major_pattern', { required: true }); const minorPattern = core.getInput('minor_pattern', { required: true }); + const changePath = core.getInput('change_path') || ''; const releasePattern = `${tagPrefix}*`; let major = 0, minor = 0, patch = 0, increment = 0; + let changed = true; + let lastCommitAll = (await cmd('git', 'rev-list', '-n1', '--all')).trim(); if (lastCommitAll === '') { // empty repo - setOutput('0', '0', '0', '0'); + setOutput('0', '0', '0', '0', changed); return; } @@ -741,6 +745,12 @@ async function run() { '--author-date-order', root === '' ? branch : `${root}..${branch}`); + if (changePath !== '') { + const changedFiles = await cmd(`git diff --name-only ${root}..${branch} -- ${changePath}`); + + changed = changedFiles.length > 0; + } + let history = log .trim() .split(eol) @@ -766,7 +776,7 @@ async function run() { patch++; } - setOutput(major, minor, patch, increment); + setOutput(major, minor, patch, increment, changed); } catch (error) { core.error(error); diff --git a/index.js b/index.js index 7e847d7..aeaf804 100644 --- a/index.js +++ b/index.js @@ -16,7 +16,7 @@ const cmd = async (command, ...args) => { return output; }; -const setOutput = (major, minor, patch, increment) => { +const setOutput = (major, minor, patch, increment, changed) => { const format = core.getInput('format', { required: true }); var version = format .replace('${major}', major) @@ -31,6 +31,7 @@ const setOutput = (major, minor, patch, increment) => { core.setOutput("minor", minor.toString()); core.setOutput("patch", patch.toString()); core.setOutput("increment", increment.toString()); + core.setOutput("changed", changed.toString()); }; async function run() { @@ -43,15 +44,18 @@ async function run() { const branch = `${remotePrefix}${core.getInput('branch', { required: true })}`; const majorPattern = core.getInput('major_pattern', { required: true }); const minorPattern = core.getInput('minor_pattern', { required: true }); + const changePath = core.getInput('change_path') || ''; const releasePattern = `${tagPrefix}*`; let major = 0, minor = 0, patch = 0, increment = 0; + let changed = true; + let lastCommitAll = (await cmd('git', 'rev-list', '-n1', '--all')).trim(); if (lastCommitAll === '') { // empty repo - setOutput('0', '0', '0', '0'); + setOutput('0', '0', '0', '0', changed); return; } @@ -105,6 +109,12 @@ async function run() { '--author-date-order', root === '' ? branch : `${root}..${branch}`); + if (changePath !== '') { + const changedFiles = await cmd(`git diff --name-only ${root}..${branch} -- ${changePath}`); + + changed = changedFiles.length > 0; + } + let history = log .trim() .split(eol) @@ -130,7 +140,7 @@ async function run() { patch++; } - setOutput(major, minor, patch, increment); + setOutput(major, minor, patch, increment, changed); } catch (error) { core.error(error); diff --git a/index.test.js b/index.test.js index 533cbd2..4a76925 100644 --- a/index.test.js +++ b/index.test.js @@ -14,15 +14,15 @@ const createTestRepo = (inputs) => { const repoDirectory = `/tmp/test${Math.random().toString(36).substring(2, 15)}`; cp.execSync(`mkdir ${repoDirectory} && git init ${repoDirectory}`); - let env = {}; - if (inputs !== undefined) { - for (let key in inputs) { - env[`INPUT_${key.toUpperCase()}`] = inputs[key]; + const run = (command, extraInputs) => { + const allInputs = Object.assign({}, inputs, extraInputs); + let env = {}; + for (let key in allInputs) { + env[`INPUT_${key.toUpperCase()}`] = allInputs[key]; } + return execute(repoDirectory, command, env); } - const run = (command) => execute(repoDirectory, command, env); - // Configure up git user run(`git config user.name "Test User"`); run(`git config user.email "test@example.com"`); @@ -31,12 +31,12 @@ const createTestRepo = (inputs) => { return { clean: () => execute('/tmp', `rm -rf ${repoDirectory}`), - makeCommit: (msg) => { - run(`touch test${i++}`); + makeCommit: (msg, path) => { + run(`touch ${path !== undefined ? path.trim('/') + '/' : ''}test${i++}`); run(`git add --all`); run(`git commit -m '${msg}'`); }, - runAction: () => run(`node ${path.join(__dirname, 'index.js')}`), + runAction: (inputs) => run(`node ${path.join(__dirname, 'index.js')}`, inputs), exec: run }; }; @@ -283,5 +283,92 @@ test('Tag order comes from commit order, not tag create order', () => { expect(result).toMatch('Version is 2.0.1+0'); + repo.clean(); +}); + + +test('Change detection is true by default', () => { + const repo = createTestRepo({ tag_prefix: '' }); // 0.0.0 + + repo.makeCommit('Initial Commit'); // 0.0.1 + repo.exec('git tag 0.0.1'); + repo.makeCommit(`Second Commit`); // 0.0.2 + const result = repo.runAction(); + + expect(result).toMatch('::set-output name=changed,::true'); + + repo.clean(); +}); + +test('Change detection is true by default', () => { + const repo = createTestRepo({ tag_prefix: '' }); // 0.0.0 + + repo.makeCommit('Initial Commit'); // 0.0.1 + repo.exec('git tag 0.0.1'); + repo.makeCommit(`Second Commit`); // 0.0.2 + const result = repo.runAction({}); + + expect(result).toMatch('::set-output name=changed,::true'); + + repo.clean(); +}); + +test('Changes to monitored path is true when change is in path', () => { + const repo = createTestRepo({ tag_prefix: '' }); // 0.0.0 + + repo.makeCommit('Initial Commit'); // 0.0.1 + repo.exec('git tag 0.0.1'); + repo.exec('mkdir project1'); + repo.makeCommit(`Second Commit`, 'project1'); // 0.0.2 + const result = repo.runAction({ change_path: "project1" }); + + expect(result).toMatch('::set-output name=changed,::true'); + + repo.clean(); +}); + +test('Changes to monitored path is false when changes are not in path', () => { + const repo = createTestRepo({ tag_prefix: '' }); // 0.0.0 + + repo.makeCommit('Initial Commit'); // 0.0.1 + repo.exec('git tag 0.0.1'); + repo.exec('mkdir project1'); + repo.exec('mkdir project2'); + repo.makeCommit(`Second Commit`, 'project2'); // 0.0.2 + const result = repo.runAction({ change_path: "project1" }); + + expect(result).toMatch('::set-output name=changed,::false'); + + repo.clean(); +}); + +test('Changes to multiple monitored path is true when change is in path', () => { + const repo = createTestRepo({ tag_prefix: '' }); // 0.0.0 + + repo.makeCommit('Initial Commit'); // 0.0.1 + repo.exec('git tag 0.0.1'); + repo.exec('mkdir project1'); + repo.exec('mkdir project2'); + repo.makeCommit(`Second Commit`, 'project2'); // 0.0.2 + const result = repo.runAction({ change_path: "./project1 ./project2" }); + + expect(result).toMatch('::set-output name=changed,::true'); + + repo.clean(); +}); + +test('Changes to multiple monitored path is false when change is not in path', () => { + const repo = createTestRepo({ tag_prefix: '' }); // 0.0.0 + + repo.makeCommit('Initial Commit'); // 0.0.1 + repo.exec('git tag 0.0.1'); + repo.exec('mkdir project1'); + repo.exec('mkdir project2'); + repo.exec('mkdir project3'); + repo.makeCommit(`Second Commit`, 'project3'); // 0.0.2 + const result = repo.runAction({ change_path: "project1 project2" }); + + expect(result).toMatch('::set-output name=changed,::false'); + repo.clean(); }); \ No newline at end of file