Skip to content

feat: Add PyInstaller packaging and CI/CD build workflow#1019

Open
WEIFENG2333 wants to merge 2 commits intomasterfrom
feat/pyinstaller-build
Open

feat: Add PyInstaller packaging and CI/CD build workflow#1019
WEIFENG2333 wants to merge 2 commits intomasterfrom
feat/pyinstaller-build

Conversation

@WEIFENG2333
Copy link
Owner

@WEIFENG2333 WEIFENG2333 commented Feb 26, 2026

Summary

  • Add PyInstaller packaging configuration (VideoCaptioner.spec) that bundles all resource files (fonts, assets, translations, prompts, subtitle styles)
  • Add scripts/build.py as a single entry point for building the application
  • Update app/config.py and main.py to support PyInstaller frozen mode, keeping bundled resources accessible via sys._MEIPASS and user data in the executable directory
  • Add GitHub Actions CI workflow (.github/workflows/build.yml) for automated Windows + macOS builds with smoke tests and artifact uploads

Test plan

  • Local Linux build succeeds with all resources bundled
  • CI Windows build succeeds and smoke test passes
  • CI macOS build succeeds and smoke test passes
  • Downloaded artifacts can launch the application

🤖 Generated with Claude Code


Note

Medium Risk
Changes runtime path resolution and writable resource locations for PyInstaller frozen mode, which can break resource loading or user data storage across platforms. Adds new build automation that downloads binaries and produces distributable artifacts.

Overview
Adds PyInstaller packaging via VideoCaptioner.spec and a new scripts/build.py entrypoint (including Windows downloads for ffmpeg/7z, copying writable resources into dist, and basic bundle verification).

Updates app/config.py and main.py to handle PyInstaller frozen mode by resolving bundled resources from sys._MEIPASS, relocating writable directories (AppData, work-dir, resource/bin, resource/subtitle_style) next to the executable, and setting the Qt plugin path appropriately.

Introduces a GitHub Actions workflow (.github/workflows/build.yml) to build on Windows/macOS, run simple smoke tests, and upload dist/VideoCaptioner/ artifacts; also ignores /build and /dist outputs in .gitignore.

Written by Cursor Bugbot for commit 48f86b0. This will update automatically on new commits. Configure here.

- Add VideoCaptioner.spec for PyInstaller configuration with all resource
  files (fonts, assets, translations, prompts, subtitle styles)
- Add scripts/build.py as the single entry point for building
- Update app/config.py to support PyInstaller frozen mode (sys._MEIPASS
  for bundled resources, exe directory for user data)
- Update main.py Qt plugin path handling for frozen mode
- Add .github/workflows/build.yml for Windows + macOS CI builds with
  smoke tests and artifact uploads
- Update .gitignore to exclude build/dist directories

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
@claude
Copy link

claude bot commented Feb 26, 2026

Claude encountered an error —— View job


I'll analyze this and get back to you.

- build.py: Auto-download ffmpeg and 7z.exe to resource/bin/ on Windows
- build.py: Copy writable resources (bin/, subtitle_style/) to dist output
- config.py: BIN_PATH and SUBTITLE_STYLE_PATH now point to _EXE_DIR
  (writable) instead of _MEIPASS (read-only) in frozen mode
- config.py: First-run copytree for preset subtitle styles from _MEIPASS
- build.yml: Add bin verification step for Windows

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
@claude
Copy link

claude bot commented Feb 26, 2026

Claude encountered an error —— View job


I'll analyze this and get back to you.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

for m in missing:
print(f" - {m}")
else:
print("All expected resources found in bundle.")
Copy link

Choose a reason for hiding this comment

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

Verify function silently passes with missing critical resources

Medium Severity

The verify() function only prints a WARNING when critical bundled resources (like logo.png, fonts, translations) are missing from the build output, but does not exit with a non-zero code. Since verify() is called at the end of every build.py run (including CI), a build with missing resources will pass CI, get uploaded as an artifact, and crash at runtime when those resources are accessed.

Fix in Cursor Fix in Web


# Windows binary download URLs
FFMPEG_URL = "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-win64-gpl.zip"
SEVENZIP_URL = "https://7-zip.org/a/7zr.exe"
Copy link

Choose a reason for hiding this comment

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

Wrong 7-Zip variant downloaded and renamed misleadingly

Low Severity

SEVENZIP_URL points to 7zr.exe, a reduced standalone 7-Zip variant that only supports .7z archives. This binary is saved as 7z.exe, which normally refers to the full 7-Zip command-line tool supporting dozens of archive formats. While the current codebase only extracts .7z files, the renamed binary silently lacks support for other formats that 7z.exe is expected to handle.

Additional Locations (1)

Fix in Cursor Fix in Web

data = tomllib.load(f)
deps = data['project']['dependencies']
subprocess.check_call([sys.executable, '-m', 'pip', 'install'] + deps)
"
Copy link

Choose a reason for hiding this comment

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

CI ignores platform-specific PyQt5-Qt5 version pin on Windows

Medium Severity

The CI installs dependencies via pip by reading pyproject.toml's [project] dependencies, but the project's [tool.uv] override-dependencies deliberately pins PyQt5-Qt5==5.15.2 on Windows. Since pip doesn't understand uv overrides, the Windows CI build installs the latest PyQt5-Qt5 (currently 5.15.16) instead of the explicitly required 5.15.2. This means the Windows artifact bundles a different Qt binary version than what developers test with, potentially causing runtime issues.

Fix in Cursor Fix in Web

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