Skip to content

Harden run ZIP import and fix review findings - #451

Open
t0mdavid-m wants to merge 3 commits into
mainfrom
claude/project-thread-h95bl1-run-import
Open

t0mdavid-m wants to merge 3 commits into
mainfrom
claude/project-thread-h95bl1-run-import

Conversation

@t0mdavid-m

@t0mdavid-m t0mdavid-m commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

🤖 Generated with Claude Code

https://claude.ai/code/session_01FkEGengFwqzeVYN7rGGrrZ

Fixes the CodeRabbit findings from the template sync in OpenMS/umetaflow#41 that hold up on template main. They are all in template code, so they reach every app through the next sync.

Run ZIP import (RunManager.import_zip)

  • A run zipped while still running is imported as failed, not finished (its results may be partial).
  • Refused before anything is read or written: more than 100,000 files, a run.json over 1 MB, a params.json over 64 MB.
  • created / finished are kept only when they are ISO timestamp strings. A number there broke list_runs() sorting and format_time().
  • Damaged member data (CRC mismatch, broken deflate) raises RunImportError ("The ZIP is damaged") instead of an uncaught BadZipFile / zlib.error.
  • A run without result files imports: zip() leaves out an empty results/, so a run.json alone now counts as a run.
  • Windows device names (NUL, CON, LPT1, aux.txt, ...) in member paths are refused.
  • The name, including its (n) collision suffix, stays within MAX_NAME_LENGTH.

Run import widgets

  • The message after an import depends on whether the run is shown. A failed or cancelled run gets a warning that it is listed on the Download page only.
  • show_results_section() takes the message too (run_widgets.show_import_notice), so after an import from the results page it no longer waits for the Download page.
  • The uploader names the upload limit (server.maxUploadSize). Streamlit 1.51 has no per-widget max_upload_size, so the limit itself stays a deployment setting.

"All parameters" dialog (StreamlitUI)

  • List values from pyOpenMS (bytes) and from params.json (newline-separated text) become lists of str (_as_str_list), so an unchanged list no longer shows b'a' and selections keep every item.
  • The list editor is chosen from the parameter's type (row["is_list"]), not from the type of its default.

CI and docs

  • build-image.yml: quotes are stripped from the overlay's newName / newTag before docker tag.
  • package.sh: notarizes with the API key only when key, key ID and issuer are all set. Otherwise it uses the Apple ID, or fails and names what is missing.
  • get_branding() docstring: app_icon is for an app's own pages; the template shows it nowhere itself.

Not changed

  • Contrib release in the Windows package cache key (openms.yml): a package built for a commit is a valid build of that commit, as answered on umetaflow#41.
  • Unlocked read-modify-write of params.json in ParameterManager: real, but it needs a locking design across all writers. Better as its own change.

Tests

  • tests/test_run_import.py: new cases for each import change above.
  • tests/test_run_import_widgets.py: the import message (AppTest) and _as_str_list.
  • python -m pytest tests/ test_gui.py: 470 passed. The 5 failures are raw_data_viewer.py, which needs pyopenms-viz's ms_plotly backend; it is missing from the local environment, and the tests fail the same way on main there.

Generated by Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Run imports now reject oversized or unsafe archives and handle damaged files more clearly. Interrupted runs are marked as failed, invalid timestamps are corrected, and imported parameter files are validated.
    • List-valued parameters handle a wider range of input formats consistently.
  • Improvements
    • Import notices now indicate whether an imported run finished and was selected, and are shown only once.
    • Duplicate imported run names are shortened as needed while retaining numbered suffixes.

Run ZIP import (RunManager.import_zip):
- a run zipped while still running is imported as failed, not finished
- refuse more than 100,000 files, a run.json over 1 MB and a params.json
  over 64 MB before anything is read or written
- keep "created"/"finished" only when they are ISO timestamp strings
- damaged member data (CRC, deflate) raises RunImportError instead of
  an uncaught zipfile/zlib error
- accept a run with no result files (zip() leaves out an empty results/)
- refuse Windows device names (NUL, CON, LPT1, ...) in member paths
- the name with its " (n)" suffix stays within MAX_NAME_LENGTH

Run import widgets: the message after an import says whether the run is
shown on the results pages, and the results pages take it too, so it no
longer waits for the Download page. The uploader names the upload limit.

"All parameters" dialog: list values from pyOpenMS (bytes) and from
params.json (newline-separated text) become lists of str, and the list
editor is chosen from the parameter's type, not from its default.

build-image.yml strips YAML quotes from the overlay's newName/newTag.
package.sh notarizes with the API key only when key, key id and issuer
are all set; otherwise it uses the Apple ID, or fails naming what is
missing. The get_branding() docstring says what app_icon is for.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkEGengFwqzeVYN7rGGrrZ
@t0mdavid-m t0mdavid-m self-assigned this Nov 2, 2026
@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 11 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6f3b60a0-2a2b-41a4-becc-fe348fce36a4
Commits

Reviewing files that changed from the base of the PR and between 89b9339 and d57db27.

Files selected for processing: 5
  • .github/workflows/build-and-test.yml
  • src/workflow/RunManager.py
  • src/workflow/StreamlitUI.py
  • tests/test_run_import.py
  • tests/test_run_import_widgets.py
Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 35a8c2d6-80b4-4719-aea2-1c65bd85a78a
Commits

Reviewing files that changed from the base of the PR and between 82bf790 and 89b9339.

Files selected for processing: 9
  • .github/workflows/build-image.yml
  • electron/scripts/package.sh
  • src/common/common.py
  • src/workflow/RunManager.py
  • src/workflow/StreamlitUI.py
  • src/workflow/WorkflowManager.py
  • src/workflow/run_widgets.py
  • tests/test_run_import.py
  • tests/test_run_import_widgets.py

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

This pull request updates ZIP run import validation and workflow notices, normalizes list parameter values, adjusts image retagging and macOS notarization credential checks, and clarifies branding documentation.

Changes: Run ZIP Import

Layer / File(s) Summary
Archive validation and discovery
src/workflow/RunManager.py, tests/test_run_import.py
The importer enforces member-count and metadata-size limits, validates ZIP paths, and accepts archives identified by results/ or run.json. Damaged ZIP and unpacking errors produce distinct import errors. Tests cover archive limits, unsafe paths, discovery cases, and damaged member data.
Imported run metadata and names
src/workflow/RunManager.py, tests/test_run_import.py
The importer validates metadata, timestamps, and parameter objects; maps running to failed; and creates unique names within the length limit. Tests cover statuses, timestamps, and duplicate overlong names.
Import notices and UI integration
src/workflow/run_widgets.py, src/workflow/WorkflowManager.py, tests/test_run_import_widgets.py
The workflow displays a one-time success or warning notice, selects an imported run only when it is finished, and includes the upload-size limit in the uploader caption. Tests cover notice behavior.

List Parameter Handling

Layer / File(s) Summary
Normalize list parameter values
src/workflow/StreamlitUI.py, tests/test_run_import_widgets.py
A shared helper converts list and tuple items to strings and splits scalar values on newlines. The parameter dialog and row widgets use it for list values.

Image Retagging

Layer / File(s) Summary
Parse overlay image values
.github/workflows/build-image.yml
The retagging step strips single and double quotes from the overlay image name and tag before the existing empty-value check.

macOS Notarization

Layer / File(s) Summary
Validate notarization credentials
electron/scripts/package.sh
The API-key path requires key content, key ID, and issuer. When key content is present but a required credential is missing and no Apple ID is configured, the script fails with an error.

Branding Documentation

Layer / File(s) Summary
Clarify icon documentation
src/common/common.py
The app_icon documentation says app pages can use it, the template does not display it, and it is the default for logo_icon.

Possibly related PRs

Suggested reviewers: claude

Change: Bug fix

Merge Risk: Low · previous review 89b93

Some list parameters may appear differently from the values passed to a tool, and certain unreadable ZIPs may show a traceback instead of an import error. These are bounded issues to address or accept before merging.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 54.55% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title names the main change: hardening the run ZIP import in RunManager.import_zip. It also covers the review fixes. The summary and objectives both center on the import hardening, which makes up …
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.
Full details: Title check

Explanation

The title names the main change: hardening the run ZIP import in RunManager.import_zip. It also covers the review fixes. The summary and objectives both center on the import hardening, which makes up most of the changeset. The remaining edits (notarization, image tagging, parameter list handling, docstring) are secondary and not named, which is acceptable for a title.

Full details: Docstring Coverage

Explanation

Docstring coverage is 54.55% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 22 functions across 8 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

A rabbit checks each ZIP with care,
And finds the run metadata there.
List values line up, names stay neat,
The workflow shares a notice sweet.
New tags shed quotes before they meet.

@coderabbitai coderabbitai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

  • Fix comments: Fix CodeRabbit comments on this PR

Comment thread src/workflow/RunManager.py Resolved
Comment thread src/workflow/StreamlitUI.py Resolved
_as_str_list() split away empty entries and turned 0 into an empty
list, so the "All parameters" dialog could show a value as unchanged
while run_topp() passes the extra empty argument. It now splits like
run_topp() does.

import_zip() turns RuntimeError (encrypted members, unsupported
compression, over-nested JSON) into RunImportError.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkEGengFwqzeVYN7rGGrrZ
…st yet

kubectl wait on a pod selector fails at once with "no matching resources
found" when it runs before the controller Deployment has created its
pod, which made test-nginx fail now and then (seen on arm64).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkEGengFwqzeVYN7rGGrrZ

Copy link
Copy Markdown
Member Author

test-nginx (simple, arm64) failed in the ingress setup: kubectl wait --selector=app.kubernetes.io/component=controller ran before the ingress-nginx Deployment had created its pod and failed at once with "no matching resources found". This does not come from this PR's changes. The fix from #450 (608a548: wait with kubectl rollout status deployment/ingress-nginx-controller instead) is now cherry-picked here as d57db27, and the new push runs the ingress jobs again.


Generated by Claude Code

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.

2 participants