Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
Binary file removed .DS_Store
Binary file not shown.
Binary file removed .coverage
Binary file not shown.
138 changes: 138 additions & 0 deletions .github/actions/build-desktop/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
name: Build desktop
description: Fetch Couchbase Lite C, build Python bindings, PyInstaller, package unsigned artifacts.

inputs:
os:
description: "macos or windows"
required: true
version:
description: "Version string used in artifact filenames (e.g. 4.0.0-beta)"
required: true

runs:
using: composite
steps:
- name: Fetch libcblite (macOS)
if: inputs.os == 'macos'
working-directory: ${{ github.workspace }}/app
shell: bash
env:
CBL_VERSION: "3.2.4"
run: |
chmod +x scripts/fetch_libcblite_macos.sh
./scripts/fetch_libcblite_macos.sh
echo "CBL_MACOS_DYLIB=${{ github.workspace }}/app/vendor/macos/libcblite.3.dylib" >> "$GITHUB_ENV"

- name: Fetch libcblite (Windows)
if: inputs.os == 'windows'
working-directory: ${{ github.workspace }}/app
shell: pwsh
env:
CBL_VERSION: "3.2.4"
run: |
powershell -File .\scripts\fetch_libcblite_windows.ps1
"CBL_WINDOWS_DLL=$env:GITHUB_WORKSPACE\app\vendor\windows\cblite.dll" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8

- name: Build Couchbase Lite Python bindings (macOS)
if: inputs.os == 'macos'
shell: bash
run: |
python -m pip install --upgrade pip
python -m pip install cffi setuptools
git clone https://github.com/couchbaselabs/couchbase-lite-python.git "${RUNNER_TEMP}/cbl-py"
git -C "${RUNNER_TEMP}/cbl-py" checkout 2d1c79041de30a26a8b7f632d52a89fc031f1600
# Same recipe as app/Dockerfile: run build.py from CouchbaseLite/.
(
cd "${RUNNER_TEMP}/cbl-py/CouchbaseLite"
python ../build.py \
--include "${{ github.workspace }}/app/vendor/macos/include" \
--library "${{ github.workspace }}/app/vendor/macos/libcblite.3.dylib"
)
echo "PYTHONPATH=${RUNNER_TEMP}/cbl-py${PYTHONPATH:+:${PYTHONPATH}}" >> "$GITHUB_ENV"

- name: Build Couchbase Lite Python bindings (Windows)
if: inputs.os == 'windows'
shell: pwsh
run: |
python -m pip install --upgrade pip
python -m pip install cffi setuptools
$clone = Join-Path $env:RUNNER_TEMP "cbl-py"
git clone https://github.com/couchbaselabs/couchbase-lite-python.git $clone
git -C $clone checkout 2d1c79041de30a26a8b7f632d52a89fc031f1600
$include = Join-Path $env:GITHUB_WORKSPACE "app\vendor\windows\include"
$library = Join-Path $env:GITHUB_WORKSPACE "app\vendor\windows\cblite.lib"
if (-not (Test-Path $library)) {
$library = Join-Path $env:GITHUB_WORKSPACE "app\vendor\windows\cblite.dll"
}
Push-Location (Join-Path $clone "CouchbaseLite")
python ..\build.py --include $include --library $library
Pop-Location
"PYTHONPATH=$clone;$env:PYTHONPATH" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8

- name: Install desktop Python deps
working-directory: ${{ github.workspace }}/app
shell: bash
run: |
python -m pip install -r requirements-desktop.txt

- name: PyInstaller (macOS)
if: inputs.os == 'macos'
working-directory: ${{ github.workspace }}/app
shell: bash
run: |
pyinstaller build_mac.spec --clean --noconfirm
test -d dist/QueryAnalyzer.app

- name: Package UNSIGNED arm64 DMG (macOS)
if: inputs.os == 'macos'
working-directory: ${{ github.workspace }}/app
shell: bash
run: |
ARCH="$(uname -m)"
case "$ARCH" in
arm64) ARCH_LABEL=arm64 ;;
x86_64) ARCH_LABEL=x86_64 ;;
*) ARCH_LABEL="$ARCH" ;;
esac
mkdir -p dist/dmg
cp -R dist/QueryAnalyzer.app dist/dmg/
ln -s /Applications dist/dmg/Applications
cat > dist/dmg/README.txt << 'EOF'
Couchbase Query Analyzer — unsigned beta

This build is NOT code-signed or notarized. Gatekeeper will block the
first launch. After dragging QueryAnalyzer.app into Applications:

xattr -dr com.apple.quarantine /Applications/QueryAnalyzer.app

Then double-click. A Terminal window shows live logs and your browser
opens http://localhost:8080. Use the menubar icon (🔍) → Quit to stop.

This artifact is Apple Silicon (arm64) when built on macos-latest.
Intel Macs need a separate x86_64 build.
EOF
hdiutil create -volname "QueryAnalyzer-Beta" \
-srcfolder dist/dmg \
-ov -format UDZO \
"dist/QueryAnalyzer-${{ inputs.version }}-UNSIGNED-${ARCH_LABEL}.dmg"
echo "DESKTOP_ARTIFACT=app/dist/QueryAnalyzer-${{ inputs.version }}-UNSIGNED-${ARCH_LABEL}.dmg" >> "$GITHUB_ENV"

- name: PyInstaller (Windows, onedir)
if: inputs.os == 'windows'
working-directory: ${{ github.workspace }}/app
shell: pwsh
run: |
pyinstaller build_win.spec --clean --noconfirm
if (-not (Test-Path "dist\QueryAnalyzer\QueryAnalyzer.exe")) {
throw "PyInstaller did not produce dist\QueryAnalyzer\QueryAnalyzer.exe"
}

- name: Package UNSIGNED x64 zip (Windows)
if: inputs.os == 'windows'
working-directory: ${{ github.workspace }}/app
shell: pwsh
run: |
$zip = "dist\QueryAnalyzer-${{ inputs.version }}-UNSIGNED-x64.zip"
if (Test-Path $zip) { Remove-Item $zip -Force }
Compress-Archive -Path "dist\QueryAnalyzer\*" -DestinationPath $zip
"DESKTOP_ARTIFACT=app/dist/QueryAnalyzer-${{ inputs.version }}-UNSIGNED-x64.zip" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
python-version-file: '.python-version'
cache: 'pip'
cache-dependency-path: tests/requirements-dev.txt

Expand Down
164 changes: 14 additions & 150 deletions .github/workflows/liquid-dryrun.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,185 +104,49 @@ jobs:
exit 1

# ==========================================================================
# macOS app — private artifact only
# macOS app — private artifact only (CBL via build-desktop)
# ==========================================================================
build-macos:
name: Build macOS App (Private Artifact)
needs: version
runs-on: macos-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install dependencies
working-directory: ./app
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pyinstaller rumps

- name: Create PyInstaller spec
working-directory: ./app
run: |
cat > QueryAnalyzer.spec << 'SPEC_EOF'
# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(
['app.py'],
pathex=[],
binaries=[],
datas=[
('index.html', '.'),
('assets', 'assets'),
('docs', 'docs'),
('config.json', '.'),
('ai_analyzer.py', '.'),
('ai_models_list.json.template', '.'),
('payload_reference.json.template', '.'),
('tray.py', '.'),
],
hiddenimports=[
'flask', 'flask_cors',
'requests', 'openai', 'icecream', 'webbrowser', 'rumps',
'tray',
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)

pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
pyz, a.scripts, [],
exclude_binaries=True,
name='QueryAnalyzer',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
# console=True so the .app launches a Terminal window with
# live stdout/stderr (startup banner, "Opening browser…",
# tracebacks). Easier debugging for unsigned beta builds.
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)

coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas,
strip=False, upx=True, upx_exclude=[], name='QueryAnalyzer')

app = BUNDLE(
coll,
name='QueryAnalyzer.app',
icon='assets/img/QueryAnalyzer.icns',
bundle_identifier='io.fuj.cb.queryanalyzer',
info_plist={
'CFBundleName': 'CB Query Analyzer (Beta)',
'CFBundleDisplayName': 'CB Query Analyzer (Beta)',
'CFBundleShortVersionString': '4.0.0',
'CFBundleVersion': '4.0.0',
'NSHighResolutionCapable': True,
'LSBackgroundOnly': False,
'LSUIElement': False,
},
)
SPEC_EOF

- name: Build with PyInstaller
working-directory: ./app
run: pyinstaller QueryAnalyzer.spec --clean --noconfirm

- name: Create DMG
working-directory: ./app
run: |
mkdir -p dist/dmg
cp -R dist/QueryAnalyzer.app dist/dmg/
hdiutil create -volname "QueryAnalyzer-Beta" \
-srcfolder dist/dmg \
-ov -format UDZO \
dist/QueryAnalyzer-${{ needs.version.outputs.version }}-macos.dmg

python-version-file: '.python-version'
- uses: ./.github/actions/build-desktop
with:
os: macos
version: ${{ needs.version.outputs.version }}
- name: Upload artifact (private to repo collaborators)
uses: actions/upload-artifact@v4
with:
name: QueryAnalyzer-${{ needs.version.outputs.version }}-macos
path: app/dist/QueryAnalyzer-${{ needs.version.outputs.version }}-macos.dmg
path: app/dist/QueryAnalyzer-${{ needs.version.outputs.version }}-UNSIGNED-arm64.dmg
retention-days: 14

# ==========================================================================
# Windows exe — private artifact only
# Windows onedir zip — private artifact only (CBL via build-desktop)
# ==========================================================================
build-windows:
name: Build Windows Executable (Private Artifact)
needs: version
runs-on: windows-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install dependencies
working-directory: ./app
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
# pystray + Pillow power the system-tray icon (tray.py).
pip install pyinstaller pystray Pillow

- name: Build with PyInstaller
working-directory: ./app
run: |
pyinstaller --name QueryAnalyzer `
--onefile `
--console `
--icon "assets/img/app_icon.ico" `
--add-data "index.html;." `
--add-data "assets;assets" `
--add-data "docs;docs" `
--add-data "config.json;." `
--add-data "ai_analyzer.py;." `
--add-data "ai_models_list.json.template;." `
--add-data "payload_reference.json.template;." `
--add-data "tray.py;." `
--hidden-import flask `
--hidden-import flask_cors `
--hidden-import requests `
--hidden-import openai `
--hidden-import icecream `
--hidden-import webbrowser `
--hidden-import pystray `
--hidden-import PIL `
--hidden-import tray `
app.py

- name: Create ZIP
working-directory: ./app
shell: pwsh
run: |
Compress-Archive -Path "dist\QueryAnalyzer.exe" `
-DestinationPath "dist\QueryAnalyzer-${{ needs.version.outputs.version }}-windows.zip"

python-version-file: '.python-version'
- uses: ./.github/actions/build-desktop
with:
os: windows
version: ${{ needs.version.outputs.version }}
- name: Upload artifact (private to repo collaborators)
uses: actions/upload-artifact@v4
with:
name: QueryAnalyzer-${{ needs.version.outputs.version }}-windows
path: app/dist/QueryAnalyzer-${{ needs.version.outputs.version }}-windows.zip
path: app/dist/QueryAnalyzer-${{ needs.version.outputs.version }}-UNSIGNED-x64.zip
retention-days: 14

# ==========================================================================
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:

- uses: actions/setup-python@v5
with:
python-version: '3.11'
python-version-file: '.python-version'

- name: Install Node dependencies
run: npm ci
Expand Down Expand Up @@ -111,7 +111,7 @@ jobs:

- uses: actions/setup-python@v5
with:
python-version: '3.11'
python-version-file: '.python-version'

- name: Install dependencies
working-directory: ./app
Expand Down
Loading
Loading