Skip to content

Implement check-for-updates and auto-update#1357

Merged
amilcarlucas merged 1 commit intomasterfrom
dmg_autoupdate
Mar 7, 2026
Merged

Implement check-for-updates and auto-update#1357
amilcarlucas merged 1 commit intomasterfrom
dmg_autoupdate

Conversation

@amilcarlucas
Copy link
Collaborator

@amilcarlucas amilcarlucas commented Mar 6, 2026

@OmkarSarkar204 can you take a look at this?

Copilot AI review requested due to automatic review settings March 6, 2026 18:50
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds macOS-native update support by downloading and installing a .dmg when available, while keeping existing Windows installer and Linux/PyPI (pip/uv) paths intact.

Changes:

  • Implemented macOS DMG download/mount/copy/unmount update flow and integrated it into the update manager.
  • Generalized URL and downloaded-file validation helpers for reuse across platforms.
  • Expanded unit tests to cover macOS DMG helpers and the new update-manager macOS branching behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
ardupilot_methodic_configurator/backend_internet.py Adds macOS DMG install pipeline and shared validation helpers used by update flows.
ardupilot_methodic_configurator/data_model_software_updates.py Routes macOS updates to DMG installer when present; otherwise falls back to pip.
tests/unit_backend_internet.py Adds unit tests for new macOS DMG helpers and shared validation utilities.
tests/unit_data_model_software_updates.py Adds tests for macOS update-manager behavior (DMG path, fallback, failures).
ARCHITECTURE_1_software_update.md Documents new macOS DMG update approach and helper functions.

)

# pylint: disable=unused-argument
# pylint: disable=unused-argument, too-many-lines, redefined-outer-nam
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

The pylint directive is misspelled (redefined-outer-nam), so pylint won’t actually disable redefined-outer-name and CI/linting may fail. Rename it to redefined-outer-name.

Suggested change
# pylint: disable=unused-argument, too-many-lines, redefined-outer-nam
# pylint: disable=unused-argument, too-many-lines, redefined-outer-name

Copilot uses AI. Check for mistakes.
Comment on lines +541 to +549
if progress_callback:
progress_callback(0.0, _("Installing {}...").format(app_name))

# Use ditto to preserve metadata, resource forks, and extended attributes
subprocess.check_call(["ditto", app_path, dest]) # noqa: S603, S607

if progress_callback:
progress_callback(100.0, _("Installation complete"))

Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

Progress reporting is duplicated and potentially conflicting: _install_app_from_mount() emits 0.0 and 100.0, and _mount_and_install_dmg() also emits 0.0 and 100.0. This can lead to repeated 0%/100% updates with different messages. Consider centralizing progress reporting in one place (e.g., only in _mount_and_install_dmg()), or use distinct progress ranges per phase (mount/install/unmount) so progress is monotonic and messages aren’t overwritten at the same percentage.

Suggested change
if progress_callback:
progress_callback(0.0, _("Installing {}...").format(app_name))
# Use ditto to preserve metadata, resource forks, and extended attributes
subprocess.check_call(["ditto", app_path, dest]) # noqa: S603, S607
if progress_callback:
progress_callback(100.0, _("Installation complete"))
# Use ditto to preserve metadata, resource forks, and extended attributes
subprocess.check_call(["ditto", app_path, dest]) # noqa: S603, S607

Copilot uses AI. Check for mistakes.
Comment on lines +573 to +574
if progress_callback:
progress_callback(0.0, _("Mounting DMG..."))
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

Progress reporting is duplicated and potentially conflicting: _install_app_from_mount() emits 0.0 and 100.0, and _mount_and_install_dmg() also emits 0.0 and 100.0. This can lead to repeated 0%/100% updates with different messages. Consider centralizing progress reporting in one place (e.g., only in _mount_and_install_dmg()), or use distinct progress ranges per phase (mount/install/unmount) so progress is monotonic and messages aren’t overwritten at the same percentage.

Copilot uses AI. Check for mistakes.
Comment on lines +585 to +588
if result:
if progress_callback:
progress_callback(100.0, _("Installation complete. Please restart the application."))
logging_info(_("macOS DMG installation complete. Please restart the application."))
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

Progress reporting is duplicated and potentially conflicting: _install_app_from_mount() emits 0.0 and 100.0, and _mount_and_install_dmg() also emits 0.0 and 100.0. This can lead to repeated 0%/100% updates with different messages. Consider centralizing progress reporting in one place (e.g., only in _mount_and_install_dmg()), or use distinct progress ranges per phase (mount/install/unmount) so progress is monotonic and messages aren’t overwritten at the same percentage.

Copilot uses AI. Check for mistakes.
Comment on lines 336 to 342
def _validate_github_url(url: str) -> bool:
"""Validate that URL is from a trusted GitHub source."""
# This whitelist is intentionally restrictive for security reasons
if url.startswith("https://github.com/"):
return True
logging_error(_("Windows installer URL must be from github.com: %s"), url)
logging_error(_("Installer URL must be from github.com: %s"), url)
return False
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

Using startswith(\"https://github.com/\") is a brittle URL validation approach (e.g., it won’t handle case normalization, leading/trailing whitespace, or other valid GitHub URL forms consistently). A more robust and security-oriented approach is to parse the URL (e.g., via urllib.parse.urlparse) and strictly validate scheme == \"https\" and hostname == \"github.com\" (optionally also constraining the path prefix to /OWNER/REPO/releases/download/).

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Contributor

github-actions bot commented Mar 6, 2026

☂️ Python Coverage

current status: ✅

Overall Coverage

Lines Covered Coverage Threshold Status
11652 10627 91% 89% 🟢

New Files

No new covered files...

Modified Files

File Coverage Status
ardupilot_methodic_configurator/backend_internet.py 90% 🟢
ardupilot_methodic_configurator/data_model_software_updates.py 100% 🟢
TOTAL 95% 🟢

updated for commit: 29d5a7e by action🐍

@github-actions
Copy link
Contributor

github-actions bot commented Mar 6, 2026

Test Results

    2 files      2 suites   28m 37s ⏱️
3 103 tests 3 098 ✅  5 💤 0 ❌
6 206 runs  6 196 ✅ 10 💤 0 ❌

Results for commit 29d5a7e.

♻️ This comment has been updated with latest results.

@OmkarSarkar204
Copy link
Contributor

@OmkarSarkar204 can you take a look at this?

Sure , do you want me to test something specific locally or should i go ahead and try to fix the errors?

@amilcarlucas
Copy link
Collaborator Author

It would be great if you could test that it works.

@OmkarSarkar204
Copy link
Contributor

@amilcarlucas , I hardcoded my local version to 2.9.10 to trigger the update. The app successfully downloaded the 2.9.13 .dmg, mounted it, and copied the .app over without any issues. Works perfectly!

Screenshot 2026-03-07 at 1 55 16 AM

logs:

2026-03-07 01:52:22,686 - INFO - Running version: 2.9.10 (git hash: acc46af6b3207eb1c6f40c4d363ce1dec1865620)
2026-03-07 01:52:22,686 - INFO - _get_verify_param() return certifi.where /Users/omkarsarkar/Desktop/ArduPilot/Methodic/version-check/methodic-test-clone/.venv/lib/python3.12/site-packages/certifi/cacert.pem
2026-03-07 01:52:28,865 - INFO - Downloading and installing new version for macOS...
2026-03-07 01:52:28,874 - INFO - _get_verify_param() return certifi.where /Users/omkarsarkar/Desktop/ArduPilot/Methodic/version-check/methodic-test-clone/.venv/lib/python3.12/site-packages/certifi/cacert.pem
2026-03-07 01:53:16,487 - INFO - macOS DMG installation complete. Please restart the application.
2026-03-07 01:53:20,509 - INFO - Will now exit the old software version.

@OmkarSarkar204
Copy link
Contributor

Just a small thing I noticed that the link(full changelog etc) inside the update banner is not clickable. I dont know if its behavorial or not, i saw it and just wanted to point it out.

@amilcarlucas
Copy link
Collaborator Author

@OmkarSarkar204 Thanks for testing and for the feedback.

The URLs are not clickable yet. A webbrowser opens in the backgound with the same information. The user can use that if he wants to click on something.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

@amilcarlucas amilcarlucas merged commit ddae051 into master Mar 7, 2026
35 of 38 checks passed
@amilcarlucas amilcarlucas deleted the dmg_autoupdate branch March 7, 2026 15:06
@OmkarSarkar204
Copy link
Contributor

@OmkarSarkar204 Thanks for testing and for the feedback.

The URLs are not clickable yet. A webbrowser opens in the backgound with the same information. The user can use that if he wants to click on something.

Got it. Thanks!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants