Skip to content

Merge dev into main: sync accumulated development work (v0.0.4a) - #4

Merged
TonyXTYan merged 70 commits into
mainfrom
dev
Aug 17, 2026
Merged

Merge dev into main: sync accumulated development work (v0.0.4a)#4
TonyXTYan merged 70 commits into
mainfrom
dev

Conversation

@TonyXTYan

Copy link
Copy Markdown
Owner

Summary

  • Syncs main with dev, which has been the active development branch since the last merge (PR renamed helab and new cicd test pipelines #1, Nov 2024) while main only received two unrelated Dependabot bumps since.
  • Brings setup.py version to 0.0.4a.
  • Most recent commits add CI auto-tagging: .github/workflows/dev-cicd.yml now detects a setup.py version bump, errors loudly if the version decreases, and creates a draft/prerelease GitHub Release (with PyInstaller build artifacts) automatically on main when the version hasn't been tagged yet — no more manual git tag push required. The release job is skipped entirely on non-main pushes to avoid wasting CI time/bandwidth downloading and zipping build artifacts that would just be discarded.

Note on scope

This PR is large (172 files) because it captures ~14 months of accumulated dev work that was never merged back to main, not just the CI change. Squash merge is recommended given the commit history includes many WIP/checkpoint commits.

Test plan

  • CI passes on this PR (test + build jobs across macOS/Windows/Ubuntu)
  • After merge, confirm the release job on main tags v0.0.4a and creates a draft prerelease with all three build artifacts attached
  • dev continues from v0.0.4b (or next version) after this merges

🤖 Generated with Claude Code

TonyXTYan and others added 21 commits January 15, 2025 13:48
… callbacks

The macos py3.12 coverage test step was hanging indefinitely (36+ min,
no timeout). Root cause: HelabFSModelThrottleDataChangedEmit is a
persistent QRunnable that loops on time.sleep() until cancel() is
called; when a test creates a HelabFileSystemModel/FolderExplorer
without it being cleanly closed, the worker is never cancelled and
keeps looping forever. At interpreter shutdown, PyQt's atexit hook
destroys the shared QThreadPool, which calls waitForDone() and blocks
forever waiting on that orphaned worker.

- tests/conftest.py: autouse fixture cancels all tracked workers after
  every test so none survive to process exit.
- Bump pinned GitHub Actions to their latest majors (Node 20 -> 24).
- Add job-level timeout-minutes and pytest-timeout (--timeout, thread
  method) so a genuine hang fails fast with a thread dump instead of
  running until GitHub's default job timeout.
- Guard two more deferred QTimer.singleShot callbacks
  (HelabFileSystemModel.rescan, HelabMainWindow resizeEvent) against
  RuntimeError when the underlying Qt object is deleted before the
  timer fires, following the existing FolderTabWidget fix.
codecov/test-results-action@v1 is deprecated (Codecov's recommended
replacement is codecov-action with report_type: test_results) and was
the last action in CI still triggering the Node 20 deprecation warning.

Also record recent working-convention memories (ask before commit,
preferred address).
Adds a get-version job that reads setup.py's version, fails loudly if
it decreased from the latest tag, and drives release creation on main
when the version hasn't been tagged yet, instead of requiring a
manually pushed tag. Uses GITHUB_TOKEN instead of PAT_TOKEN so the
auto-created tag doesn't re-trigger the workflow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Gate the whole release job on should_release instead of just the
final release-creation steps, so non-main pushes no longer download
and zip ~1.3GB of build artifacts that are immediately discarded.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@codecov-commenter

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment

Thanks for integrating Codecov - We've got you covered ☂️

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2d7614f567

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

should_release: ${{ steps.compare.outputs.should_release }}
steps:
- name: Checkout code
uses: actions/checkout@v7

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore resolvable GitHub Action versions

The workflow upgrades its core dependencies to nonexistent major tags, including actions/checkout@v7, actions/setup-python@v7, actions/upload-artifact@v7, actions/download-artifact@v8, and codecov/codecov-action@v7. Every push therefore fails while resolving the first checkout step, before the documented test matrix, builds, or automatic release logic can run; use published action majors instead.

AGENTS.md reference: AGENTS.md:L85-L87

Useful? React with 👍 / 👎.

Comment thread helab/models/HelabFileSystemModel.py Outdated
Comment on lines +382 to +383
top_left = self.index(min_row, min_col)
bottom_right = self.index(max_row, max_col)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Emit data changes under each index's actual parent

When a completed status belongs to a nested directory, these calls reconstruct top_left and bottom_right with the default root parent rather than the parents of the collected indexes. The resulting dataChanged signal targets unrelated root rows, so the visible nested row can retain its loading or stale status; batches spanning multiple parents must be split and emitted using indexes with the same actual parent.

Useful? React with 👍 / 👎.

Comment thread helab/models/ScriptTreeSelector.py Outdated
Comment on lines +189 to +190
self.tree_widget.setHeaderLabels(["Script", "Run"])
self.tree_widget.setColumnCount(2)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Allocate a column for every displayed script action

The tree declares only two columns, with valid indexes 0 and 1, but _load_current_group() installs a second action button in column 2. Both bundled analysis classes return two actions, so their Plot/Visualize buttons are placed outside the model's column range and are not visible; declare three columns and a corresponding header, or render all actions within the existing action column.

Useful? React with 👍 / 👎.

Comment thread helab/workers/StatusWorker.py Outdated
if self._is_cancelled:
logging.debug(f"StatusWorker canceled for: {self.path}")
# self.signals.finished.emit(StatusReport(self.path, 'canceled', -1, []))
self._finished_emit_helper(StatusReport(self.path, 'canceled', -1, []))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use the registered cancelled status spelling

If a StatusWorker observes a cancellation, it caches the status as canceled, while StatusReport.STATUS_MISTERY and StatusIcons.ICONS_STATUS register only cancelled. Stopping a scan therefore leaves that path with an invalid status and the bug icon until another rescan replaces it; construct the report with cancelled here.

Useful? React with 👍 / 👎.

TonyXTYan and others added 5 commits August 17, 2026 22:14
macOS's default launchd/Finder-launch environment caps open file
descriptors at 256, far below a typical interactive shell's ulimit.
HeLab's directory-scanning worker pools exhaust that quickly, and Qt
hard-aborts when pipe() fails while creating a thread's event
dispatcher. Raise the process's own soft limit toward the hard cap.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
PyInstaller flags onefile mode combined with a macOS .app BUNDLE as
deprecated: a .app can't be a single file, and the self-extracting
onefile executable clashed with macOS's security/signing behavior.
Onedir mode produces a proper native .app directly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…us spelling

- HelabFileSystemModel._bulk_data_changed grouped indexes by directory and
  emitted dataChanged per actual parent instead of the root, so nested rows
  stopped getting stuck on stale/loading status.
- ScriptTreeSelector's tree widget now has 3 columns so a script's second
  action button (e.g. Plot/Visualize) is no longer placed out of range and
  silently dropped.
- StatusWorker now emits 'cancelled' (matching StatusReport.STATUS_MISTERY
  and StatusIcons.ICONS_STATUS) instead of the unregistered 'canceled'.

Addresses Codex review comments on PR #4.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
PyInstaller's BUNDLE step auto-injects LSBackgroundOnly=true into
Info.plist when the EXE is built with console=True, which makes macOS
treat the app as background-only: no Dock icon, no menu bar. HeLab is
a normal GUI app, so it should build windowed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@TonyXTYan
TonyXTYan merged commit 59550a8 into main Aug 17, 2026
24 of 25 checks passed
@TonyXTYan
TonyXTYan deleted the dev branch August 19, 2026 03:00
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