-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Automatically download the right bin for the latest release and install #5561
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
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 |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| <script> | ||
| function B() { window.history.back(); } | ||
| var cnfr = false; | ||
| var deviceInfo = null; | ||
| function cR() { | ||
| if (!cnfr) { | ||
| var bt = gId('rev'); | ||
|
|
@@ -22,15 +23,30 @@ | |
| fetch(getURL('/json/info')) | ||
| .then(response => response.json()) | ||
| .then(data => { | ||
| deviceInfo = data; | ||
| document.querySelector('.installed-version').textContent = `${data.brand} ${data.ver} (${data.vid})`; | ||
| const repoUrl = data.repo && data.repo !== "unknown" ? "https://github.com/" + data.repo + "/releases/latest" : null; | ||
| document.querySelector('.release-name').textContent = data.release; | ||
| // assemble update URL and update release badge | ||
| if (data.repo && data.repo !== "unknown") { | ||
| const repoUrl = "https://github.com/" + data.repo + "/releases/latest"; | ||
| if (repoUrl) { | ||
| const badgeUrl = "https://img.shields.io/github/release/" + data.repo + ".svg?style=flat-square"; | ||
| document.querySelector('.release-repo').href = repoUrl; | ||
| document.querySelector('.release-badge').src = badgeUrl; | ||
| toggle('release-download'); // only show release download item after receiving a valid data.repo | ||
| // fetch latest release from GitHub to build direct bin download link | ||
| fetch(`https://api.github.com/repos/${data.repo}/releases/latest`) | ||
| .then(r => r.json()) | ||
| .then(gh => { | ||
| const ver = gh.tag_name.replace(/^v/, ''); | ||
| const suffix = `_${ver}_${data.release}.bin`; | ||
| const asset = gh.assets.find(a => a.name.endsWith(suffix)); | ||
| if (asset) { | ||
| const binUrl = asset.browser_download_url.replace(/^https?:\/\/[^/]+/, 'https://download.wled.me'); | ||
| const el = document.querySelector('.release-name'); | ||
| el.innerHTML = `<a href="${binUrl}">${data.release}</a>`; | ||
| } | ||
| }) | ||
| .catch(() => {}); // silently ignore if GitHub API unavailable | ||
| } else { | ||
| gId('Norelease-download').classList.add("hide"); // repo invalid -> hide everything | ||
| } | ||
|
|
@@ -60,6 +76,48 @@ | |
| gId('bootupd').classList.add("hide"); | ||
| toggle('upd'); | ||
| } | ||
| async function autoUpdate() { | ||
| const btn = gId('autoUpdBtn'); | ||
| const status = gId('autoUpdStatus'); | ||
| btn.disabled = true; | ||
| status.textContent = ''; | ||
| try { | ||
| const info = deviceInfo; | ||
| if (!info || !info.repo || info.repo === 'unknown') { | ||
| status.textContent = 'No release repository available for this build.'; | ||
| btn.disabled = false; | ||
| return; | ||
| } | ||
| status.textContent = 'Checking GitHub for latest release...'; | ||
| const ghResp = await fetch(`https://api.github.com/repos/${info.repo}/releases/latest`); | ||
| if (!ghResp.ok) throw new Error(`GitHub API error: ${ghResp.status}`); | ||
| const ghRelease = await ghResp.json(); | ||
| const releaseVer = ghRelease.tag_name.replace(/^v/, ''); | ||
| const assetSuffix = `_${releaseVer}_${info.release}.bin`; | ||
| const asset = ghRelease.assets.find(a => a.name.endsWith(assetSuffix)); | ||
| if (!asset) { | ||
| const available = ghRelease.assets.map(a => a.name).join(', '); | ||
| status.textContent = `Firmware not found (*${assetSuffix}). Available: ${available}`; | ||
| btn.disabled = false; | ||
| return; | ||
| } | ||
| status.textContent = `Downloading ${asset.name} (${Math.round(asset.size/1024)} KB)...`; | ||
| const fwUrl = asset.browser_download_url.replace(/^https?:\/\/[^/]+/, 'https://download.wled.me'); | ||
| const fwResp = await fetch(fwUrl); | ||
| if (!fwResp.ok) throw new Error(`Download failed: ${fwResp.status}`); | ||
|
Comment on lines
+105
to
+107
Contributor
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. Unconditional URL rewrite breaks auto-update for non-official repos At Line 91, replacing every release asset host with Proposed fix- const fwUrl = asset.browser_download_url.replace(/^https?:\/\/[^/]+/, 'https://download.wled.me');
- const fwResp = await fetch(fwUrl);
- if (!fwResp.ok) throw new Error(`Download failed: ${fwResp.status}`);
+ const githubUrl = asset.browser_download_url;
+ const useMirror = (info.repo || '').toLowerCase() === 'wled/wled';
+ const fwUrl = useMirror
+ ? githubUrl.replace(/^https?:\/\/[^/]+/, 'https://download.wled.me')
+ : githubUrl;
+ let fwResp = await fetch(fwUrl);
+ if (!fwResp.ok && useMirror) fwResp = await fetch(githubUrl); // mirror fallback
+ if (!fwResp.ok) throw new Error(`Download failed: ${fwResp.status}`);🤖 Prompt for AI Agents |
||
| const blob = await fwResp.blob(); | ||
| const file = new File([blob], asset.name, {type: 'application/octet-stream'}); | ||
| const dt = new DataTransfer(); | ||
| dt.items.add(file); | ||
| document.querySelector('input[name="update"]').files = dt.files; | ||
| status.textContent = `Downloaded ${asset.name}. Uploading to device...`; | ||
| hideforms(); | ||
| gId('upd').submit(); | ||
| } catch(e) { | ||
| status.textContent = 'Auto-update failed: ' + e.message; | ||
| btn.disabled = false; | ||
| } | ||
| } | ||
| </script> | ||
| <style> | ||
| @import url("style.css"); | ||
|
|
@@ -77,18 +135,22 @@ <h2>WLED Software Update</h2> | |
| <p> | ||
| Installed version: <span class="sip installed-version">Loading...</span><br> | ||
| Release: <span class="sip release-name">Loading...</span><br> | ||
| <span id="Norelease-download">Latest binary: Checking...<br></span> | ||
| <span id="Norelease-download">Latest release: Checking...<br></span> | ||
| <span id="release-download" class="hide"> | ||
| Download the latest binary: <a class="release-repo" href="https://github.com/wled/WLED/releases/latest" target="_blank" rel="noopener noreferrer" | ||
| Latest version: <a class="release-repo" href="https://github.com/wled/WLED/releases/latest" target="_blank" rel="noopener noreferrer" | ||
| style="vertical-align: text-bottom; display: inline-flex;"> | ||
| <img class="release-badge" alt="badge"></a><br> <!-- start with an empty placeholder, src will be filled after fetching /json/info --> | ||
| <img class="release-badge" alt="View latest"></a><br> | ||
| <button type="button" id="autoUpdBtn" onclick="autoUpdate()">Auto update</button> | ||
| <span id="autoUpdStatus" style="display:block;margin-top:4px;font-size:13px;"></span> | ||
| </span> | ||
| </p> | ||
| <hr class="sml"> | ||
| <h3>Manual upload</h3> | ||
| <input type="hidden" name="skipValidation" value="" id="sV"> | ||
| <input type='file' name='update' required><br> <!--should have accept='.bin', but it prevents file upload from android app--> | ||
| <input type='checkbox' onchange="sV.value=checked?1:''" id="skipValidation"> | ||
| <label for='skipValidation'>Ignore firmware validation</label><br> | ||
| <button type="submit">Update WLED!</button><br> | ||
| <button type="submit">Upload</button><br> | ||
| <span id="rev"> | ||
| <hr class="sml"> | ||
| <button type="button" onclick="cR()">Revert update</button><br> | ||
|
|
@@ -107,4 +169,4 @@ <h2>Bootloader Update</h2> | |
| <div id="Noupd" class="hide sec"><b>Updating...</b><br>Please do not close or refresh the page :)</div> | ||
| <p><button id="backbtn" type="button" onclick="B()">Back</button></p> | ||
| </body> | ||
| </html> | ||
| </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.
Hide the “Checking…” placeholder in the successful path.
After a valid repo is detected, Line 35 reveals
#release-downloadbut#Norelease-downloadremains visible, so stale status text can stay on screen.Proposed fix
Also applies to: 138-139
🤖 Prompt for AI Agents