Skip to content

Commit ab3cf4a

Browse files
authored
Merge pull request #4999 from willmmiles/0_15_x-fix-4929
0.15 version of OTA validation
2 parents c756a12 + 14ffde4 commit ab3cf4a

File tree

14 files changed

+708
-76
lines changed

14 files changed

+708
-76
lines changed

pio-scripts/set_metadata.py

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
Import('env')
2+
import subprocess
3+
import json
4+
import re
5+
6+
def get_github_repo():
7+
"""Extract GitHub repository name from git remote URL.
8+
9+
Uses the remote that the current branch tracks, falling back to 'origin'.
10+
This handles cases where repositories have multiple remotes or where the
11+
main remote is not named 'origin'.
12+
13+
Returns:
14+
str: Repository name in 'owner/repo' format for GitHub repos,
15+
'unknown' for non-GitHub repos, missing git CLI, or any errors.
16+
"""
17+
try:
18+
remote_name = 'origin' # Default fallback
19+
20+
# Try to get the remote for the current branch
21+
try:
22+
# Get current branch name
23+
branch_result = subprocess.run(['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
24+
capture_output=True, text=True, check=True)
25+
current_branch = branch_result.stdout.strip()
26+
27+
# Get the remote for the current branch
28+
remote_result = subprocess.run(['git', 'config', f'branch.{current_branch}.remote'],
29+
capture_output=True, text=True, check=True)
30+
tracked_remote = remote_result.stdout.strip()
31+
32+
# Use the tracked remote if we found one
33+
if tracked_remote:
34+
remote_name = tracked_remote
35+
except subprocess.CalledProcessError:
36+
# If branch config lookup fails, continue with 'origin' as fallback
37+
pass
38+
39+
# Get the remote URL for the determined remote
40+
result = subprocess.run(['git', 'remote', 'get-url', remote_name],
41+
capture_output=True, text=True, check=True)
42+
remote_url = result.stdout.strip()
43+
44+
# Check if it's a GitHub URL
45+
if 'github.com' not in remote_url.lower():
46+
return None
47+
48+
# Parse GitHub URL patterns:
49+
# https://github.com/owner/repo.git
50+
# [email protected]:owner/repo.git
51+
# https://github.com/owner/repo
52+
53+
# Remove .git suffix if present
54+
if remote_url.endswith('.git'):
55+
remote_url = remote_url[:-4]
56+
57+
# Handle HTTPS URLs
58+
https_match = re.search(r'github\.com/([^/]+/[^/]+)', remote_url, re.IGNORECASE)
59+
if https_match:
60+
return https_match.group(1)
61+
62+
# Handle SSH URLs
63+
ssh_match = re.search(r'github\.com:([^/]+/[^/]+)', remote_url, re.IGNORECASE)
64+
if ssh_match:
65+
return ssh_match.group(1)
66+
67+
return None
68+
69+
except FileNotFoundError:
70+
# Git CLI is not installed or not in PATH
71+
return None
72+
except subprocess.CalledProcessError:
73+
# Git command failed (e.g., not a git repo, no remote, etc.)
74+
return None
75+
except Exception:
76+
# Any other unexpected error
77+
return None
78+
79+
PACKAGE_FILE = "package.json"
80+
81+
def get_version():
82+
try:
83+
with open(PACKAGE_FILE, "r") as package:
84+
return json.load(package)["version"]
85+
except (FileNotFoundError, KeyError, json.JSONDecodeError):
86+
return None
87+
88+
89+
def has_def(cppdefs, name):
90+
""" Returns true if a given name is set in a CPPDEFINES collection """
91+
for f in cppdefs:
92+
if isinstance(f, tuple):
93+
f = f[0]
94+
if f == name:
95+
return True
96+
return False
97+
98+
99+
def add_wled_metadata_flags(env, node):
100+
cdefs = env["CPPDEFINES"].copy()
101+
102+
if not has_def(cdefs, "WLED_REPO"):
103+
repo = get_github_repo()
104+
if repo:
105+
cdefs.append(("WLED_REPO", f"\\\"{repo}\\\""))
106+
107+
if not has_def(cdefs, "WLED_VERSION"):
108+
version = get_version()
109+
if version:
110+
cdefs.append(("WLED_VERSION", version))
111+
112+
# This transforms the node in to a Builder; it cannot be modified again
113+
return env.Object(
114+
node,
115+
CPPDEFINES=cdefs
116+
)
117+
118+
env.AddBuildMiddleware(
119+
add_wled_metadata_flags,
120+
"*/wled_metadata.cpp"
121+
)

pio-scripts/set_version.py

Lines changed: 0 additions & 8 deletions
This file was deleted.

platformio.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ ldscript_4m1m = eagle.flash.4m1m.ld
110110

111111
[scripts_defaults]
112112
extra_scripts =
113-
pre:pio-scripts/set_version.py
113+
pre:pio-scripts/set_metadata.py
114114
post:pio-scripts/output_bins.py
115115
post:pio-scripts/strip-floats.py
116116
pre:pio-scripts/user_config_copy.py

tools/cdata.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -370,12 +370,6 @@ const char PAGE_dmxmap[] PROGMEM = R"=====()=====";
370370
name: "PAGE_update",
371371
method: "gzip",
372372
filter: "html-minify",
373-
mangle: (str) =>
374-
str
375-
.replace(
376-
/function GetV().*\<\/script\>/gms,
377-
"</script><script src=\"/settings/s.js?p=9\"></script>"
378-
)
379373
},
380374
{
381375
file: "welcome.htm",

wled00/data/update.htm

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,26 @@
66
<script>
77
function B() { window.history.back(); }
88
function U() { document.getElementById("uf").style.display="none";document.getElementById("msg").style.display="block"; }
9-
function GetV() {/*injected values here*/}
9+
function GetV() {
10+
// Fetch device info via JSON API instead of compiling it in
11+
fetch('/json/info')
12+
.then(response => response.json())
13+
.then(data => {
14+
document.querySelector('.installed-version').textContent = `${data.brand} ${data.ver} (${data.vid})`;
15+
document.querySelector('.release-name').textContent = data.release;
16+
// TODO - assemble update URL
17+
// TODO - can this be done at build time?
18+
if (data.arch == "esp8266") {
19+
toggle('rev');
20+
}
21+
})
22+
.catch(error => {
23+
console.log('Could not fetch device info:', error);
24+
// Fallback to compiled-in value if API call fails
25+
document.querySelector('.installed-version').textContent = 'Unknown';
26+
document.querySelector('.release-name').textContent = 'Unknown';
27+
});
28+
}
1029
</script>
1130
<style>
1231
@import url("style.css");
@@ -16,11 +35,15 @@
1635
<body onload="GetV()">
1736
<h2>WLED Software Update</h2>
1837
<form method='POST' action='./update' id='uf' enctype='multipart/form-data' onsubmit="U()">
19-
Installed version: <span class="sip">WLED ##VERSION##</span><br>
38+
Installed version: <span class="sip installed-version">Loading...</span><br>
39+
Release: <span class="sip release-name">Loading...</span><br>
2040
Download the latest binary:&nbsp;<a href="https://github.com/Aircoookie/WLED/releases" target="_blank"
2141
style="vertical-align: text-bottom; display: inline-flex;">
2242
<img src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"></a><br>
43+
<input type="hidden" name="skipValidation" value="" id="sV">
2344
<input type='file' name='update' required><br> <!--should have accept='.bin', but it prevents file upload from android app-->
45+
<input type='checkbox' onchange="sV.value=checked?1:''" id="skipValidation">
46+
<label for='skipValidation'>Ignore firmware validation</label><br>
2447
<button type="submit">Update!</button><br>
2548
<button type="button" onclick="B()">Back</button>
2649
</form>

wled00/e131.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ void prepareArtnetPollReply(ArtPollReply *reply) {
416416

417417
reply->reply_port = ARTNET_DEFAULT_PORT;
418418

419-
char * numberEnd = versionString;
419+
char * numberEnd = (char*) versionString; // strtol promises not to try to edit this.
420420
reply->reply_version_h = (uint8_t)strtol(numberEnd, &numberEnd, 10);
421421
numberEnd++;
422422
reply->reply_version_l = (uint8_t)strtol(numberEnd, &numberEnd, 10);

0 commit comments

Comments
 (0)