import type {Context} from '@actions/github/lib/context'; import type {Octokit} from '@technote-space/github-action-helper/dist/types'; import type {Logger} from '@technote-space/github-action-log-helper'; import {setOutput} from '@actions/core'; import {Utils} from '@technote-space/github-action-helper'; import {getTargetRunId, isExcludeContext, isConsiderReRun, getIntervalMs, getFilteredRun} from './utils/misc'; import {cancelWorkflowRun, getWorkflowId, getWorkflowRun, getWorkflowRunUpdatedAt, getWorkflowRunNumber, getWorkflowRuns} from './utils/workflow'; export const execute = async(logger: Logger, octokit: Octokit, context: Context): Promise<void> => { if (isExcludeContext(context)) { logger.info('This is not target context.'); setOutput('ids', ''); return; } const runId = getTargetRunId(context); logger.info('run id: %d', runId); const run = await getWorkflowRun(runId, octokit, context); logger.startProcess('run:'); console.log(getFilteredRun(run)); logger.endProcess(); const workflowId = await getWorkflowId(run); logger.info('workflow id: %d', workflowId); const runs = await getWorkflowRuns(workflowId, logger, octokit, context); if (!runs.some(_run => _run.run_number === run.run_number)) { runs.push(run); } logger.startProcess('workflow runs:'); console.log(runs.map(run => getFilteredRun(run))); logger.endProcess(); // cancel all workflows except latest one (consider re-run) const runsWithUpdatedAt = runs.map(run => ({...run, updatedAt: getWorkflowRunUpdatedAt(run)})); const latestRunNumber = Math.max(...runsWithUpdatedAt.map(run => getWorkflowRunNumber(run))); const latestUpdatedAt = Math.max(...runsWithUpdatedAt.map(run => run.updatedAt)); const targetRuns = runsWithUpdatedAt.filter( run => getWorkflowRunNumber(run) < latestRunNumber && // not latest run (!isConsiderReRun() || run.updatedAt < latestUpdatedAt), // not re-run (only updated_at seems to be updated even when re-run) ); logger.log(); logger.startProcess('Cancelling...'); const interval = getIntervalMs(); await targetRuns.reduce(async(prev, run) => { await prev; logger.log('cancel: %d', run.id); try { await cancelWorkflowRun(run.id, octokit, context); } catch (error) { logger.error(error.message); } if (interval) { await Utils.sleep(interval); } }, Promise.resolve()); logger.info('total: %d', targetRuns.length); setOutput('ids', targetRuns.map(run => run.id).join(',')); logger.endProcess(); };