Skip to content

Use device-reported repository for upgrades#2078

Open
LordMike wants to merge 8 commits into
frenck:mainfrom
LordMike:codex/use-device-repo-upgrade
Open

Use device-reported repository for upgrades#2078
LordMike wants to merge 8 commits into
frenck:mainfrom
LordMike:codex/use-device-repo-upgrade

Conversation

@LordMike
Copy link
Copy Markdown

@LordMike LordMike commented May 21, 2026

Proposed Changes

Adds support for using the repository reported by a WLED device's /json info response when downloading firmware during WLED.upgrade().

The upgrade API still accepts an explicit repo override. If no repo is passed, it uses device.info.repo, which defaults to wled/WLED for firmware that does not report a repository.

Validation performed:

  • pytest --cov wled tests
  • ruff check .
  • ruff format --check .
  • ty check examples src tests

This code was authored by OpenAI Codex.

Related Issues

Related to #2049

Thanks to @netmindz for the original implementation and discussion that shaped this change.

Summary by CodeRabbit

  • New Features

    • Firmware upgrades can use a custom GitHub repository or automatically use the repository reported by the connected device; missing/blank values fall back to the built-in default.
    • Device info now exposes a repository field to users.
  • Tests

    • Added tests and updated snapshots to verify repository selection during upgrades (device-reported, explicit override, and fallback cases).
  • Documentation

    • Added README section explaining release asset naming, repo selection, and usage examples.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds device-reported firmware repository support: Info gains repo defaulting to DEFAULT_REPO; WLED.upgrade accepts optional repo and falls back to device.info.repo (stripped) or DEFAULT_REPO. Tests, snapshots, and README updated.

Changes

Firmware Repository Configuration

Layer / File(s) Summary
Info model repo field
src/wled/models.py
Info dataclass adds repo: str field with DEFAULT_REPO default and documentation describing GitHub owner/repository format.
WLED.upgrade repo parameter
src/wled/wled.py
Method signature changed to repo: str | None = None; implementation derives the repo from self._device.info.repo when caller omits it, strips whitespace, and falls back to DEFAULT_REPO.
Info repo deserialization tests and snapshots
tests/test_models.py, tests/__snapshots__/test_models.ambr
Tests verify Info.from_dict defaults to DEFAULT_REPO when repo is absent and preserves provided repo; snapshots updated to include repo='wled/WLED' across multiple fixtures and versions.
Upgrade repo selection tests
tests/test_wled.py
Parametrized tests assert firmware download URL selection based on device info.repo, explicit repo argument, and handling of blank/whitespace info.repo.
README firmware upgrade docs
README.md
Add section documenting firmware upgrade release asset selection, required filename convention, examples, and new [wled-releases] link reference.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

bugfix

Suggested reviewers

  • frenck

Poem

🐰 A tiny hare with whiskers bright,

I nudged Info to set repo right,
Upgrades now find the proper well,
Fetch, upload, and ring the bell,
Hoppity hops — firmware done tonight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately reflects the primary change: adding support for using the device-reported repository field when performing firmware upgrades, with a fallback to the default repository.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@LordMike LordMike marked this pull request as ready for review May 21, 2026 21:17
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/wled/wled.py`:
- Around line 686-687: The current fallback only checks for None when assigning
repo from self._device.info.repo, which allows empty or whitespace strings to be
used and later produces invalid GitHub URLs; update the assignment logic in the
code path that sets repo (the repo variable and usage of self._device.info.repo)
to normalize/trim the device-provided value and treat any falsy or blank (e.g.,
"", whitespace-only) value as missing, falling back to DEFAULT_REPO instead;
ensure you explicitly strip whitespace from self._device.info.repo before
testing and then assign DEFAULT_REPO when the stripped value is empty.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 91682953-0cb0-4e27-be48-2b1800e1c759

📥 Commits

Reviewing files that changed from the base of the PR and between fa80d52 and 5a7318e.

📒 Files selected for processing (5)
  • src/wled/models.py
  • src/wled/wled.py
  • tests/__snapshots__/test_models.ambr
  • tests/test_models.py
  • tests/test_wled.py

Comment thread src/wled/wled.py Outdated
@mik-laj
Copy link
Copy Markdown
Collaborator

mik-laj commented May 21, 2026

Hey. I think we should put together some documentation that describes how the release file is created and how you can start distributing new releases to your own devices, because we're really the only ones providing the automatic update mechanism, so we're the ones setting the standard. For now, this is just a guess based on how files were created in WLED/WLED, but it was never explicitly written as a rule, so another person would have to reverse engineer our code and release structure in the WLED/WLED repo to be able to create a new repository with custom releases.

For example, I'm wondering if GLEDOPTO releases its files correctly? If not, how should they do it? Is there documentation anywhere that describes this?

@LordMike
Copy link
Copy Markdown
Author

While working on this, I found out what the scheme is, and it seems really sensible (although it is at present 100% dependent on Github specifically). Its built in two parts: a utility to detect a latest release (which already supports a supplied repo), and then an upgrader (which we're fixing) which will, given a version and a device, find the relevant release file.

WLEDReleases is a utility to fetch releases from github, for the repo in question. It will scan for releases and find the latest release, the latest prerelease and so on.

Independently. WLED.upgrade() will given a device (which it operates on), will build a url from the information that looks like this:

https://github.com/{repo}/releases/download/v{version}/{update_file}

The update_file is build like this: {device.info.brand}_{version}_{device.info.release}.bin[.gz]

The release and brand from the device info are embedded into the built binaries at compile time.

I'm sure you knew this, but this is the consolidated info that is really needed to build docs.

@mik-laj
Copy link
Copy Markdown
Collaborator

mik-laj commented May 22, 2026

Sound good to me. Can you add that information to README or other docs file? I would like to have documentation that I can send to someone if they want to provide automatic updates.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.52%. Comparing base (3e87d76) to head (83fc42c).
⚠️ Report is 615 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff             @@
##             main    #2078       +/-   ##
===========================================
+ Coverage   58.61%   97.52%   +38.91%     
===========================================
  Files           6        8        +2     
  Lines         662     1133      +471     
  Branches      143      113       -30     
===========================================
+ Hits          388     1105      +717     
+ Misses        270       18      -252     
- Partials        4       10        +6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mik-laj mik-laj added enhancement Enhancement of the code, not introducing new features. new-feature New features or options. and removed enhancement Enhancement of the code, not introducing new features. labels May 22, 2026
@LordMike
Copy link
Copy Markdown
Author

@mik-laj I gave it a shot. I used the projects Readme.md to host it - if it should go elsewhere, let me know.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 70-84: Update the firmware asset naming docs to reflect the full
upgrade contract: replace the pattern literal "WLED_{version}_{release}.bin"
with a generic "{brand}_{version}_{release}.bin[.gz]" and update the explanatory
text to state that "brand" and "release" come from device.info.brand and
device.info.release while "version" is the release tag without the leading "v";
also adjust the example sentence to include device.info.brand (e.g.,
`brand="WLED"`) so the example URL and explanation match the new pattern.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a337a0ff-efa4-41f7-be7c-8e55e46e1fa8

📥 Commits

Reviewing files that changed from the base of the PR and between 9396328 and 3384f38.

📒 Files selected for processing (1)
  • README.md

Comment thread README.md
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_wled.py`:
- Around line 1270-1271: The test case labeled "missing_device_repo" is
incorrectly using a whitespace string like the "blank_device_repo" case; update
the pytest.param for id "missing_device_repo" to simulate a truly missing repo
(e.g., pass None or omit the repo key) instead of " " so the info.repo fallback
path is exercised—change the first argument in that pytest.param (currently " ")
to None (or adjust the input dict to not include repo) while keeping
DEFAULT_REPO and the test id intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b1ea74b4-1111-4a9d-8501-4c6201beb746

📥 Commits

Reviewing files that changed from the base of the PR and between 700cba1 and ba38a0e.

📒 Files selected for processing (1)
  • tests/test_wled.py

Comment thread tests/test_wled.py Outdated
Comment thread tests/test_wled.py
Comment thread README.md Outdated
LordMike and others added 2 commits May 23, 2026 19:06
Co-authored-by: Kamil Breguła <mik-laj@users.noreply.github.com>
@LordMike
Copy link
Copy Markdown
Author

@mik-laj that seems like all of it - besides the CI job failing due to auth, right?

@mik-laj
Copy link
Copy Markdown
Collaborator

mik-laj commented May 24, 2026

@LordMike The code and documentation look good now, but I'll want to test it in practice. Do you have any favorite repositories that follow our convention? How did you test if this code works?

@LordMike
Copy link
Copy Markdown
Author

LordMike commented May 24, 2026

I did it on my own repo: https://github.com/LordMike/WLED/releases

I'm still waiting on this repo and the HA integration to fully see it in action end to end - but at least for my repo, the correct url is produced. I have not tested actually calling upgrade on my device through this, because I know that part works once the file has been downloaded. So just arriving at the correct url was enough for me.

I basically just ran the WLED's CI workflows, slightly manipulated. Goal being being able to at some point just retarget.. Then I found this work already in progress, so I jumped the bandwagon :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new-feature New features or options.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants