Studio: keep chat in place when composer attachments resize it (#6070) #1452
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
| # SPDX-License-Identifier: AGPL-3.0-only | |
| # Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. | |
| # Mac counterpart to studio-update-smoke.yml. Verifies that on a real | |
| # Apple Silicon (macos-14, M1) runner: | |
| # | |
| # 1. install.sh --local --no-torch installs Studio AND auto-fetches | |
| # the prebuilt llama.cpp Mac binary (llama-bNNNN-bin-macos-arm64 | |
| # from ggml-org/llama.cpp). Hitting the source-build fallback is | |
| # treated as an Unsloth bug -- Studio must always pick the | |
| # prebuilt on Mac. | |
| # 2. unsloth studio update --local is idempotent. Two consecutive | |
| # runs both report "prebuilt up to date and validated", no | |
| # source-build fallback. | |
| # 3. The installed Studio still boots and /api/health returns | |
| # healthy after the update path. | |
| name: Mac Studio Update CI | |
| on: | |
| pull_request: | |
| paths: | |
| - 'install.sh' | |
| - 'scripts/uninstall.sh' | |
| - 'studio/setup.sh' | |
| - 'studio/install_python_stack.py' | |
| - 'studio/install_llama_prebuilt.py' | |
| - 'studio/backend/requirements/**' | |
| - 'unsloth_cli/commands/studio.py' | |
| - 'pyproject.toml' | |
| - '.github/workflows/studio-mac-update-smoke.yml' | |
| push: | |
| branches: [main, pip] | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| update-idempotency: | |
| name: Studio Updating Tests | |
| runs-on: macos-14 | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: '22' | |
| - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 | |
| with: | |
| python-version: '3.12' | |
| cache: 'pip' | |
| - name: Install Studio (--local, --no-torch) | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| mkdir -p logs | |
| set -o pipefail | |
| bash install.sh --local --no-torch 2>&1 | tee logs/install.log | |
| - name: Assert llama.cpp loads on this macOS | |
| run: bash .github/scripts/assert-llama-loads.sh | |
| - name: First update should be a no-op (prebuilt already validated) | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -o pipefail | |
| unsloth studio update --local 2>&1 | tee logs/update.log | |
| if grep -q "falling back to source build" logs/update.log; then | |
| echo "::error::studio update fell back to source-build llama.cpp on Mac." | |
| grep -E "llama-prebuilt|llama.cpp" logs/update.log | tail -60 | |
| exit 1 | |
| fi | |
| if ! grep -qE "prebuilt up to date and validated|prebuilt installed and validated" logs/update.log; then | |
| echo "::error::no prebuilt up-to-date marker in update.log." | |
| grep -E "llama-prebuilt|llama.cpp" logs/update.log | tail -60 | |
| exit 1 | |
| fi | |
| echo "update path took the prebuilt fast path" | |
| - name: Second update must also be a no-op | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -o pipefail | |
| unsloth studio update --local 2>&1 | tee logs/update2.log | |
| grep -q "falling back to source build" logs/update2.log && { | |
| echo "::error::second update fell back to source build on Mac" | |
| tail -60 logs/update2.log; exit 1; } || true | |
| grep -qE "prebuilt up to date and validated|prebuilt installed and validated" logs/update2.log | |
| echo "second update was clean" | |
| - name: Boot Studio briefly to confirm the install is still usable | |
| run: | | |
| mkdir -p logs | |
| UNSLOTH_API_ONLY=1 unsloth studio -H 127.0.0.1 -p 18891 \ | |
| > logs/studio.log 2>&1 & | |
| PID=$! | |
| HEALTHY="" | |
| for i in $(seq 1 60); do | |
| if curl -fs http://127.0.0.1:18891/api/health > /tmp/health.json; then | |
| if python3 -c "import json,sys; d=json.load(open('/tmp/health.json')); sys.exit(0 if d.get('status')=='healthy' else 1)"; then | |
| HEALTHY=1 | |
| break | |
| fi | |
| fi | |
| sleep 1 | |
| done | |
| if [ -z "$HEALTHY" ]; then | |
| echo "Studio failed to come up after \`update\`" | |
| tail -200 logs/studio.log | |
| kill "$PID" 2>/dev/null || true | |
| exit 1 | |
| fi | |
| kill "$PID" 2>/dev/null || true | |
| echo "post-update Studio /api/health OK" | |
| - name: Uninstall and verify clean | |
| # Round-trip through scripts/uninstall.sh on real macOS. As a side | |
| # effect this exercises the macOS-only .app bundle + Launch Services | |
| # removal path (~/Applications/Unsloth Studio.app, lsregister -u) | |
| # which is not testable from a Linux runner. Skips gracefully if | |
| # scripts/uninstall.sh has not landed yet (lets this workflow merge | |
| # before #5497). | |
| run: | | |
| set -o pipefail | |
| if [ ! -f scripts/uninstall.sh ]; then | |
| echo "scripts/uninstall.sh not present in this tree; skipping round-trip" | |
| : > logs/uninstall.log | |
| exit 0 | |
| fi | |
| sh scripts/uninstall.sh 2>&1 | tee logs/uninstall.log | |
| leak=0 | |
| for p in \ | |
| "$HOME/.unsloth/studio" \ | |
| "$HOME/.local/share/unsloth" \ | |
| "$HOME/Applications/Unsloth Studio.app" \ | |
| "$HOME/Desktop/Unsloth Studio.app" \ | |
| "$HOME/.local/bin/unsloth"; do | |
| if [ -e "$p" ] || [ -L "$p" ]; then | |
| echo "::error::leak: $p" | |
| leak=$((leak + 1)) | |
| fi | |
| done | |
| [ "$leak" -eq 0 ] || exit 1 | |
| sh scripts/uninstall.sh 2>&1 | tail -5 | |
| sh scripts/uninstall.sh 2>&1 | tail -5 | |
| echo "PASS: mac install -> update -> uninstall round-trip clean" | |
| - name: Upload update logs | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: mac-studio-update-log | |
| path: | | |
| logs/install.log | |
| logs/update.log | |
| logs/update2.log | |
| logs/studio.log | |
| logs/uninstall.log | |
| retention-days: 7 |