build(deps): bump phonenumbers from 9.0.36 to 9.0.37 #291
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: "Build Executable" | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: {} | |
| release: | |
| types: [created] | |
| jobs: | |
| build: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: windows-latest | |
| artifact: kuckuck_windows | |
| binary: kuckuck_windows.exe | |
| - os: macos-latest | |
| artifact: kuckuck_macos_arm64 | |
| binary: kuckuck_macos_arm64 | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Set up uv | |
| uses: astral-sh/setup-uv@v10.0.1 | |
| with: | |
| python-version: "3.14" | |
| # Single-binary release (~ 300 MB). Bundles the CLI entry point | |
| # (src/kuckuck/__main__.py), the FastMCP server (invoked as | |
| # ``kuckuck mcp serve``), and the full NER stack (gliner + CPU-only | |
| # torch + transformers) so the downloaded executable supports the CLI, | |
| # the install-claude-hook flow, and the MCP-stdio server in one go. | |
| # | |
| # CPU-only torch is critical: a default install pulls ~3 GB of | |
| # CUDA / triton / nvidia libraries that we never use at runtime. The | |
| # +cpu wheels from pytorch.org are ~250 MB and produce a ~300 MB binary. | |
| # Installed with `uv pip` (not `uv sync`) so this preinstalled CPU | |
| # wheel is what satisfies gliner's torch requirement, instead of | |
| # whatever uv.lock resolved. | |
| # | |
| # Model weights themselves are NOT bundled - they live in | |
| # ~/.cache/kuckuck/models after 'kuckuck fetch-model'. Bundling them | |
| # would push the binary past 1 GB without giving users a way to pick a | |
| # different model. | |
| - name: Install build dependencies | |
| shell: bash | |
| run: | | |
| uv venv | |
| uv pip install -e ".[cli,mcp]" --group build_executable | |
| uv pip install --index-url https://download.pytorch.org/whl/cpu torch | |
| uv pip install 'gliner>=0.2.20' 'huggingface-hub>=0.20' 'onnxruntime>=1.18' | |
| - name: Build Executable | |
| shell: bash | |
| run: | | |
| uv run --no-sync pyinstaller --onefile --name ${{ matrix.artifact }} \ | |
| --collect-data kuckuck \ | |
| --collect-submodules kuckuck_mcp \ | |
| --collect-all fastmcp \ | |
| --collect-all mcp \ | |
| --collect-all gliner \ | |
| --collect-all huggingface_hub \ | |
| --collect-submodules transformers \ | |
| --collect-data transformers \ | |
| --collect-all tokenizers \ | |
| --collect-data torch \ | |
| --collect-binaries torch \ | |
| --collect-all sentencepiece \ | |
| --collect-all safetensors \ | |
| --copy-metadata torch \ | |
| --copy-metadata gliner \ | |
| --copy-metadata transformers \ | |
| --copy-metadata huggingface_hub \ | |
| --copy-metadata tokenizers \ | |
| --exclude-module nvidia \ | |
| --exclude-module triton \ | |
| --exclude-module cuda \ | |
| --exclude-module tensorflow \ | |
| --exclude-module jax \ | |
| src/kuckuck/__main__.py | |
| # macOS Apple Silicon refuses to execute unsigned Mach-O binaries (amfi | |
| # kills them with SIGKILL regardless of Gatekeeper settings). Ad-hoc | |
| # signing ("codesign -s -") is free and sufficient for local use and | |
| # for binaries distributed via GitHub releases after the user clears | |
| # the quarantine xattr: | |
| # xattr -c kuckuck_macos_arm64 | |
| - name: Codesign (macOS) | |
| if: matrix.os == 'macos-latest' | |
| run: codesign --force --deep --sign - dist/${{ matrix.binary }} | |
| - name: Freeze build dependencies | |
| run: uv pip freeze > dist/build-dependencies-${{ matrix.artifact }}.txt | |
| shell: bash | |
| - name: Upload Executable as Artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: ${{ matrix.artifact }} | |
| path: | | |
| dist/${{ matrix.binary }} | |
| dist/build-dependencies-${{ matrix.artifact }}.txt | |
| # Cache the GLiNER model snapshot once across the matrix so the NER smoke | |
| # test does not re-download 1.1 GB on every run. Subsequent matrix entries | |
| # restore from this cache via the actions/cache restore step. | |
| fetch_ner_model: | |
| runs-on: ubuntu-latest | |
| name: "Fetch GLiNER model (cached)" | |
| steps: | |
| - name: Restore model cache | |
| id: cache | |
| uses: actions/cache@v6 | |
| with: | |
| path: ~/.cache/kuckuck/models | |
| key: gliner-multi-v2.1 | |
| - name: Set up uv | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| uses: astral-sh/setup-uv@v10.0.1 | |
| with: | |
| python-version: "3.14" | |
| - name: Download model | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| run: | | |
| uv venv | |
| uv pip install huggingface-hub | |
| uv run --no-sync python -c "from huggingface_hub import snapshot_download; \ | |
| snapshot_download(repo_id='urchade/gliner_multi-v2.1', \ | |
| local_dir='${HOME}/.cache/kuckuck/models/gliner_multi-v2.1')" | |
| smoke_test: | |
| # fetch_ner_model is in the needs list so the NER smoke test always runs | |
| # against a populated model cache. Before the single-binary collapse a | |
| # missing cache silently skipped the NER leg - fine back then because a | |
| # separate slim variant was the ultimate safety net, but with one fat | |
| # binary as the only artifact there is no slimmer fallback to catch a | |
| # NER regression. | |
| needs: [build, fetch_ner_model] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: windows-latest | |
| artifact: kuckuck_windows | |
| binary: kuckuck_windows.exe | |
| - os: macos-latest | |
| artifact: kuckuck_macos_arm64 | |
| binary: kuckuck_macos_arm64 | |
| runs-on: ${{ matrix.os }} | |
| name: "Smoke Test (${{ matrix.artifact }})" | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Set up Python | |
| uses: actions/setup-python@v7 | |
| with: | |
| python-version: "3.14" | |
| - name: Download Executable | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: ${{ matrix.artifact }} | |
| path: dist | |
| # actions/upload-artifact zips contents and the zip format does not | |
| # reliably preserve Unix mode bits on download — restore +x. | |
| - name: Make binary executable (macOS) | |
| if: matrix.os == 'macos-latest' | |
| run: chmod +x dist/${{ matrix.binary }} | |
| shell: bash | |
| - name: Restore GLiNER model cache | |
| uses: actions/cache@v6 | |
| with: | |
| path: ~/.cache/kuckuck/models | |
| key: gliner-multi-v2.1 | |
| - name: Smoke Test | |
| run: python unittests/smoke_test_exe.py dist/${{ matrix.binary }} | |
| - name: NER Smoke Test | |
| run: python unittests/smoke_test_exe_ner.py dist/${{ matrix.binary }} | |
| shell: bash | |
| release: | |
| needs: [build, smoke_test] | |
| if: github.event_name == 'release' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Download Windows Executable | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: kuckuck_windows | |
| path: dist/windows | |
| continue-on-error: true | |
| - name: Download macOS Executable | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: kuckuck_macos_arm64 | |
| path: dist/macos | |
| continue-on-error: true | |
| - name: Rename Executables with version | |
| run: | | |
| set -eu | |
| mkdir -p dist/release | |
| if [ -f ./dist/windows/kuckuck_windows.exe ]; then | |
| mv ./dist/windows/kuckuck_windows.exe \ | |
| ./dist/release/kuckuck_windows_${{ github.ref_name }}.exe | |
| else | |
| echo "::warning::Windows artifact missing; skipping" | |
| fi | |
| if [ -f ./dist/macos/kuckuck_macos_arm64 ]; then | |
| mv ./dist/macos/kuckuck_macos_arm64 \ | |
| ./dist/release/kuckuck_macos_arm64_${{ github.ref_name }} | |
| else | |
| echo "::warning::macOS arm64 artifact missing; skipping" | |
| fi | |
| ls -la dist/release/ | |
| - name: Upload Executable to Release | |
| uses: softprops/action-gh-release@v3 | |
| with: | |
| files: | | |
| ./dist/release/kuckuck_windows_${{ github.ref_name }}.exe | |
| ./dist/release/kuckuck_macos_arm64_${{ github.ref_name }} | |
| fail_on_unmatched_files: false |