diff --git a/changelog.d/1583-workflow-runs-dedup.fixed.md b/changelog.d/1583-workflow-runs-dedup.fixed.md new file mode 100644 index 00000000..5c8cb099 --- /dev/null +++ b/changelog.d/1583-workflow-runs-dedup.fixed.md @@ -0,0 +1 @@ +With no run active and the last attempt failed, the workflow **Runs** tab listed that same attempt twice: a phantom row for the live run plus its own history row. It now lists one row per attempt — the failed attempt appears once, marked `Failed` — while a real retry still shows the earlier attempt and the current one ([#1583](https://github.com/ThinkFlowLab/FlyBot/issues/1583)). diff --git a/plugins/workflow/client.js b/plugins/workflow/client.js index 750fa802..21c1a8f6 100644 --- a/plugins/workflow/client.js +++ b/plugins/workflow/client.js @@ -693,7 +693,11 @@ window.__ModuleLoader__.load({ current: workflow.run?.id === run.id, })) for (const task of queued) rows.push({ task, status: 'queued', current: false }) - const seen = new Set(rows.map(row => row.id ?? `${row.task?.id ?? ''}|${row.at ?? ''}`)) + const seen = new Set() + for (const row of rows) { + if (row.id) seen.add(row.id) + seen.add(`${row.task?.id ?? ''}|${row.at ?? ''}`) + } for (const item of history) { const key = item.id ?? `${item.task?.id ?? ''}|${item.at ?? ''}` if (seen.has(key)) continue diff --git a/plugins/workflow/test/client.test.js b/plugins/workflow/test/client.test.js index 0746bcd4..3d209dd6 100644 --- a/plugins/workflow/test/client.test.js +++ b/plugins/workflow/test/client.test.js @@ -931,6 +931,36 @@ test('run history does not invent a second running row when only one live run ex assert.equal(rows.filter(row => row.status === 'running').length, 1) }) +test('a failed live attempt is listed once, as failed, not as its own history row (#1583)', () => { + const task = { id: '#1422', title: 'PR 1422' } + const workflow = { + activeCount: 0, + queue: [], + runs: [{ id: 'run-a', live: true, status: 'failed', task, updatedAt: 1_700_000_000_000 }], + run: { id: 'run-a', live: true, status: 'failed', task, updatedAt: 1_700_000_000_000 }, + history: [{ task, status: 'failed', at: 1_700_000_000_000 }], + } + const rows = client.runHistoryRows(workflow) + assert.equal(rows.length, 1) + assert.equal(rows[0].status, 'failed') + assert.equal(rows.filter(row => row.status === 'running').length, 0) +}) + +test('a genuine retry still shows the failed attempt and the current one (#1583)', () => { + const task = { id: '#1422', title: 'PR 1422' } + const workflow = { + activeCount: 1, + queue: [], + runs: [{ id: 'run-b', live: true, status: 'running', task, updatedAt: 1_700_000_100_000 }], + run: { id: 'run-b', live: true, status: 'running', task, updatedAt: 1_700_000_100_000 }, + history: [{ task, status: 'failed', at: 1_700_000_000_000 }], + } + const rows = client.runHistoryRows(workflow) + assert.equal(rows.length, 2) + assert.deepEqual(rows.map(row => row.status), ['running', 'failed']) + assert.deepEqual(rows.map(row => row.current), [true, false]) +}) + test('the runs tab shows one running row per concurrent live run', async () => { const graph = delivery() graph.activeCount = 2