generated from actions/typescript-action
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #133 from cactusoft-ca/feature/change-calculation-…
…of-latest-sha Feature/change calculation of latest sha
- Loading branch information
Showing
4 changed files
with
89 additions
and
191 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,125 +1,80 @@ | ||
import * as core from '@actions/core'; | ||
import * as exec from '@actions/exec'; | ||
|
||
const cache = new Map<string, number>(); | ||
|
||
async function isDescendant(maybeDescendantHash: string, ancestorHash: string) { | ||
if (cache.has(maybeDescendantHash + ancestorHash)) { | ||
return cache.get(maybeDescendantHash + ancestorHash) as number; | ||
} | ||
if (maybeDescendantHash === ancestorHash) return 0; | ||
const result = await exec.getExecOutput('git merge-base --is-ancestor ' + ancestorHash + ' ' + maybeDescendantHash, undefined, { ignoreReturnCode: true }); | ||
const isDescendant = result.exitCode === 0 ? -1 : 1; | ||
cache.set(maybeDescendantHash + ancestorHash, isDescendant); | ||
cache.set(ancestorHash + maybeDescendantHash, result.exitCode === 0 ? 1 : -1); | ||
return isDescendant; | ||
} | ||
|
||
/** | ||
* return the mid value among x, y, and z | ||
* @param x | ||
* @param y | ||
* @param z | ||
* @param compare | ||
* @returns {Promise.<*>} | ||
*/ | ||
async function getPivot<T>(x: T, y: T, z: T, compare: (x: T, y: T) => Promise<number>) { | ||
if (await compare(x, y) < 0) { | ||
if (await compare(y, z) < 0) { | ||
return y; | ||
} else if (await compare(z, x) < 0) { | ||
return x; | ||
} else { | ||
return z; | ||
} | ||
} else if (await compare(y, z) > 0) { | ||
return y; | ||
} else if (await compare(z, x) > 0) { | ||
return x; | ||
} else { | ||
return z; | ||
} | ||
} | ||
|
||
/** | ||
* asynchronous quick sort | ||
* @param arr array to sort | ||
* @param compare asynchronous comparing function | ||
* @param left index where the range of elements to be sorted starts | ||
* @param right index where the range of elements to be sorted ends | ||
* @returns {Promise.<*>} | ||
*/ | ||
async function quickSort<T>(arr: T[], compare: (x: T, y: T) => Promise<number>, left = 0, right = arr.length - 1) { | ||
if (left < right) { | ||
let i = left, j = right, tmp; | ||
const pivot = await getPivot(arr[i], arr[i + Math.floor((j - i) / 2)], arr[j], compare); | ||
while (true) { | ||
while (await compare(arr[i], pivot) < 0) { | ||
i++; | ||
} | ||
while (await compare(pivot, arr[j]) < 0) { | ||
j--; | ||
} | ||
if (i >= j) { | ||
break; | ||
} | ||
tmp = arr[i]; | ||
arr[i] = arr[j]; | ||
arr[j] = tmp; | ||
|
||
i++; | ||
j--; | ||
} | ||
await quickSort(arr, compare, left, i - 1); | ||
await quickSort(arr, compare, j + 1, right); | ||
} | ||
return arr; | ||
} | ||
|
||
import * as core from '@actions/core' | ||
import * as exec from '@actions/exec' | ||
|
||
async function run(): Promise<void> { | ||
try { | ||
|
||
const paths = core.getMultilineInput('paths', { required: true }); | ||
|
||
const paths = core.getMultilineInput('paths', {required: true}) | ||
|
||
// printing the list of paths provided | ||
core.debug('List of provided paths:') | ||
for (let path of paths) { | ||
for (const path of paths) { | ||
core.debug(path) | ||
} | ||
|
||
const hashset: Set<string> = new Set<string>() | ||
|
||
// Get git hashes for each folder/file from the input parameters | ||
for (const path of paths) { | ||
const result = await exec.getExecOutput('git', ['log', '--pretty=format:"%H"', '-n1', path]); | ||
const result = await exec.getExecOutput('git', [ | ||
'log', | ||
'--pretty=format:"%H"', | ||
'-n1', | ||
path | ||
]) | ||
if (!hashset.has(result.stdout)) { | ||
hashset.add(result.stdout); | ||
hashset.add(replaceAll(replaceAll(result.stdout, '"', ''), "'", '')) | ||
} | ||
} | ||
|
||
|
||
// printing the list of paths provided | ||
core.debug('List of sha paths:') | ||
for (let sha of hashset) { | ||
for (const sha of hashset) { | ||
core.debug(sha) | ||
} | ||
|
||
const sorted = await quickSort(Array.from(hashset), (x, y) => { | ||
return isDescendant(x, y); | ||
}); | ||
const hashesList = [] | ||
|
||
// Get oldest and youngest | ||
const youngest = sorted[0]; | ||
const oldest = sorted[sorted.length -1]; | ||
for (const sha of hashset) { | ||
const result = await exec.getExecOutput( | ||
'git', | ||
['log', '--ancestry-path', `${sha}...HEAD`, "--pretty='%H'"], | ||
{silent: true} | ||
) | ||
|
||
core.setOutput('youngest', youngest); | ||
core.setOutput('oldest', oldest); | ||
const hashes = result.stdout | ||
.split(/\r?\n/) | ||
.map(x => replaceAll(replaceAll(x, '"', ''), "'", '')) | ||
.filter(x => x) | ||
|
||
hashes.push(sha) | ||
hashesList.push(hashes) | ||
} | ||
|
||
const smallestLength = Math.min(...hashesList.map(x => x.length)) | ||
let commonHash | ||
|
||
for (let i = 0; i < smallestLength; i++) { | ||
const values = hashesList.map(x => x[i]) | ||
const distinctValues = [...new Set(values)] | ||
if (distinctValues.length !== 1) { | ||
core.debug( | ||
`Found distinct hash value: ${JSON.stringify(distinctValues)}` | ||
) | ||
break | ||
} else { | ||
core.debug(`Setting common Hash to: ${distinctValues[0]}`) | ||
commonHash = distinctValues[0] | ||
} | ||
} | ||
|
||
core.setOutput('youngest', commonHash) | ||
} catch (error) { | ||
core.setFailed(error.message) | ||
} | ||
} | ||
|
||
run(); | ||
function replaceAll(str: string, find: string, replace: string): string { | ||
return str.replace(new RegExp(find, 'g'), replace) | ||
} | ||
|
||
run() |