Skip to content

Commit

Permalink
Merge pull request #133 from cactusoft-ca/feature/change-calculation-…
Browse files Browse the repository at this point in the history
…of-latest-sha

Feature/change calculation of latest sha
  • Loading branch information
plchampigny authored Jul 13, 2022
2 parents d4b62a8 + f978374 commit da717df
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 191 deletions.
131 changes: 37 additions & 94 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typescript-action",
"version": "0.0.0",
"version": "2.0.0",
"private": true,
"description": "TypeScript template action",
"main": "lib/main.js",
Expand Down
145 changes: 50 additions & 95 deletions src/main.ts
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()

0 comments on commit da717df

Please sign in to comment.