Skip to content

Build LarkSync (Windows) #4

Build LarkSync (Windows)

Build LarkSync (Windows) #4

Workflow file for this run

# ─────────────────────────────────────────────────────────────────────
# GitHub Actions — Build LarkSync for Windows
# Runs on a free Windows VM provided by GitHub.
# Triggers: manual (workflow_dispatch) or push to 'windows' branch.
# Output: LarkSync-Windows.zip artifact (downloadable from Actions tab)
# ─────────────────────────────────────────────────────────────────────
name: Build LarkSync (Windows)
on:
workflow_dispatch: # Manual trigger from GitHub UI
push:
branches: [windows]
paths-ignore:
- '*.md'
- 'docs/**'
jobs:
build-windows:
runs-on: windows-latest
steps:
# ── 1. Checkout source code ──────────────────────────────────
- name: Checkout repository
uses: actions/checkout@v4
# ── 2. Set up Python ─────────────────────────────────────────
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
# ── 3. Install dependencies ──────────────────────────────────
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements_windows.txt
# ── 4. Convert PNG icon to ICO (if needed) ───────────────────
- name: Prepare icon
run: |
pip install Pillow
python -c "
from PIL import Image
import os
png_path = 'assets/icon_1024.png'
ico_path = 'assets/icon.ico'
if os.path.exists(png_path) and not os.path.exists(ico_path):
img = Image.open(png_path)
sizes = [(16,16),(32,32),(48,48),(64,64),(128,128),(256,256)]
img.save(ico_path, format='ICO', sizes=sizes)
print(f'Created {ico_path}')
elif os.path.exists(ico_path):
print(f'{ico_path} already exists')
else:
print('No icon source found, building without icon')
"
# ── 5. Build with PyInstaller ────────────────────────────────
- name: Build executable
run: |
python -c "
import PyInstaller.__main__
import os
icon_arg = []
if os.path.exists('assets/icon.ico'):
icon_arg = ['--icon=assets/icon.ico']
PyInstaller.__main__.run([
'main.py',
'--name=LarkSync',
'--windowed',
*icon_arg,
'--add-data=assets;assets',
'--hidden-import=PyQt6',
'--hidden-import=PyQt6.QtCore',
'--hidden-import=PyQt6.QtGui',
'--hidden-import=PyQt6.QtWidgets',
'--hidden-import=google.oauth2',
'--hidden-import=google.auth',
'--hidden-import=google.auth.transport.requests',
'--hidden-import=googleapiclient.discovery',
'--hidden-import=googleapiclient.http',
'--hidden-import=google_auth_oauthlib.flow',
'--hidden-import=requests',
'--hidden-import=app',
'--hidden-import=app.config_manager',
'--hidden-import=app.setup_wizard',
'--hidden-import=app.tray_app',
'--hidden-import=app.settings_dialog',
'--hidden-import=app.log_viewer',
'--hidden-import=app.sync_thread',
'--hidden-import=app.win_menu',
'--hidden-import=sync',
'--hidden-import=sync.lark_auth',
'--hidden-import=sync.lark_client',
'--hidden-import=sync.google_client',
'--hidden-import=sync.sync_engine',
'--hidden-import=sync.lark_notifier',
'--collect-submodules=app',
'--collect-submodules=sync',
'--clean',
'-y',
])
"
# ── 6. Package output ────────────────────────────────────────
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: LarkSync-Windows
path: dist/LarkSync/
retention-days: 30
compression-level: 9