-
Notifications
You must be signed in to change notification settings - Fork 1
ci: publish built binaries with run history #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4ce59a0
0951da8
144b20e
fee9bbc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -80,8 +80,12 @@ function runNumber(run) { | |
| return run.number == null ? run.key : "#" + run.number; | ||
| } | ||
|
|
||
| function commitLabel(run) { | ||
| return shortSha(run.llgoCommit || run.sourceCommit || run.key); | ||
| } | ||
|
|
||
| function runLabel(run) { | ||
| return runNumber(run) + " · " + dateLabel(run.createdAt); | ||
| return commitLabel(run) + " · " + dateLabel(run.createdAt); | ||
| } | ||
|
|
||
| async function loadRun(meta) { | ||
|
|
@@ -154,8 +158,8 @@ function renderComparison(newer, baseline) { | |
| const baselineByName = baseline ? benchmarkMap(baseline) : new Map(); | ||
| const benchmarkNames = Array.from(new Set(Array.from(newerByName.keys()).concat(Array.from(baselineByName.keys())))).sort(); | ||
|
|
||
| const newerHeading = "Newer · " + runNumber(newer.run); | ||
| const baselineHeading = baseline ? "Older · " + runNumber(baseline.run) : "Older"; | ||
| const newerHeading = "Newer · " + commitLabel(newer.run); | ||
| const baselineHeading = baseline ? "Older · " + commitLabel(baseline.run) : "Older"; | ||
| grid.innerHTML = benchmarkNames.map(function (name) { | ||
| const newerBenchmark = newerByName.get(name); | ||
| const baselineBenchmark = baselineByName.get(name); | ||
|
|
@@ -178,13 +182,10 @@ function renderHistoryTable(runs) { | |
| const body = document.querySelector("#history-body"); | ||
| body.replaceChildren(); | ||
| for (const run of runs) { | ||
| const link = run.workflowUrl | ||
| ? '<a href="' + escapeHtml(run.workflowUrl) + '">' + escapeHtml(runNumber(run)) + "</a>" | ||
| : escapeHtml(runNumber(run)); | ||
| const row = document.createElement("tr"); | ||
| row.innerHTML = | ||
| "<td>" + link + "<small>" + escapeHtml(dateLabel(run.createdAt)) + "</small></td>" + | ||
| "<td><code>" + escapeHtml(shortSha(run.llgoCommit)) + "</code></td>" + | ||
| "<td><code>" + (run.workflowUrl ? '<a href="' + escapeHtml(run.workflowUrl) + '">' : "") + escapeHtml(commitLabel(run)) + (run.workflowUrl ? "</a>" : "") + "</td>" + | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Malformed HTML: unclosed |
||
| "<td>" + escapeHtml(dateLabel(run.createdAt)) + "</td>" + | ||
| "<td>" + escapeHtml(run.goVersion || "—") + "</td>" + | ||
| "<td>" + escapeHtml(run.llvmVersion || "—") + "</td>" + | ||
| "<td>" + escapeHtml(run.ref || "—") + "</td>"; | ||
|
|
@@ -238,11 +239,11 @@ function renderHistoryChart(name, documents) { | |
| const color = seriesColors[configIndex % seriesColors.length]; | ||
| return '<path d="' + chartPath(points, x, y) + '" fill="none" stroke="' + color + '" stroke-width="2.5"></path>' + points.map(function (point) { | ||
| return '<circle cx="' + x(point.index) + '" cy="' + y(point.value) + '" r="3.5" fill="' + color + '"><title>' + | ||
| escapeHtml(name + " · " + config + " · " + runNumber(point.document.run) + ": " + formatBytes(point.value)) + "</title></circle>"; | ||
| escapeHtml(name + " · " + config + " · " + commitLabel(point.document.run) + ": " + formatBytes(point.value)) + "</title></circle>"; | ||
| }).join(""); | ||
| }).join(""); | ||
| const labels = documents.map(function (document, index) { | ||
| return '<text class="chart-axis-label" text-anchor="middle" x="' + x(index) + '" y="' + (height - 14) + '">' + escapeHtml(runNumber(document.run)) + "</text>"; | ||
| return '<text class="chart-axis-label" text-anchor="middle" x="' + x(index) + '" y="' + (height - 14) + '">' + escapeHtml(commitLabel(document.run)) + "</text>"; | ||
| }).join(""); | ||
| const legend = configs.map(function (config, index) { | ||
| return '<span style="--series:' + seriesColors[index % seriesColors.length] + '">' + escapeHtml(configLabels[config] || config) + "</span>"; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,7 @@ | |
| <meta charset="utf-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1"> | ||
| <title>LLGo binary-size history</title> | ||
| <link rel="stylesheet" href="style.css?v=20260722-2300"> | ||
| <link rel="stylesheet" href="style.css?v=20260723-1200"> | ||
| </head> | ||
| <body> | ||
| <main class="shell"> | ||
|
|
@@ -47,7 +47,7 @@ <h2 id="history-heading">Size history</h2> | |
| <div id="history-charts" class="chart-grid" aria-live="polite"></div> | ||
| <div class="table-wrap"> | ||
| <table> | ||
| <thead><tr><th>Run</th><th>LLGo commit</th><th>Go</th><th>LLVM</th><th>Workflow</th></tr></thead> | ||
| <thead><tr><th>LLGo commit</th><th>Created</th><th>Go</th><th>LLVM</th><th>Workflow</th></tr></thead> | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Header/content mismatch: the last column header is |
||
| <tbody id="history-body"></tbody> | ||
| </table> | ||
| </div> | ||
|
|
@@ -59,6 +59,6 @@ <h2 id="history-heading">Size history</h2> | |
| <a href="data/index.json">Raw run index</a> | ||
| </footer> | ||
| </main> | ||
| <script src="app.js?v=20260722-2300"></script> | ||
| <script src="app.js?v=20260723-1200"></script> | ||
| </body> | ||
| </html> | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Path-traversal / destructive-op gap: the key comes from
results.jsoncontent (llgoCommit/sourceCommit) and the only guard isre.fullmatch(r"[A-Za-z0-9._-]+", ...), which matches.and... Aresults.jsonin the persistedpageshistory whosellgoCommitis".."yieldstarget_dir = runs_dir/..=.../data, soshutil.rmtree(target_dir)(below) wipes the entire published history andos.renamethen clobbersdata."."similarly targets the runs dir itself.Under the happy path values are 40-char SHAs (
LLGO_COMMITis validated upstream), so this is defense-in-depth rather than an active exploit — but the sole protection deliberately permits the traversal tokens. Reject bare dots explicitly, e.g. addor str(key) in (".", "..")to this skip condition, and apply the same fix to therun_keyvalidator at line 80 (ideally a shared SHA-shaped pattern like^[0-9a-f]{7,40}$).