fix: improve workflow run detection for cancelled jobs
Some checks failed
🏗️ Build Apps / 🤖 Build Android APK (Phone) (push) Has been cancelled
🏗️ Build Apps / 🤖 Build Android APK (TV) (push) Has been cancelled
🏗️ Build Apps / 🍎 Build iOS IPA (Phone) (push) Has been cancelled
🔒 Lockfile Consistency Check / 🔍 Check bun.lock and package.json consistency (push) Has been cancelled
🛡️ CodeQL Analysis / 🔎 Analyze with CodeQL (actions) (push) Has been cancelled
🛡️ CodeQL Analysis / 🔎 Analyze with CodeQL (javascript-typescript) (push) Has been cancelled
🏷️🔀Merge Conflict Labeler / 🏷️ Labeling Merge Conflicts (push) Has been cancelled
🚦 Security & Quality Gate / 📝 Validate PR Title (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Vulnerable Dependencies (push) Has been cancelled
🚦 Security & Quality Gate / 🚑 Expo Doctor Check (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Lint & Test (check) (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Lint & Test (format) (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Lint & Test (lint) (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Lint & Test (typecheck) (push) Has been cancelled

Enhances the artifact comment workflow to better handle cancelled workflow runs by checking individual job statuses instead of dismissing entire workflows.

Previously, workflows marked as cancelled at the top level were completely ignored, even if some jobs within them were still running or completed successfully.

Now prioritizes active jobs over cancelled ones and validates that at least one job is actually running before processing a workflow run, preventing false negatives while still filtering out truly cancelled workflows.
This commit is contained in:
Uruk
2025-09-30 02:15:25 +02:00
parent 71a3c5e92b
commit c6ad06b084

View File

@@ -112,13 +112,12 @@ jobs:
per_page: 30 per_page: 30
}); });
// Filter for build workflows only, exclude cancelled runs, and sort by creation time (most recent first) // Filter for build workflows only, include active runs even if marked as cancelled
const buildRuns = workflowRuns.workflow_runs const buildRuns = workflowRuns.workflow_runs
.filter(run => .filter(run =>
(run.name.includes('Build Apps') || (run.name.includes('Build Apps') ||
run.name.includes('Android APK Build') || run.name.includes('Android APK Build') ||
run.name.includes('iOS IPA Build')) && run.name.includes('iOS IPA Build'))
run.conclusion !== 'cancelled' // Ignore cancelled runs
) )
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at)); .sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
@@ -133,16 +132,28 @@ jobs:
let allArtifacts = []; let allArtifacts = [];
let buildStatuses = {}; let buildStatuses = {};
// Get the most relevant run for each workflow type (prioritize in_progress over completed) // Get the most relevant run for each workflow type (prioritize active over cancelled)
const findBestRun = (nameFilter) => { const findBestRun = (nameFilter) => {
const matchingRuns = buildRuns.filter(run => run.name.includes(nameFilter)); const matchingRuns = buildRuns.filter(run => run.name.includes(nameFilter));
// First try to find an in-progress run // First try to find an in-progress run
const inProgressRun = matchingRuns.find(run => run.status === 'in_progress'); const inProgressRun = matchingRuns.find(run => run.status === 'in_progress');
if (inProgressRun) return inProgressRun; if (inProgressRun) return inProgressRun;
// Then try to find a queued run // Then try to find a queued run
const queuedRun = matchingRuns.find(run => run.status === 'queued'); const queuedRun = matchingRuns.find(run => run.status === 'queued');
if (queuedRun) return queuedRun; if (queuedRun) return queuedRun;
// Finally fall back to most recent completed run
// Check if the workflow is completed but has non-cancelled jobs
const completedRuns = matchingRuns.filter(run => run.status === 'completed');
for (const run of completedRuns) {
// We'll check individual jobs later to see if they're actually running
if (run.conclusion !== 'cancelled') {
return run;
}
}
// Finally fall back to most recent run (even if cancelled at workflow level)
return matchingRuns[0]; // Already sorted by most recent first return matchingRuns[0]; // Already sorted by most recent first
}; };
@@ -152,7 +163,7 @@ jobs:
// For the consolidated workflow, get individual job statuses // For the consolidated workflow, get individual job statuses
if (latestAppsRun) { if (latestAppsRun) {
console.log(`Getting individual job statuses for run ${latestAppsRun.id}`); console.log(`Getting individual job statuses for run ${latestAppsRun.id} (status: ${latestAppsRun.status}, conclusion: ${latestAppsRun.conclusion || 'none'})`);
try { try {
// Get all jobs for this workflow run // Get all jobs for this workflow run
@@ -167,6 +178,21 @@ jobs:
console.log(`- Job: ${job.name} | Status: ${job.status} | Conclusion: ${job.conclusion || 'none'}`); console.log(`- Job: ${job.name} | Status: ${job.status} | Conclusion: ${job.conclusion || 'none'}`);
}); });
// Check if we have any actually running jobs (not cancelled)
const activeJobs = jobs.jobs.filter(job =>
job.status === 'in_progress' ||
job.status === 'queued' ||
(job.status === 'completed' && job.conclusion !== 'cancelled')
);
console.log(`Found ${activeJobs.length} active (non-cancelled) jobs out of ${jobs.jobs.length} total jobs`);
// If no jobs are actually running, skip this workflow
if (activeJobs.length === 0 && latestAppsRun.conclusion === 'cancelled') {
console.log('All jobs are cancelled, skipping this workflow run');
return; // Exit early
}
// Map job names to our build targets // Map job names to our build targets
const jobMappings = { const jobMappings = {
'Android Phone': ['🤖 Build Android APK (Phone)', 'build-android-phone'], 'Android Phone': ['🤖 Build Android APK (Phone)', 'build-android-phone'],