Bumps the actions group with 12 updates in the / directory: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `4.2.2` | `7.0.1` | | [actions/setup-python](https://github.com/actions/setup-python) | `6.2.0` | `7.0.0` | | [actions/setup-node](https://github.com/actions/setup-node) | `6.4.0` | `7.0.0` | | [actions/cache/restore](https://github.com/actions/cache) | `5.0.5` | `6.1.0` | | [actions/cache/save](https://github.com/actions/cache) | `5.0.5` | `6.1.0` | | [actions/upload-artifact](https://github.com/actions/upload-artifact) | `4.6.1` | `7.0.1` | | [step-security/harden-runner](https://github.com/step-security/harden-runner) | `2.19.1` | `2.20.0` | | [ossf/scorecard-action](https://github.com/ossf/scorecard-action) | `2.4.1` | `2.4.3` | | [github/codeql-action](https://github.com/github/codeql-action) | `3` | `4` | | [tauri-apps/tauri-action](https://github.com/tauri-apps/tauri-action) | `0.6.2` | `1.0.0` | | [trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog) | `3.95.3` | `3.95.9` | | [actions/stale](https://github.com/actions/stale) | `10.2.0` | `10.4.0` | Updates `actions/checkout` from 4.2.2 to 7.0.1 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.2.2...3d3c42e5aac5ba805825da76410c181273ba90b1) Updates `actions/setup-python` from 6.2.0 to 7.0.0 - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v6.2.0...5fda3b95a4ea91299a34e894583c3862153e4b97) Updates `actions/setup-node` from 6.4.0 to 7.0.0 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](48b55a011b...8207627860) Updates `actions/cache/restore` from 5.0.5 to 6.1.0 - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](27d5ce7f10...55cc834586) Updates `actions/cache/save` from 5.0.5 to 6.1.0 - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](27d5ce7f10...55cc834586) Updates `actions/upload-artifact` from 4.6.1 to 7.0.1 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4.6.1...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a) Updates `step-security/harden-runner` from 2.19.1 to 2.20.0 - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](a5ad31d6a1...bf7454d06d) Updates `ossf/scorecard-action` from 2.4.1 to 2.4.3 - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](f49aabe0b5...4eaacf0543) Updates `github/codeql-action` from 3 to 4 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v3...v4) Updates `tauri-apps/tauri-action` from 0.6.2 to 1.0.0 - [Release notes](https://github.com/tauri-apps/tauri-action/releases) - [Changelog](https://github.com/tauri-apps/tauri-action/blob/dev/CHANGELOG.md) - [Commits](84b9d35b5f...1deb371b0c) Updates `trufflesecurity/trufflehog` from 3.95.3 to 3.95.9 - [Release notes](https://github.com/trufflesecurity/trufflehog/releases) - [Commits](37b77001d0...27b0417c16) Updates `actions/stale` from 10.2.0 to 10.4.0 - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](b5d41d4e1d...1e223db275) --- updated-dependencies: - dependency-name: actions/cache/restore dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/cache/save dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/checkout dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/setup-node dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/setup-python dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions - dependency-name: actions/stale dependency-version: 10.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions - dependency-name: actions/upload-artifact dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: github/codeql-action dependency-version: 4.37.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: ossf/scorecard-action dependency-version: 2.4.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: step-security/harden-runner dependency-version: 2.20.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions - dependency-name: tauri-apps/tauri-action dependency-version: 1.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: trufflesecurity/trufflehog dependency-version: 3.95.9 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions ... Signed-off-by: dependabot[bot] <support@github.com>
355 lines
15 KiB
YAML
355 lines
15 KiB
YAML
# SPDX-License-Identifier: AGPL-3.0-only
|
|
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
|
|
|
|
# Mac counterpart to studio-ui-smoke.yml. Same Playwright + Chromium
|
|
# end-to-end chat UI flow, but on macos-14 (M1) so we catch
|
|
# Mac-specific frontend / backend wiring regressions that the Linux
|
|
# job would miss (e.g. the Mac Tauri shell loading the same React
|
|
# bundle, or the Mac llama.cpp prebuilt's HTTP layer behaving
|
|
# differently from the Linux build).
|
|
|
|
name: Mac Studio UI CI
|
|
|
|
on:
|
|
pull_request:
|
|
paths:
|
|
- 'studio/**'
|
|
- 'unsloth/**'
|
|
- 'unsloth_cli/**'
|
|
- 'install.sh'
|
|
- 'pyproject.toml'
|
|
- 'tests/studio/**'
|
|
- '.github/scripts/run-studio-permission-browser.sh'
|
|
- '.github/workflows/studio-mac-ui-smoke.yml'
|
|
push:
|
|
branches: [main, pip]
|
|
workflow_dispatch:
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
ui-smoke:
|
|
name: Chat UI Tests
|
|
runs-on: macos-14
|
|
timeout-minutes: 35
|
|
env:
|
|
GGUF_REPO: unsloth/gemma-3-270m-it-GGUF
|
|
GGUF_VARIANT: UD-Q4_K_XL
|
|
GGUF_FILE: gemma-3-270m-it-UD-Q4_K_XL.gguf
|
|
STUDIO_PORT: '18896'
|
|
HF_HOME: ${{ github.workspace }}/hf-cache
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: '22'
|
|
|
|
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
with:
|
|
python-version: '3.12'
|
|
cache: 'pip'
|
|
|
|
- name: Restore HF_HOME for ${{ env.GGUF_REPO }}
|
|
id: cache-hf
|
|
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
continue-on-error: true
|
|
with:
|
|
path: hf-cache
|
|
key: ${{ runner.os }}-hf-${{ env.GGUF_REPO }}-${{ env.GGUF_VARIANT }}-v2
|
|
|
|
- name: Prime HF_HOME with the GGUF
|
|
id: prime-hf
|
|
if: steps.cache-hf.outputs.cache-hit != 'true' || steps.cache-hf.outcome != 'success'
|
|
env:
|
|
# Withheld on PR: this step runs checked-out PR code; public GGUF still downloads.
|
|
HF_TOKEN: ${{ github.event_name != 'pull_request' && secrets.HF_TOKEN || '' }}
|
|
run: |
|
|
python -m pip install --upgrade huggingface_hub
|
|
mkdir -p hf-cache
|
|
bash .github/scripts/hf-download-with-retry.sh "$GGUF_REPO" "$GGUF_FILE"
|
|
bash .github/scripts/hf-download-with-retry.sh ggml-org/models tinyllamas/stories260K.gguf
|
|
|
|
- name: Save HF_HOME for ${{ env.GGUF_REPO }}
|
|
if: always() && steps.prime-hf.outcome == 'success'
|
|
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
with:
|
|
path: hf-cache
|
|
key: ${{ runner.os }}-hf-${{ env.GGUF_REPO }}-${{ env.GGUF_VARIANT }}-v2
|
|
|
|
- name: Install Unsloth (--local, --no-torch)
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
# Withheld on PR: this step runs checked-out PR code; public GGUF still downloads.
|
|
HF_TOKEN: ${{ github.event_name != 'pull_request' && secrets.HF_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: Install Playwright browsers
|
|
# No --with-deps on Mac: that flag installs Linux apt packages.
|
|
# GitHub-hosted macos-14 ships the system frameworks Chromium
|
|
# needs already.
|
|
# Pinned <1.58 because all 1.55-1.58 drivers ship Node 24 on
|
|
# macos-14 and intermittently hit 'SyntaxError: Unexpected end
|
|
# of JSON input' in pipeTransport.js. Run 25491698868 showed
|
|
# the crash hitting 100% of three retry attempts -- not a
|
|
# rare race but a hard reproduction. Belt-and-suspenders fix:
|
|
# the test scripts pass --single-process to Chromium (see
|
|
# tests/studio/playwright_chat_ui.py) AND we patch
|
|
# pipeTransport.js below to swallow JSON parse errors instead
|
|
# of crashing the driver Node process. Both together let the
|
|
# in-script retry recover from any residual flakes.
|
|
run: |
|
|
pip install 'playwright>=1.55,<1.58'
|
|
python -m playwright install chromium webkit
|
|
|
|
- name: Patch Playwright pipeTransport.js to tolerate malformed JSON
|
|
# In Playwright 1.55-1.58, pipeTransport.js does
|
|
# `JSON.parse(message)` with no try/catch; when Chromium dies
|
|
# mid-write the partial buffer crashes the driver Node
|
|
# process and the test script exits with 'Connection closed
|
|
# while reading from the driver'. Newer Playwright versions
|
|
# added a try/catch upstream. Backport that here.
|
|
run: |
|
|
python - <<'PY'
|
|
import os, re, sys
|
|
import playwright
|
|
driver_dir = os.path.join(os.path.dirname(playwright.__file__), "driver", "package", "lib", "server")
|
|
path = os.path.join(driver_dir, "pipeTransport.js")
|
|
src = open(path).read()
|
|
# Wrap both `this.onmessage.call(null, JSON.parse(...))` sites in try/catch.
|
|
patched = re.sub(
|
|
r"this\.onmessage\.call\(null, JSON\.parse\((message2?)\)\);",
|
|
r"try { this.onmessage.call(null, JSON.parse(\1)); } "
|
|
r"catch (e) { /* swallow malformed JSON from a crashing browser */ }",
|
|
src,
|
|
)
|
|
if patched == src:
|
|
# Already patched, or upstream changed -- either way, don't fail the build.
|
|
print(f"pipeTransport.js: no JSON.parse calls matched at {path}; skipping.")
|
|
else:
|
|
open(path, "w").write(patched)
|
|
print(f"pipeTransport.js: patched JSON.parse calls in {path}")
|
|
PY
|
|
|
|
- name: Reset auth + boot Unsloth
|
|
run: |
|
|
# Wipe (not reset-password): the boot below must re-seed a fresh .bootstrap_password.
|
|
rm -rf ~/.unsloth/studio/auth
|
|
mkdir -p logs
|
|
UNSLOTH_API_ONLY=1 unsloth studio -H 127.0.0.1 -p "$STUDIO_PORT" \
|
|
> logs/studio.log 2>&1 &
|
|
echo "STUDIO_PID=$!" >> "$GITHUB_ENV"
|
|
|
|
- name: Wait for /api/health
|
|
run: |
|
|
for i in $(seq 1 180); do
|
|
if curl -fs "http://127.0.0.1:${STUDIO_PORT}/api/health" > /tmp/health.json; then
|
|
jq -e '.status == "healthy"' /tmp/health.json && break
|
|
fi
|
|
sleep 1
|
|
done
|
|
jq -e '.status == "healthy"' /tmp/health.json
|
|
|
|
- name: Pass bootstrap password to the Playwright step
|
|
run: |
|
|
OLD=$(cat ~/.unsloth/studio/auth/.bootstrap_password)
|
|
NEW="CIUi-$(python -c 'import secrets; print(secrets.token_urlsafe(16))')"
|
|
NEW2="CIUi-$(python -c 'import secrets; print(secrets.token_urlsafe(16))')"
|
|
echo "::add-mask::$OLD"
|
|
echo "::add-mask::$NEW"
|
|
echo "::add-mask::$NEW2"
|
|
echo "STUDIO_OLD_PW=$OLD" >> "$GITHUB_ENV"
|
|
echo "STUDIO_NEW_PW=$NEW" >> "$GITHUB_ENV"
|
|
echo "STUDIO_NEW2_PW=$NEW2" >> "$GITHUB_ENV"
|
|
|
|
- name: Drive the chat UI with Playwright
|
|
env:
|
|
BASE_URL: http://127.0.0.1:18896
|
|
PW_ART_DIR: logs/playwright
|
|
STUDIO_UI_STRICT: '1'
|
|
# macos-14 free runner is 3 vCPU / 7 GB / no Metal-accel
|
|
# available to llama.cpp from CI; gemma-3-270m turn latency
|
|
# has been observed to crowd the 180s default. Triple it.
|
|
STUDIO_UI_TURN_TIMEOUT_MS: '540000'
|
|
# Retry up to 3 times to absorb known macos-14 free-runner
|
|
# flakes: (1) Playwright Node 24 pipeTransport.js 'Unexpected
|
|
# end of JSON input' crash when the Chromium browser process
|
|
# dies mid-test, (2) Chromium net::ERR_NO_BUFFER_SPACE when the
|
|
# runner's kernel briefly runs out of socket buffers, and (3) a
|
|
# goto 'interrupted by another navigation' when the SPA auth
|
|
# guard redirects mid-navigation. The retry FULLY resets Unsloth
|
|
# (kill, wipe auth, reboot, wait /api/health, re-export
|
|
# bootstrap pw) before re-running the script. A real test failure
|
|
# (assertion / timeout) does NOT match any pattern so it bypasses
|
|
# retry and surfaces immediately.
|
|
run: |
|
|
mkdir -p logs/playwright
|
|
attempt=1
|
|
max_attempts=3
|
|
while : ; do
|
|
set +e
|
|
python tests/studio/playwright_chat_ui.py 2>&1 | tee logs/playwright_attempt_${attempt}.log
|
|
rc=${PIPESTATUS[0]}
|
|
set -e
|
|
if [ "$rc" -eq 0 ]; then
|
|
break
|
|
fi
|
|
if { grep -q "Unexpected end of JSON input" logs/playwright_attempt_${attempt}.log \
|
|
|| grep -q "ERR_NO_BUFFER_SPACE" logs/playwright_attempt_${attempt}.log \
|
|
|| grep -q "interrupted by another navigation" logs/playwright_attempt_${attempt}.log; } \
|
|
&& [ "$attempt" -lt "$max_attempts" ]; then
|
|
echo "::warning::Playwright flake on attempt ${attempt}; resetting Unsloth and retrying..."
|
|
kill "${STUDIO_PID}" 2>/dev/null || true
|
|
sleep 2
|
|
rm -rf ~/.unsloth/studio/auth
|
|
UNSLOTH_API_ONLY=1 unsloth studio -H 127.0.0.1 -p "$STUDIO_PORT" \
|
|
> "logs/studio_retry_${attempt}.log" 2>&1 &
|
|
STUDIO_PID=$!
|
|
echo "STUDIO_PID=$STUDIO_PID" >> "$GITHUB_ENV"
|
|
for i in $(seq 1 180); do
|
|
if curl -fs "http://127.0.0.1:${STUDIO_PORT}/api/health" > /tmp/health.json \
|
|
&& jq -e '.status == "healthy"' /tmp/health.json >/dev/null; then
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
STUDIO_OLD_PW=$(cat ~/.unsloth/studio/auth/.bootstrap_password)
|
|
STUDIO_NEW_PW="CIUi-$(python -c 'import secrets; print(secrets.token_urlsafe(16))')"
|
|
STUDIO_NEW2_PW="CIUi-$(python -c 'import secrets; print(secrets.token_urlsafe(16))')"
|
|
echo "::add-mask::$STUDIO_OLD_PW"
|
|
echo "::add-mask::$STUDIO_NEW_PW"
|
|
echo "::add-mask::$STUDIO_NEW2_PW"
|
|
export STUDIO_OLD_PW STUDIO_NEW_PW STUDIO_NEW2_PW
|
|
attempt=$((attempt + 1))
|
|
sleep 3
|
|
continue
|
|
fi
|
|
exit "$rc"
|
|
done
|
|
|
|
- name: Stop Unsloth (chat-ui ends with Shutdown click; this is belt-and-suspenders)
|
|
if: always()
|
|
run: |
|
|
kill "${STUDIO_PID}" 2>/dev/null || true
|
|
sleep 2
|
|
|
|
- name: Cross-browser permission controls
|
|
run: |
|
|
bash .github/scripts/run-studio-permission-browser.sh 18895 webkit
|
|
|
|
- name: Reset auth + boot Unsloth for extra UI tests (port 18897)
|
|
run: |
|
|
rm -rf ~/.unsloth/studio/auth
|
|
mkdir -p logs
|
|
UNSLOTH_API_ONLY=1 unsloth studio -H 127.0.0.1 -p 18897 \
|
|
> logs/studio_extra.log 2>&1 &
|
|
echo "STUDIO_EXTRA_PID=$!" >> "$GITHUB_ENV"
|
|
|
|
- name: Wait for /api/health on 18897
|
|
run: |
|
|
for i in $(seq 1 180); do
|
|
if curl -fs "http://127.0.0.1:18897/api/health" > /tmp/health2.json; then
|
|
jq -e '.status == "healthy"' /tmp/health2.json && break
|
|
fi
|
|
sleep 1
|
|
done
|
|
jq -e '.status == "healthy"' /tmp/health2.json
|
|
|
|
- name: Pass bootstrap pw for extra UI test
|
|
run: |
|
|
OLD=$(cat ~/.unsloth/studio/auth/.bootstrap_password)
|
|
NEW="CIUiExtra-$(python -c 'import secrets; print(secrets.token_urlsafe(16))')"
|
|
echo "::add-mask::$OLD"
|
|
echo "::add-mask::$NEW"
|
|
echo "STUDIO_EXTRA_OLD_PW=$OLD" >> "$GITHUB_ENV"
|
|
echo "STUDIO_EXTRA_NEW_PW=$NEW" >> "$GITHUB_ENV"
|
|
|
|
- name: Drive Compare/Recipes/Export/Unsloth/Settings with Playwright
|
|
env:
|
|
BASE_URL: http://127.0.0.1:18897
|
|
STUDIO_OLD_PW: ${{ env.STUDIO_EXTRA_OLD_PW }}
|
|
STUDIO_NEW_PW: ${{ env.STUDIO_EXTRA_NEW_PW }}
|
|
PW_ART_DIR: logs/playwright_extra
|
|
STUDIO_UI_STRICT: '1'
|
|
# See "Drive the chat UI" step.
|
|
STUDIO_UI_TURN_TIMEOUT_MS: '540000'
|
|
GGUF_REPO: ${{ env.GGUF_REPO }}
|
|
GGUF_VARIANT: ${{ env.GGUF_VARIANT }}
|
|
# Same flake-retry shape as "Drive the chat UI with Playwright" -- catches
|
|
# pipeTransport JSON crash, ERR_NO_BUFFER_SPACE, and nav interrupts.
|
|
run: |
|
|
mkdir -p logs/playwright_extra
|
|
attempt=1
|
|
max_attempts=3
|
|
while : ; do
|
|
set +e
|
|
python tests/studio/playwright_extra_ui.py 2>&1 | tee logs/playwright_extra_attempt_${attempt}.log
|
|
rc=${PIPESTATUS[0]}
|
|
set -e
|
|
if [ "$rc" -eq 0 ]; then
|
|
break
|
|
fi
|
|
if { grep -q "Unexpected end of JSON input" logs/playwright_extra_attempt_${attempt}.log \
|
|
|| grep -q "ERR_NO_BUFFER_SPACE" logs/playwright_extra_attempt_${attempt}.log \
|
|
|| grep -q "interrupted by another navigation" logs/playwright_extra_attempt_${attempt}.log; } \
|
|
&& [ "$attempt" -lt "$max_attempts" ]; then
|
|
echo "::warning::Playwright flake on attempt ${attempt}; resetting Unsloth and retrying..."
|
|
kill "${STUDIO_EXTRA_PID}" 2>/dev/null || true
|
|
sleep 2
|
|
rm -rf ~/.unsloth/studio/auth
|
|
UNSLOTH_API_ONLY=1 unsloth studio -H 127.0.0.1 -p 18897 \
|
|
> "logs/studio_extra_retry_${attempt}.log" 2>&1 &
|
|
STUDIO_EXTRA_PID=$!
|
|
echo "STUDIO_EXTRA_PID=$STUDIO_EXTRA_PID" >> "$GITHUB_ENV"
|
|
for i in $(seq 1 180); do
|
|
if curl -fs "http://127.0.0.1:18897/api/health" > /tmp/health2.json \
|
|
&& jq -e '.status == "healthy"' /tmp/health2.json >/dev/null; then
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
STUDIO_OLD_PW=$(cat ~/.unsloth/studio/auth/.bootstrap_password)
|
|
STUDIO_NEW_PW="CIUiExtra-$(python -c 'import secrets; print(secrets.token_urlsafe(16))')"
|
|
echo "::add-mask::$STUDIO_OLD_PW"
|
|
echo "::add-mask::$STUDIO_NEW_PW"
|
|
export STUDIO_OLD_PW STUDIO_NEW_PW
|
|
attempt=$((attempt + 1))
|
|
sleep 3
|
|
continue
|
|
fi
|
|
exit "$rc"
|
|
done
|
|
|
|
- name: Stop second Unsloth
|
|
if: always()
|
|
run: |
|
|
kill "${STUDIO_EXTRA_PID}" 2>/dev/null || true
|
|
sleep 2
|
|
|
|
- name: Upload Playwright artifacts
|
|
if: always()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: mac-studio-ui-smoke-artifacts
|
|
path: |
|
|
logs/studio.log
|
|
logs/studio_extra.log
|
|
logs/install.log
|
|
logs/playwright
|
|
logs/playwright-permissions-*
|
|
logs/playwright_extra
|
|
logs/studio-permissions-*.log
|
|
retention-days: 7
|