Skip to content

fix(plugins): protect modified files on upgrade and surface diff failures - #3969

Open
EmilyRagan wants to merge 5 commits into
mainfrom
fix_modified_plugin_dialog_upgrade
Open

EmilyRagan wants to merge 5 commits into
mainfrom
fix_modified_plugin_dialog_upgrade

Conversation

@EmilyRagan

@EmilyRagan EmilyRagan commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Problems

  1. A failed diff was reported as "no conflicts." PluginModel.modified_diff rescued every error and returned [], and ModifiedPluginDialog.loadDiff also turned any request failure (including a 504) into []. The dialog then said "None of {plugin}'s modified files conflict with the new plugin. Installing will proceed normally.", even though no check had completed.
  2. The upgrade dialog was wrong without Version History. The dialog is shared by Core and Enterprise and tells users that installing replaces modified files and saves the old content to Version History. TargetModel#apply_upgrade_version only runs when the Enterprise VersionStore is present, so in Core the modified copy under targets_modified/ stays in place and keeps overriding the new plugin's file. Nothing is versioned, and the old "delete modified files" option was removed, so Core users had no way to take the plugin's version.
  3. Upgrades could lose modified files in Enterprise without Version History. TargetModel#version_store_available? only checked that the Enterprise VersionStore class loads, not that it is enabled. With OPENC3_VERSION_HISTORY_DIR unset, VersionStore.commit does nothing, but apply_upgrade_version still deleted the modified copy. The user's content was gone with no saved version.

Changes

  • PluginModel.modified_diff no longer swallows errors. The controller already returns them as a 500 with a message.
  • ModifiedPluginDialog shows an inline error when the diff fails. It explains that continuing keeps all modified files, which then override the new plugin. The request sets Ignore-Errors for 5xx so the global banner, which would include the truncated plugin hash, doesn't also appear.
  • PluginsTab passes the existing scriptVersionsEnabled flag (from /openc3-api/info) into the dialog as versionHistory. When it is false (Core, or Enterprise without OPENC3_VERSION_HISTORY_DIR), an upgrade shows the modified-file list and the DELETE MODIFIED checkbox, as it did before Version History, plus a note that kept files override the plugin. version_history_files is not sent in that case.
  • version_store_available? now also requires VersionStore.enabled?. When Version History is disabled, the backend ignores version_history_files and leaves modified copies in place, even if the frontend sends that list.
  • The upgrade section of the Playwright plugins test checks the delete box when it is shown.

Testing

  • openc3/spec/models/plugin_model_spec.rb: 61 examples, 0 failures
  • openc3/spec/models/target_model_spec.rb: 109 examples, 0 failures, including new version_store_available? cases (enabled, disabled, gem absent)
  • openc3-cosmos-cmd-tlm-api/spec/controllers/plugins_controller_spec.rb: 32 examples, 0 failures, including a new 500 case
  • ESLint with --max-warnings 0 on the changed Vue files, and Prettier on the Playwright spec
  • Playwright not run locally

🤖 Generated with Claude Code

EmilyRagan and others added 2 commits September 30, 2026 17:10
Co-Authored-By: Claude <noreply@anthropic.com>
…istory

- Show the delete-modified checkbox on upgrade when Version History is
  disabled, since kept modified files override the new plugin
- Show modified_diff failures in the dialog instead of reporting that
  no modified files conflict
- Check the delete box in the upgrade playwright test when it is shown

Co-Authored-By: Claude <noreply@anthropic.com>
@EmilyRagan
EmilyRagan force-pushed the fix_modified_plugin_dialog_upgrade branch from 708cd01 to 4a16877 Compare September 30, 2026 23:11
@EmilyRagan
EmilyRagan changed the base branch from fix_modified_diff_python_install to main September 30, 2026 23:11
@codecov

codecov Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 22.72727% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.12%. Comparing base (e3a728f) to head (254dd97).

Files with missing lines Patch % Lines
...nc3-vue-common/src/tools/admin/tabs/PluginsTab.vue 0.00% 12 Missing ⚠️
...ue-common/src/tools/admin/ModifiedPluginDialog.vue 37.50% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3969      +/-   ##
==========================================
- Coverage   80.13%   80.12%   -0.02%     
==========================================
  Files         901      901              
  Lines       68370    68374       +4     
  Branches     2699     2650      -49     
==========================================
- Hits        54789    54784       -5     
- Misses      12913    12924      +11     
+ Partials      668      666       -2     
Flag Coverage Δ
frontend 67.00% <15.00%> (+0.01%) ⬆️
python 80.13% <ø> (ø)
ruby-api 82.34% <ø> (-0.25%) ⬇️
ruby-backend 85.67% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@EmilyRagan EmilyRagan self-assigned this Sep 30, 2026
@EmilyRagan EmilyRagan changed the title fix(admin): modified plugin dialog upgrade flow without version history fix(plugins): protect modified files on upgrade and surface diff failures Sep 30, 2026
@EmilyRagan
EmilyRagan marked this pull request as ready for review September 30, 2026 23:19
@sonarqubecloud

Copy link
Copy Markdown

This branch has not been deployed

No deployments
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.

1 participant