From 9e35c3aa8f7df196926f36973214b9af24b55e13 Mon Sep 17 00:00:00 2001 From: Seungpyo1007 Date: Thu, 18 Jun 2026 15:21:22 +0900 Subject: [PATCH 1/2] fix(site): show negative history deltas Related to #19 --- site/src/pages/index.astro | 5 +++-- site/src/scripts/techapi.js | 23 ++++++++++++++++------- site/src/styles/techapi.css | 3 +++ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/site/src/pages/index.astro b/site/src/pages/index.astro index 30636394c3a..45b6e90444f 100644 --- a/site/src/pages/index.astro +++ b/site/src/pages/index.astro @@ -48,8 +48,8 @@ const endpoints = [ TTechAPI diff --git a/site/src/scripts/techapi.js b/site/src/scripts/techapi.js index ac788e21ac3..74c742b716d 100644 --- a/site/src/scripts/techapi.js +++ b/site/src/scripts/techapi.js @@ -222,9 +222,16 @@ function countUp(node, target) { const prev = sumByKey(prevRows); return nextRows .map((row) => ({ key: row.key, delta: row.count - (prev[row.key] || 0) })) - .filter((row) => row.delta > 0) - .sort((a, b) => b.delta - a.delta) - .slice(0, 2); + .filter((row) => row.delta !== 0) + .sort((a, b) => Math.abs(b.delta) - Math.abs(a.delta)) + .slice(0, 3); + } + + function formatDelta(delta, baseline = false) { + if (baseline) return "baseline"; + if (delta > 0) return "+" + delta.toLocaleString(); + if (delta < 0) return delta.toLocaleString(); + return "no change"; } function renderHistory(points) { @@ -234,18 +241,19 @@ function countUp(node, target) { const range = Math.max(1, maxTotal - minTotal); chartEl.innerHTML = points.map((point) => { const pct = 18 + ((point.total - minTotal) / range) * 82; - const deltaText = point.delta > 0 ? "+" + point.delta.toLocaleString() : "baseline"; + const deltaText = formatDelta(point.delta, point.baseline); + const deltaClass = point.delta < 0 ? " is-negative" : ""; return ` ${point.total.toLocaleString()} - ${esc(deltaText)} + ${esc(deltaText)} `; }).join(""); listEl.innerHTML = points.slice().reverse().map((point) => { const changes = point.changes.length - ? point.changes.map((row) => `${shortLabel[row.key]} +${row.delta.toLocaleString()}`).join(", ") - : (point.delta > 0 ? `total +${point.delta.toLocaleString()}` : "baseline snapshot"); + ? point.changes.map((row) => `${shortLabel[row.key]} ${formatDelta(row.delta)}`).join(", ") + : (point.baseline ? "baseline snapshot" : `total ${formatDelta(point.delta)}`); return `
  • ${esc(point.title)} ${esc(point.when)} - ${esc(point.sha)} - ${esc(changes)} @@ -296,6 +304,7 @@ function countUp(node, target) { for (let i = 0; i < points.length; i++) { const prev = points[i - 1]; + points[i].baseline = !prev; points[i].delta = prev ? points[i].total - prev.total : 0; points[i].changes = largestChanges(prev?.rows, points[i].rows); } diff --git a/site/src/styles/techapi.css b/site/src/styles/techapi.css index edb6ae38f6d..ccbb490de2c 100644 --- a/site/src/styles/techapi.css +++ b/site/src/styles/techapi.css @@ -366,6 +366,9 @@ code, .mono { font-family: var(--mono); } font-size: 10px; color: var(--accent-text); } +.history-bar-delta.is-negative { + color: var(--err); +} .history-list li { display: grid; grid-template-columns: 12px 1fr; From cd07f7be74c349e688b5c7f0a7995f40576ad784 Mon Sep 17 00:00:00 2001 From: Seungpyo1007 Date: Thu, 18 Jun 2026 15:24:16 +0900 Subject: [PATCH 2/2] ci: stop auto-linking persistent trackers --- .github/workflows/pr-metadata.yml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.github/workflows/pr-metadata.yml b/.github/workflows/pr-metadata.yml index 59a6cff9bbf..72c4b50e6ec 100644 --- a/.github/workflows/pr-metadata.yml +++ b/.github/workflows/pr-metadata.yml @@ -40,18 +40,15 @@ jobs: }); const labels = new Set(); - const trackers = new Set(); const title = pr.title.toLowerCase(); for (const file of files) { const path = file.filename; const isDataDump = path.startsWith('site/public/v1/') || path === 'site/public/openapi.json'; if (path.startsWith('site/') && !isDataDump) { labels.add('site'); - trackers.add('#19'); } if (path.startsWith('data/') || isDataDump) { labels.add('data'); - trackers.add('#1'); } if (path.startsWith('app/')) labels.add('app'); if (path.startsWith('.github/workflows/')) labels.add('ci'); @@ -104,22 +101,6 @@ jobs: break; } - if (trackers.size) { - const marker = ''; - const existing = pr.body || ''; - const refs = [...trackers].sort().map((ref) => `- Related to ${ref}`).join('\n'); - const block = `${marker}\n\n## Tracking\n${refs}`; - const body = existing.includes(marker) - ? existing.replace(new RegExp(`${marker}[\\s\\S]*$`), block) - : `${existing.trim()}\n\n${block}`.trim(); - await github.rest.pulls.update({ - owner, - repo, - pull_number: issue_number, - body, - }); - } - const changedLines = files.reduce((sum, file) => sum + file.additions + file.deletions, 0); let priority = 'Medium'; if (labels.has('data') && (files.length >= 25 || changedLines >= 1000)) {