From 23c89d0cfe76570b71fcdf417bf184ce981fbb07 Mon Sep 17 00:00:00 2001 From: a Date: Tue, 7 Jul 2026 22:43:13 -0500 Subject: [PATCH 1/4] Add download-beta page with live build progress New /download-beta page that uses the streaming build API: - Same look and feel as the existing /download page (same CSS, header, footer, package rendering with icons, download counts, version inputs, module docs previews) - Vanilla JS instead of jQuery - Clicking Download posts to /api/build, then navigates to /download-beta/build/?key={hash} for live progress - Build page shows current step label, progress bar, and scrolling build log via SSE - Auto-downloads the artifact on completion with a fallback 'click here' link - If the build is already cached, skips straight to download --- src/download-beta/build/index.html | 56 +++++ src/download-beta/index.html | 90 +++++++ src/resources/css/download-beta.css | 60 +++++ src/resources/js/download-beta-build.js | 122 ++++++++++ src/resources/js/download-beta.js | 304 ++++++++++++++++++++++++ 5 files changed, 632 insertions(+) create mode 100644 src/download-beta/build/index.html create mode 100644 src/download-beta/index.html create mode 100644 src/resources/css/download-beta.css create mode 100644 src/resources/js/download-beta-build.js create mode 100644 src/resources/js/download-beta.js diff --git a/src/download-beta/build/index.html b/src/download-beta/build/index.html new file mode 100644 index 00000000..136cd151 --- /dev/null +++ b/src/download-beta/build/index.html @@ -0,0 +1,56 @@ + + + + Building Caddy + {{import "/old/includes/head.html"}} + {{template "head"}} + + + + + +
+
+
+ +
a project
+
+ {{include "/old/includes/header-nav.html"}} +
+ +
+

Building Caddy...

+

Your custom build is in progress. This page will update automatically.

+ +
+
Waiting for build to start...
+
+
+
+
+ +
+
+
+ + +
+
+ + {{include "/old/includes/footer.html"}} + + diff --git a/src/download-beta/index.html b/src/download-beta/index.html new file mode 100644 index 00000000..839b3530 --- /dev/null +++ b/src/download-beta/index.html @@ -0,0 +1,90 @@ + + + + Download Caddy + {{import "/old/includes/head.html"}} + {{template "head"}} + + + + + +
+
+
+ +
a project
+
+ {{include "/old/includes/header-nav.html"}} +
+ +
+
+
+ Platform: + +
+
+
+
+ Standard features: ☑️ +
+
+
+
+ Extra features: 0 +
+
+
+ Download +
+
+ + + +
+ Only choose plugins you need and trust +
+
+ Run the following against the downloaded binary: + xattr -d com.apple.quarantine + +
+ +
+ +
+
+ + {{include "/old/includes/footer.html"}} + + diff --git a/src/resources/css/download-beta.css b/src/resources/css/download-beta.css new file mode 100644 index 00000000..c3dd024c --- /dev/null +++ b/src/resources/css/download-beta.css @@ -0,0 +1,60 @@ +/* Download Beta - additions on top of /old/resources/css/download.css */ + +/* Build progress page */ + +#build-page { + max-width: 700px; + margin: 0 auto; + padding: 40px 20px; +} + +.stage-label { + font-size: 22px; + font-weight: 600; + margin-bottom: 12px; + min-height: 1.4em; + transition: opacity 200ms ease; +} + +.progress-bar { + width: 100%; + height: 8px; + background: #e8e8e8; + border-radius: 4px; + overflow: hidden; + margin: 0 0 16px; +} + +.progress-bar-fill { + height: 100%; + background: rgb(25, 97, 192); + border-radius: 4px; + width: 0%; + transition: width 400ms ease; +} + +#build-log-container { + background: #1a1a2e; + color: #ccc; + border-radius: 8px; + padding: 16px; + max-height: 300px; + overflow-y: auto; + font-family: 'PT Mono', monospace; + font-size: 12px; + line-height: 1.6; + margin: 16px 0; +} + +#build-log { + white-space: pre-wrap; + word-break: break-all; +} + +#build-result { + text-align: center; + margin-top: 24px; +} + +.text-error { color: #cc0000; } +.hidden { display: none; } diff --git a/src/resources/js/download-beta-build.js b/src/resources/js/download-beta-build.js new file mode 100644 index 00000000..866d50e9 --- /dev/null +++ b/src/resources/js/download-beta-build.js @@ -0,0 +1,122 @@ +// Download Beta - Build progress page +// Connects to SSE at /api/build/{key}/events and shows live progress. +// Auto-downloads the artifact on completion. + +var STEP_LABELS = { + 'create_environment': 'Setting up build environment', + 'initialize_module': 'Initializing Go module', + 'pin_versions': 'Downloading dependencies', + 'windows_resources': 'Generating Windows resources', + 'tidy_module': 'Resolving modules', + 'compile': 'Compiling', + 'cleanup': 'Cleaning up', +}; + +var STEP_ORDER = [ + 'create_environment', + 'initialize_module', + 'pin_versions', + 'tidy_module', + 'compile', + 'cleanup', +]; + +function getStepProgress(step) { + var idx = STEP_ORDER.indexOf(step); + if (idx === -1) return 0; + return Math.round(((idx + 1) / STEP_ORDER.length) * 100); +} + +document.addEventListener('DOMContentLoaded', function() { + var params = new URLSearchParams(window.location.search); + var key = params.get('key'); + + if (!key) { + showError('No build key provided.'); + return; + } + + var downloadUrl = '/api/build/' + key + '/download'; + document.getElementById('download-link').href = downloadUrl; + + // connect to SSE + var evtSource = new EventSource('/api/build/' + key + '/events'); + var logEl = document.getElementById('build-log'); + var logContainer = document.getElementById('build-log-container'); + + evtSource.addEventListener('step', function(e) { + try { + var data = JSON.parse(e.data); + var label = STEP_LABELS[data.step] || data.step; + document.getElementById('current-step').textContent = label + '...'; + document.getElementById('progress-fill').style.width = getStepProgress(data.step) + '%'; + } catch(err) {} + }); + + evtSource.addEventListener('log', function(e) { + try { + var data = JSON.parse(e.data); + if (data.line) { + logEl.textContent += data.line + '\n'; + logContainer.scrollTop = logContainer.scrollHeight; + } + } catch(err) {} + }); + + evtSource.addEventListener('result', function(e) { + evtSource.close(); + try { + var data = JSON.parse(e.data); + if (data.success) { + showSuccess(downloadUrl); + } else { + showError(data.error || 'Build failed.'); + } + } catch(err) { + showError('Failed to parse build result.'); + } + }); + + evtSource.onerror = function() { + evtSource.close(); + // check if build completed while we were disconnected + fetch(downloadUrl, { method: 'HEAD' }).then(function(r) { + if (r.ok) { + showSuccess(downloadUrl); + } else { + showError('Lost connection to the build server.'); + } + }).catch(function() { + showError('Lost connection to the build server.'); + }); + }; +}); + +function showSuccess(downloadUrl) { + document.getElementById('build-title').textContent = 'Build Complete'; + document.getElementById('build-subtitle').textContent = ''; + document.getElementById('progress-fill').style.width = '100%'; + document.getElementById('current-step').textContent = 'Done'; + + document.getElementById('build-result').classList.remove('hidden'); + document.getElementById('result-success').classList.remove('hidden'); + + // auto-download via hidden link + var a = document.createElement('a'); + a.href = downloadUrl; + a.download = ''; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); +} + +function showError(msg) { + document.getElementById('build-title').textContent = 'Build Failed'; + document.getElementById('build-subtitle').textContent = ''; + document.getElementById('progress-fill').style.width = '0%'; + document.getElementById('current-step').textContent = ''; + + document.getElementById('build-result').classList.remove('hidden'); + document.getElementById('result-error').classList.remove('hidden'); + document.getElementById('error-message').textContent = msg; +} diff --git a/src/resources/js/download-beta.js b/src/resources/js/download-beta.js new file mode 100644 index 00000000..235bc955 --- /dev/null +++ b/src/resources/js/download-beta.js @@ -0,0 +1,304 @@ +// Download Beta - Main page +// Same layout as the original download page, but uses vanilla JS +// and the new /api/build endpoint for streaming builds. + +function detectPlatform() { + var os = 'linux', arch = 'amd64'; + if (/Macintosh/i.test(navigator.userAgent)) os = 'darwin'; + else if (/Windows/i.test(navigator.userAgent)) os = 'windows'; + else if (/FreeBSD/i.test(navigator.userAgent)) os = 'freebsd'; + else if (/OpenBSD/i.test(navigator.userAgent)) os = 'openbsd'; + + if (os === 'darwin' || /amd64|x64|x86_64|Win64|WOW64|i686|64-bit/i.test(navigator.userAgent)) { + arch = 'amd64'; + } else if (/arm64/.test(navigator.userAgent)) { + arch = 'arm64'; + } else if (/ ARM| armv/.test(navigator.userAgent)) { + arch = 'arm'; + var armVer = /armv6/.test(navigator.userAgent) ? '6' + : /armv5/.test(navigator.userAgent) ? '5' : '7'; + arch += armVer; + } + return [os, arch]; +} + +function truncate(str, maxLen) { + if (!str) return ''; + str = str.trim(); + var m = str.match(/\.(\s|$)/); + var end = m ? m.index + 1 : str.length; + str = str.substring(0, end); + return str.length <= maxLen ? str : str.substring(0, maxLen) + '...'; +} + +function moduleDocsPreview(mod, maxLen) { + if (!mod || !mod.docs) return ''; + var short = truncate(mod.docs, maxLen); + if (short.indexOf(mod.name) === 0) { + short = short.substr(mod.name.length).trim(); + } + return short; +} + +function splitVCSProvider(pkgPath) { + var providers = ['github.com/', 'bitbucket.org/']; + for (var i = 0; i < providers.length; i++) { + if (pkgPath.toLowerCase().indexOf(providers[i]) === 0) { + return { provider: providers[i], path: pkgPath.slice(providers[i].length) }; + } + } + return { provider: '', path: pkgPath }; +} + +function getBuildParams() { + var platformStr = document.getElementById('platform').value || 'linux-amd64'; + var parts = platformStr.split('-'); + var os = parts[0], arch = parts[1], arm = parts[2] || ''; + var qs = new URLSearchParams(); + if (os) qs.set('os', os); + if (arch) qs.set('arch', arch); + if (arm) qs.set('arm', arm); + + document.querySelectorAll('#optional-packages .package.selected').forEach(function(el) { + var path = el.querySelector('.package-link').textContent.trim(); + var ver = el.querySelector('input[name=version]'); + if (ver && ver.value.trim()) { + path += '@' + ver.value.trim(); + } + qs.append('p', path); + }); + + return qs; +} + +// Load packages +fetch('/api/packages').then(function(r) { return r.json(); }).then(function(json) { + var packageList = json.result || []; + packageList.sort(function(a, b) { return b.downloads - a.downloads; }); + + var preselected = new URL(window.location.href).searchParams.getAll('package'); + + function renderWhenReady() { + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', render); + } else { + render(); + } + } + + function render() { + var container = document.getElementById('optional-packages'); + + for (var i = 0; i < packageList.length; i++) { + var pkg = packageList[i]; + + var pkgEl = document.createElement('div'); + pkgEl.className = 'package'; + + // icon + var iconEl = document.createElement('div'); + iconEl.className = 'package-icon'; + iconEl.textContent = '\uD83D\uDCE6'; // 📦 + pkgEl.appendChild(iconEl); + + // data container + var dataEl = document.createElement('div'); + dataEl.className = 'package-data'; + + // meta (downloads + version input) + var metaEl = document.createElement('div'); + metaEl.className = 'package-meta'; + metaEl.innerHTML = 'downloads: ' + pkg.downloads + ' ' + + 'version: '; + dataEl.appendChild(metaEl); + + // package link + var linkEl = document.createElement('a'); + linkEl.className = 'package-link'; + linkEl.target = '_blank'; + linkEl.title = 'View package repo'; + linkEl.href = pkg.repo || '#'; + + var split = splitVCSProvider(pkg.path); + if (split.provider) { + var hostSpan = document.createElement('span'); + hostSpan.className = 'package-host'; + hostSpan.textContent = split.provider; + linkEl.appendChild(hostSpan); + linkEl.appendChild(document.createElement('br')); + } + var nameSpan = document.createElement('span'); + nameSpan.className = 'package-name'; + nameSpan.textContent = split.path; + linkEl.appendChild(nameSpan); + dataEl.appendChild(linkEl); + + // modules + var modulesEl = document.createElement('div'); + modulesEl.className = 'package-modules'; + + if (pkg.modules && pkg.modules.length > 0) { + for (var j = 0; j < pkg.modules.length; j++) { + var mod = pkg.modules[j]; + var modEl = document.createElement('div'); + modEl.className = 'module'; + + var modLink = document.createElement('a'); + modLink.className = 'module-link'; + modLink.target = '_blank'; + modLink.href = '/docs/modules/' + mod.name; + modLink.title = 'View module details'; + modLink.textContent = mod.name; + + var modDesc = document.createElement('span'); + modDesc.className = 'module-desc'; + modDesc.textContent = moduleDocsPreview(mod, 120); + + modEl.innerHTML = '\uD83D\uDD0C '; // 🔌 + modEl.appendChild(modLink); + modEl.appendChild(modDesc); + modulesEl.appendChild(modEl); + } + } else { + modulesEl.className += ' package-no-modules'; + modulesEl.textContent = 'This package does not add any modules to the JSON config structure. Either it is another kind of plugin (such as a config adapter) or this listing is in error.'; + } + dataEl.appendChild(modulesEl); + pkgEl.appendChild(dataEl); + + if (preselected.includes(pkg.path)) { + pkgEl.classList.add('selected'); + } + + container.appendChild(pkgEl); + } + + updatePage(); + } + + renderWhenReady(); +}).catch(function(err) { + document.addEventListener('DOMContentLoaded', function() { + document.getElementById('optional-packages').innerHTML = + '

Failed to load packages. The build server may be unavailable.

'; + }); +}); + +document.addEventListener('DOMContentLoaded', function() { + // auto-detect platform + var detected = detectPlatform(); + var platformEl = document.getElementById('platform'); + if (platformEl) { + platformEl.value = detected[0] + '-' + detected[1]; + } + updatePage(); + + var downloadButtonHtml = document.getElementById('download').innerHTML; + + // filter + document.getElementById('filter').addEventListener('input', function() { + var q = this.value.trim().toLowerCase(); + var count = 0; + document.querySelectorAll('.package').forEach(function(el) { + if (!q) { el.style.display = ''; return; } + var corpus = el.textContent.toLowerCase(); + if (corpus.indexOf(q) === -1) { + el.style.display = 'none'; + } else { + el.style.display = ''; + count++; + } + }); + this.classList.toggle('found', q && count > 0); + this.classList.toggle('not-found', q && count === 0); + if (!q) { this.classList.remove('found', 'not-found'); } + }); + + // platform change + document.getElementById('platform').addEventListener('change', updatePage); + + // package selection + document.getElementById('optional-packages').addEventListener('click', function(e) { + var pkg = e.target.closest('.package'); + if (!pkg) return; + // don't toggle if clicking a link or input + if (e.target.closest('a') || e.target.closest('input')) return; + pkg.classList.toggle('selected'); + updatePage(); + + // update URL + var newUrl = new URL(window.location.href); + var currentSelected = newUrl.searchParams.getAll('package'); + newUrl.searchParams.delete('package'); + var pkgPath = pkg.querySelector('.package-link').textContent.trim(); + if (pkg.classList.contains('selected')) { + if (!currentSelected.includes(pkgPath)) { + currentSelected.push(pkgPath); + } + } else { + var pos = currentSelected.indexOf(pkgPath); + if (pos >= 0) currentSelected.splice(pos, 1); + } + currentSelected.forEach(function(s) { newUrl.searchParams.append('package', s); }); + history.replaceState({}, document.title, newUrl.toString()); + }); + + // download button + document.getElementById('download').addEventListener('click', function(e) { + e.preventDefault(); + var btn = document.getElementById('download'); + if (btn.classList.contains('disabled')) return; + + btn.classList.add('disabled'); + btn.innerHTML = '
Starting build...'; + + // disable fields + document.querySelectorAll('.download-bar select, #optional-packages input').forEach(function(el) { + el.disabled = true; + }); + + var qs = getBuildParams(); + + fetch('/api/build?' + qs.toString(), { method: 'POST' }) + .then(function(r) { return r.json(); }) + .then(function(json) { + if (json.error) { + alert(json.error.message || 'Build request failed'); + enableFields(btn, downloadButtonHtml); + return; + } + var result = json.result; + if (result.status === 'complete') { + // already cached -- go straight to download + window.location.href = '/api/build/' + result.key + '/download'; + enableFields(btn, downloadButtonHtml); + return; + } + // navigate to build progress page + window.location.href = '/download-beta/build/?key=' + result.key; + }) + .catch(function(err) { + alert('Failed to start build: ' + err.message); + enableFields(btn, downloadButtonHtml); + }); + }); + + function enableFields(btn, originalHtml) { + btn.classList.remove('disabled'); + btn.innerHTML = originalHtml; + document.querySelectorAll('.download-bar select, #optional-packages input').forEach(function(el) { + el.disabled = false; + }); + } +}); + +function updatePage() { + var count = document.querySelectorAll('.package.selected').length; + var el = document.getElementById('package-count'); + if (el) el.textContent = count; + + // show/hide darwin warning + var platformVal = document.getElementById('platform').value || ''; + var darwinWarn = document.getElementById('darwin-warning'); + if (darwinWarn) darwinWarn.style.display = platformVal.indexOf('darwin') === 0 ? '' : 'none'; +} From 31c7c7b53c7418fa1a3494ccefcf9b96f7b2809f Mon Sep 17 00:00:00 2001 From: a Date: Tue, 7 Jul 2026 23:09:49 -0500 Subject: [PATCH 2/4] Handle reset event on build page for worker retries When the build server retries on a different worker (503 from a draining node), the SSE stream sends a 'reset' event. The frontend clears the build log, resets the progress bar, and shows a message that the build is retrying on another server. --- src/resources/js/download-beta-build.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/resources/js/download-beta-build.js b/src/resources/js/download-beta-build.js index 866d50e9..afa505fe 100644 --- a/src/resources/js/download-beta-build.js +++ b/src/resources/js/download-beta-build.js @@ -63,6 +63,16 @@ document.addEventListener('DOMContentLoaded', function() { } catch(err) {} }); + evtSource.addEventListener('reset', function(e) { + // server is retrying the build on another worker -- + // clear the UI so we show fresh progress + logEl.textContent = ''; + document.getElementById('current-step').textContent = 'Retrying build...'; + document.getElementById('progress-fill').style.width = '0%'; + document.getElementById('build-title').textContent = 'Building Caddy...'; + document.getElementById('build-subtitle').textContent = 'Build worker was restarted, retrying on another server.'; + }); + evtSource.addEventListener('result', function(e) { evtSource.close(); try { From e0267c01ae0a90afc0f6b9a4cb89f4e5be44dc7c Mon Sep 17 00:00:00 2001 From: a Date: Wed, 8 Jul 2026 17:13:58 -0500 Subject: [PATCH 3/4] Add PGO profile selection and upload to download page The download-beta page now has a collapsible PGO Optimization section: - None (default): no PGO, same as before - Default: selects a pre-configured server-side profile - Upload: lets users upload their own .pprof file When a named profile is selected, it's sent as a ?pgo= query param. When a custom profile is uploaded, it's base64-encoded and sent in the POST body. A badge shows 'enabled' when PGO is active. --- src/download-beta/index.html | 25 +++++++++++ src/resources/css/download-beta.css | 40 ++++++++++++++++++ src/resources/js/download-beta.js | 65 ++++++++++++++++++++++++++++- 3 files changed, 129 insertions(+), 1 deletion(-) diff --git a/src/download-beta/index.html b/src/download-beta/index.html index 839b3530..241cf233 100644 --- a/src/download-beta/index.html +++ b/src/download-beta/index.html @@ -69,6 +69,31 @@ +
+
+ PGO Optimization +
+

+ Profile-Guided Optimization uses runtime profiling data to produce a faster binary. + Select a pre-configured profile or upload your own .pprof file. +

+
+ + + +
+ +
+
+
+
diff --git a/src/resources/css/download-beta.css b/src/resources/css/download-beta.css index c3dd024c..4bdfe138 100644 --- a/src/resources/css/download-beta.css +++ b/src/resources/css/download-beta.css @@ -1,5 +1,45 @@ /* Download Beta - additions on top of /old/resources/css/download.css */ +/* PGO section */ + +.pgo-section { + margin-top: 16px; + background: rgba(255, 255, 255, .6); + border-radius: 4px; + padding: 0 16px; +} + +.pgo-section summary { + cursor: pointer; + padding: 12px 0; + font-size: 16px; +} + +.pgo-badge { + font-size: 11px; + background: rgb(25, 97, 192); + color: #fff; + padding: 2px 8px; + border-radius: 10px; + vertical-align: middle; + margin-left: 6px; +} + +.pgo-options { + padding-bottom: 16px; +} + +.pgo-controls { + display: flex; + flex-direction: column; + gap: 8px; +} + +.pgo-controls label { + cursor: pointer; + font-size: 15px; +} + /* Build progress page */ #build-page { diff --git a/src/resources/js/download-beta.js b/src/resources/js/download-beta.js index 235bc955..9b361e03 100644 --- a/src/resources/js/download-beta.js +++ b/src/resources/js/download-beta.js @@ -50,6 +50,9 @@ function splitVCSProvider(pkgPath) { return { provider: '', path: pkgPath }; } +// stored PGO file data (base64) when user uploads a custom profile +var pgoFileData = null; + function getBuildParams() { var platformStr = document.getElementById('platform').value || 'linux-amd64'; var parts = platformStr.split('-'); @@ -68,9 +71,24 @@ function getBuildParams() { qs.append('p', path); }); + // named PGO profile + var pgoRadio = document.querySelector('input[name=pgo]:checked'); + if (pgoRadio && pgoRadio.value && pgoRadio.value !== 'upload') { + qs.set('pgo', pgoRadio.value); + } + return qs; } +// returns the JSON body for the POST request if PGO upload is selected +function getBuildBody() { + var pgoRadio = document.querySelector('input[name=pgo]:checked'); + if (pgoRadio && pgoRadio.value === 'upload' && pgoFileData) { + return JSON.stringify({ pgo_profile_data: pgoFileData }); + } + return null; +} + // Load packages fetch('/api/packages').then(function(r) { return r.json(); }).then(function(json) { var packageList = json.result || []; @@ -258,8 +276,14 @@ document.addEventListener('DOMContentLoaded', function() { }); var qs = getBuildParams(); + var body = getBuildBody(); + var fetchOpts = { method: 'POST' }; + if (body) { + fetchOpts.body = body; + fetchOpts.headers = { 'Content-Type': 'application/json' }; + } - fetch('/api/build?' + qs.toString(), { method: 'POST' }) + fetch('/api/build?' + qs.toString(), fetchOpts) .then(function(r) { return r.json(); }) .then(function(json) { if (json.error) { @@ -283,6 +307,45 @@ document.addEventListener('DOMContentLoaded', function() { }); }); + // PGO radio buttons + document.querySelectorAll('input[name=pgo]').forEach(function(radio) { + radio.addEventListener('change', function() { + var badge = document.getElementById('pgo-badge'); + var fileInput = document.getElementById('pgo-file'); + var fileName = document.getElementById('pgo-file-name'); + + if (this.value === 'upload') { + fileInput.style.display = ''; + fileInput.click(); + } else { + fileInput.style.display = 'none'; + fileName.style.display = 'none'; + } + + badge.style.display = this.value ? '' : 'none'; + }); + }); + + // PGO file upload + document.getElementById('pgo-file').addEventListener('change', function() { + var file = this.files[0]; + var fileName = document.getElementById('pgo-file-name'); + if (!file) { + pgoFileData = null; + fileName.style.display = 'none'; + return; + } + fileName.style.display = ''; + fileName.textContent = 'Selected: ' + file.name + ' (' + Math.round(file.size / 1024) + ' KB)'; + + var reader = new FileReader(); + reader.onload = function() { + // result is a data URL like "data:...;base64,XXXX" + pgoFileData = reader.result.split(',')[1]; + }; + reader.readAsDataURL(file); + }); + function enableFields(btn, originalHtml) { btn.classList.remove('disabled'); btn.innerHTML = originalHtml; From 4faa593cde222dc086c601cf121a203d553e5fbf Mon Sep 17 00:00:00 2001 From: a Date: Wed, 8 Jul 2026 17:15:41 -0500 Subject: [PATCH 4/4] Revert "Add PGO profile selection and upload to download page" This reverts commit e0267c01ae0a90afc0f6b9a4cb89f4e5be44dc7c. --- src/download-beta/index.html | 25 ----------- src/resources/css/download-beta.css | 40 ------------------ src/resources/js/download-beta.js | 65 +---------------------------- 3 files changed, 1 insertion(+), 129 deletions(-) diff --git a/src/download-beta/index.html b/src/download-beta/index.html index 241cf233..839b3530 100644 --- a/src/download-beta/index.html +++ b/src/download-beta/index.html @@ -69,31 +69,6 @@
-
-
- PGO Optimization -
-

- Profile-Guided Optimization uses runtime profiling data to produce a faster binary. - Select a pre-configured profile or upload your own .pprof file. -

-
- - - -
- -
-
-
-
diff --git a/src/resources/css/download-beta.css b/src/resources/css/download-beta.css index 4bdfe138..c3dd024c 100644 --- a/src/resources/css/download-beta.css +++ b/src/resources/css/download-beta.css @@ -1,45 +1,5 @@ /* Download Beta - additions on top of /old/resources/css/download.css */ -/* PGO section */ - -.pgo-section { - margin-top: 16px; - background: rgba(255, 255, 255, .6); - border-radius: 4px; - padding: 0 16px; -} - -.pgo-section summary { - cursor: pointer; - padding: 12px 0; - font-size: 16px; -} - -.pgo-badge { - font-size: 11px; - background: rgb(25, 97, 192); - color: #fff; - padding: 2px 8px; - border-radius: 10px; - vertical-align: middle; - margin-left: 6px; -} - -.pgo-options { - padding-bottom: 16px; -} - -.pgo-controls { - display: flex; - flex-direction: column; - gap: 8px; -} - -.pgo-controls label { - cursor: pointer; - font-size: 15px; -} - /* Build progress page */ #build-page { diff --git a/src/resources/js/download-beta.js b/src/resources/js/download-beta.js index 9b361e03..235bc955 100644 --- a/src/resources/js/download-beta.js +++ b/src/resources/js/download-beta.js @@ -50,9 +50,6 @@ function splitVCSProvider(pkgPath) { return { provider: '', path: pkgPath }; } -// stored PGO file data (base64) when user uploads a custom profile -var pgoFileData = null; - function getBuildParams() { var platformStr = document.getElementById('platform').value || 'linux-amd64'; var parts = platformStr.split('-'); @@ -71,24 +68,9 @@ function getBuildParams() { qs.append('p', path); }); - // named PGO profile - var pgoRadio = document.querySelector('input[name=pgo]:checked'); - if (pgoRadio && pgoRadio.value && pgoRadio.value !== 'upload') { - qs.set('pgo', pgoRadio.value); - } - return qs; } -// returns the JSON body for the POST request if PGO upload is selected -function getBuildBody() { - var pgoRadio = document.querySelector('input[name=pgo]:checked'); - if (pgoRadio && pgoRadio.value === 'upload' && pgoFileData) { - return JSON.stringify({ pgo_profile_data: pgoFileData }); - } - return null; -} - // Load packages fetch('/api/packages').then(function(r) { return r.json(); }).then(function(json) { var packageList = json.result || []; @@ -276,14 +258,8 @@ document.addEventListener('DOMContentLoaded', function() { }); var qs = getBuildParams(); - var body = getBuildBody(); - var fetchOpts = { method: 'POST' }; - if (body) { - fetchOpts.body = body; - fetchOpts.headers = { 'Content-Type': 'application/json' }; - } - fetch('/api/build?' + qs.toString(), fetchOpts) + fetch('/api/build?' + qs.toString(), { method: 'POST' }) .then(function(r) { return r.json(); }) .then(function(json) { if (json.error) { @@ -307,45 +283,6 @@ document.addEventListener('DOMContentLoaded', function() { }); }); - // PGO radio buttons - document.querySelectorAll('input[name=pgo]').forEach(function(radio) { - radio.addEventListener('change', function() { - var badge = document.getElementById('pgo-badge'); - var fileInput = document.getElementById('pgo-file'); - var fileName = document.getElementById('pgo-file-name'); - - if (this.value === 'upload') { - fileInput.style.display = ''; - fileInput.click(); - } else { - fileInput.style.display = 'none'; - fileName.style.display = 'none'; - } - - badge.style.display = this.value ? '' : 'none'; - }); - }); - - // PGO file upload - document.getElementById('pgo-file').addEventListener('change', function() { - var file = this.files[0]; - var fileName = document.getElementById('pgo-file-name'); - if (!file) { - pgoFileData = null; - fileName.style.display = 'none'; - return; - } - fileName.style.display = ''; - fileName.textContent = 'Selected: ' + file.name + ' (' + Math.round(file.size / 1024) + ' KB)'; - - var reader = new FileReader(); - reader.onload = function() { - // result is a data URL like "data:...;base64,XXXX" - pgoFileData = reader.result.split(',')[1]; - }; - reader.readAsDataURL(file); - }); - function enableFields(btn, originalHtml) { btn.classList.remove('disabled'); btn.innerHTML = originalHtml;