Skip to content

Commit

Permalink
Only consider the most recent check run
Browse files Browse the repository at this point in the history
Signed-off-by: Alexandre Barone <abalexandrebarone@gmail.com>
  • Loading branch information
devodev committed Dec 19, 2024
1 parent f5a78e8 commit 5103a2d
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 35 deletions.
106 changes: 105 additions & 1 deletion __tests__/main.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {wait} from '../src/wait'
import {expect, test} from '@jest/globals'
import {CheckRun, filterCheckRuns} from '../src/poll'
import {describe, expect, test} from '@jest/globals'

test('throws invalid number', async () => {
const input = parseInt('foo', 10)
Expand All @@ -13,3 +14,106 @@ test('wait 500 ms', async () => {
var delta = Math.abs(end.getTime() - start.getTime())
expect(delta).toBeGreaterThan(450)
})

describe('filterCheckRuns', () => {
const test_cases: {
name: string,
runs: CheckRun[],
expected: CheckRun[],
matchPattern?: string,
ignoreChecks?: string[],
ignorePattern?: string | undefined,
}[] = [
{ name: 'empty', runs: [], expected: [] },
{
name: '1 run no filter',
runs: [{ name: 'check1', started_at: '2024-01-01T00:00:00', status: 'completed', conclusion: 'success' }],
expected: [{ name: 'check1', started_at: '2024-01-01T00:00:00', status: 'completed', conclusion: 'success' }],
},
{
name: '2 runs no filter',
runs: [
{ name: 'check1', started_at: '2024-01-01T00:00:00', status: 'completed', conclusion: 'success' },
{ name: 'check2', started_at: '2024-01-01T00:01:00', status: 'completed', conclusion: 'success' },
],
expected: [
{ name: 'check1', started_at: '2024-01-01T00:00:00', status: 'completed', conclusion: 'success' },
{ name: 'check2', started_at: '2024-01-01T00:01:00', status: 'completed', conclusion: 'success' },
],
},
{
name: 'matchPattern',
matchPattern: 'check-(cat|dog)',
runs: [
{ name: 'check-cat', started_at: '2024-01-01T00:00:00', status: 'completed', conclusion: 'success' },
{ name: 'check-dog', started_at: '2024-01-01T00:01:00', status: 'completed', conclusion: 'success' },
{ name: 'check-bird', started_at: '2024-01-01T00:02:00', status: 'completed', conclusion: 'success' },
],
expected: [
{ name: 'check-cat', started_at: '2024-01-01T00:00:00', status: 'completed', conclusion: 'success' },
{ name: 'check-dog', started_at: '2024-01-01T00:01:00', status: 'completed', conclusion: 'success' },
],
},
{
name: 'ignoreChecks',
ignoreChecks: ['check-dog', 'check-bird'],
runs: [
{ name: 'check-cat', started_at: '2024-01-01T00:00:00', status: 'completed', conclusion: 'success' },
{ name: 'check-dog', started_at: '2024-01-01T00:01:00', status: 'completed', conclusion: 'success' },
{ name: 'check-bird', started_at: '2024-01-01T00:02:00', status: 'completed', conclusion: 'success' },
],
expected: [
{ name: 'check-cat', started_at: '2024-01-01T00:00:00', status: 'completed', conclusion: 'success' },
],
},
{
name: 'ignorePattern',
ignorePattern: 'check-(cat|dog)',
runs: [
{ name: 'check-cat', started_at: '2024-01-01T00:00:00', status: 'completed', conclusion: 'success' },
{ name: 'check-dog', started_at: '2024-01-01T00:01:00', status: 'completed', conclusion: 'success' },
{ name: 'check-bird', started_at: '2024-01-01T00:02:00', status: 'completed', conclusion: 'success' },
],
expected: [
{ name: 'check-bird', started_at: '2024-01-01T00:02:00', status: 'completed', conclusion: 'success' },
],
},
{
name: 'only keep most recent runs',
ignorePattern: 'check-(cat|dog)',
runs: [
{ name: 'check', started_at: '2024-01-01T00:00:00', status: 'completed', conclusion: 'failure' },
{ name: 'check', started_at: '2024-01-01T00:01:00', status: 'completed', conclusion: 'failure' },
{ name: 'check', started_at: '2024-01-01T00:02:00', status: 'completed', conclusion: 'success' },
],
expected: [
{ name: 'check', started_at: '2024-01-01T00:02:00', status: 'completed', conclusion: 'success' },
],
},
{
name: 'all filters',
matchPattern: 'check-',
ignoreChecks: ['check-dog', 'check-bird'],
ignorePattern: 'check-(zebra|lion)',
runs: [
{ name: 'check-cat', started_at: '2024-01-01T00:00:00', status: 'completed', conclusion: 'failure' },
{ name: 'check-cat', started_at: '2024-01-01T00:01:00', status: 'completed', conclusion: 'failure' },
{ name: 'check-cat', started_at: '2024-01-01T00:02:00', status: 'completed', conclusion: 'success' },
{ name: 'check-dog', started_at: '2024-01-01T00:01:00', status: 'completed', conclusion: 'success' },
{ name: 'check-bird', started_at: '2024-01-01T00:02:00', status: 'completed', conclusion: 'success' },
{ name: 'check-zebra', started_at: '2024-01-01T00:00:00', status: 'completed', conclusion: 'success' },
{ name: 'check-lion', started_at: '2024-01-01T00:00:00', status: 'completed', conclusion: 'success' },
],
expected: [
{ name: 'check-cat', started_at: '2024-01-01T00:02:00', status: 'completed', conclusion: 'success' },
],
},
];

test_cases.forEach(({ name, runs, matchPattern, ignoreChecks, ignorePattern, expected }) => {
test(name, () => {
const result = filterCheckRuns(runs, matchPattern, ignoreChecks || [], ignorePattern);
expect(result).toStrictEqual(expected);
});
});
});
42 changes: 28 additions & 14 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.

60 changes: 41 additions & 19 deletions src/poll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,24 +79,7 @@ export async function poll(config: Config): Promise<void> {

core.debug(`Received ${totalChecks} total check runs`)

// ignore the current job's check run
let check_runs = all_check_runs.filter(
run => !ignoreChecks.includes(run.name)
)

// filter by match pattern
if (matchPattern) {
core.debug(`Filtering check runs by match pattern: ${matchPattern}`)
const pattern = new RegExp(matchPattern)
check_runs = check_runs.filter(run => pattern.test(run.name))
}

// filter by ignore pattern
if (ignorePattern) {
core.debug(`Filtering check runs by ignore pattern: ${ignorePattern}`)
const pattern = new RegExp(ignorePattern)
check_runs = check_runs.filter(run => !pattern.test(run.name))
}
let check_runs = filterCheckRuns(all_check_runs, matchPattern, ignoreChecks, ignorePattern)

core.info(`Parse ${check_runs.length} check runs`)
for (const run of check_runs) {
Expand All @@ -109,6 +92,7 @@ export async function poll(config: Config): Promise<void> {
const failed = check_runs.filter(run =>
isFailure({
name: run.name,
started_at: run.started_at,
status: run.status,
conclusion: run.conclusion
})
Expand Down Expand Up @@ -153,6 +137,43 @@ export async function poll(config: Config): Promise<void> {
)
}

export function filterCheckRuns(
runs: CheckRun[],
matchPattern: string | undefined,
ignoreChecks: string[],
ignorePattern: string | undefined,
): CheckRun[] {
// ignore the current job's check run
let checkRuns = runs.filter(
run => !ignoreChecks.includes(run.name)
)

// filter by match pattern
if (matchPattern) {
core.debug(`Filtering check runs by match pattern: ${matchPattern}`)
const pattern = new RegExp(matchPattern)
checkRuns = checkRuns.filter(run => pattern.test(run.name))
}

// filter by ignore pattern
if (ignorePattern) {
core.debug(`Filtering check runs by ignore pattern: ${ignorePattern}`)
const pattern = new RegExp(ignorePattern)
checkRuns = checkRuns.filter(run => !pattern.test(run.name))
}

// filter by latest run to avoid reporting failures for checks
// that are triggered for the same SHA (ex.: pull_request.edited).
let checkRunsByName = checkRuns.reduce<Map<string, CheckRun>>((map, check) => {
if (!map.has(check.name) || new Date(check.started_at || '') > new Date(map.get(check.name)!.started_at || '')) {
map.set(check.name, check);
}
return map;
}, new Map<string, CheckRun>());

return [...checkRunsByName.values()]
}

function isFailure(run: CheckRun): boolean {
if (run.status === 'completed') {
// all conclusions besides success or skipped are considered failures
Expand All @@ -162,8 +183,9 @@ function isFailure(run: CheckRun): boolean {
return false
}

interface CheckRun {
export interface CheckRun {
name: string
started_at: string | null
status: string
conclusion:
| (
Expand Down

0 comments on commit 5103a2d

Please sign in to comment.