Skip to content

fix(runtimed): ephemeral notebook review cleanups #4360

fix(runtimed): ephemeral notebook review cleanups

fix(runtimed): ephemeral notebook review cleanups #4360

Workflow file for this run

name: Build
on:
push:
branches: [main]
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
jobs:
changes:
name: Detect source changes
runs-on: blacksmith-4vcpu-ubuntu-2404
outputs:
source_changed: ${{ steps.filter.outputs.source }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Check changed paths
id: filter
uses: dorny/paths-filter@v3
with:
filters: |
source:
- ".github/workflows/**"
- "apps/**"
- "bin/**"
- "crates/**"
- "e2e/**"
- "!e2e/*.md"
- "python/**"
- "scripts/**"
- "src/**"
- "Cargo.toml"
- "Cargo.lock"
- "rust-toolchain.toml"
- "package.json"
- "package-lock.json"
- "pnpm-lock.yaml"
- "pnpm-workspace.yaml"
- "biome.json"
- "components.json"
- "tailwind.config.js"
- "tsconfig.json"
- "vitest.config.ts"
lint:
name: Lint & Format
needs: [changes]
if: needs.changes.outputs.source_changed == 'true'
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v6
- name: Install rust
uses: dsherret/rust-toolchain-file@v1
- name: Check Rust formatting
run: cargo fmt --check
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "20"
- name: Enable corepack
run: corepack enable
- name: Install JS dependencies
run: pnpm install
- name: Check Biome (format + lint + imports)
run: npx @biomejs/biome check apps/notebook/src/ e2e/
- name: Check MCP App renderer plugins are up to date
run: |
pnpm --filter nteract-mcp-app run build:plugins
git diff --exit-code crates/runt-mcp/assets/plugins/ || {
echo "::error::MCP App renderer plugins are stale. Run 'cd apps/mcp-app && pnpm build:plugins' and commit the changes."
exit 1
}
- name: Lint GitHub Actions workflows
uses: raven-actions/actionlint@v2
with:
shellcheck: false
windows-clippy:
name: Windows (clippy)
needs: [changes]
if: needs.changes.outputs.source_changed == 'true'
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v6
with:
lfs: true
- name: Install rust
uses: dsherret/rust-toolchain-file@v1
- uses: Swatinem/rust-cache@v2
with:
shared-key: windows-cross
- name: Install mingw-w64 and add Windows GNU target
run: |
sudo apt-get update -qq
sudo apt-get install -y gcc-mingw-w64-x86-64 nasm
rustup target add x86_64-pc-windows-gnu
# Build MCP output widget HTML (needed by runt-mcp's include_str!)
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm --filter nteract-mcp-app install && pnpm --filter nteract-mcp-app run build
- name: Clippy (Windows cross-check)
run: cargo clippy --target x86_64-pc-windows-gnu --workspace --exclude notebook --exclude runtimed-wasm --exclude runtimed-py --all-targets -- -D warnings
wasm-deno:
name: WASM + Deno Tests
needs: [changes]
if: needs.changes.outputs.source_changed == 'true'
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v6
- name: Install rust
uses: dsherret/rust-toolchain-file@v1
- uses: Swatinem/rust-cache@v2
with:
shared-key: ubuntu-wasm
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Build runtimed-wasm
run: wasm-pack build crates/runtimed-wasm --target web --out-dir ../../apps/notebook/src/wasm/runtimed-wasm
- name: Check WASM bindings are up to date
run: |
git diff --exit-code -- apps/notebook/src/wasm/runtimed-wasm/ ':!*.wasm' || {
echo "::error::Checked-in WASM bindings are stale. Run: wasm-pack build crates/runtimed-wasm --target web --out-dir ../../apps/notebook/src/wasm/runtimed-wasm"
exit 1
}
- name: Install Deno
uses: denoland/setup-deno@v2
with:
deno-version: "2.4"
- name: Run runtimed-wasm Deno tests
run: deno test --allow-read --allow-env --no-check crates/runtimed-wasm/tests/
build-ui:
name: Build shared UI artifacts
needs: [changes]
if: needs.changes.outputs.source_changed == 'true'
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v6
with:
lfs: true
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "20"
- name: Enable corepack
run: corepack enable
- name: Set pnpm store directory
run: pnpm config set store-dir ~/.pnpm-store
- name: Cache pnpm store
uses: actions/cache@v5
with:
path: ~/.pnpm-store
key: pnpm-store-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
pnpm-store-${{ runner.os }}-
- name: Install JS dependencies
run: pnpm install
- name: Build UIs
run: |
pnpm --dir apps/notebook build
- name: Upload UI build artifacts
uses: actions/upload-artifact@v4
with:
name: ui-build-dist
path: |
apps/notebook/dist/
retention-days: 1
js-tests:
name: JS Tests & Benchmarks
needs: [changes]
if: needs.changes.outputs.source_changed == 'true'
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v6
with:
lfs: true
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "20"
- name: Enable corepack
run: corepack enable
- name: Set pnpm store directory
run: pnpm config set store-dir ~/.pnpm-store
- name: Cache pnpm store
uses: actions/cache@v5
with:
path: ~/.pnpm-store
key: pnpm-store-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
pnpm-store-${{ runner.os }}-
- name: Install JS dependencies
run: pnpm install
- name: Run JS tests
run: pnpm test:run
- name: Run JS benchmarks
run: pnpm vitest bench --run apps/notebook/src/lib/__tests__/
build-linux:
name: Linux (release artifacts)
needs: [changes, build-ui]
if: needs.changes.outputs.source_changed == 'true'
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v6
with:
lfs: true
- name: Download UI build artifacts
uses: actions/download-artifact@v4
with:
name: ui-build-dist
path: apps/notebook/dist
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libxdo-dev
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install rust
uses: dsherret/rust-toolchain-file@v1
- uses: Swatinem/rust-cache@v2
with:
shared-key: ubuntu-release
# Build MCP output widget HTML (needed by runt-mcp's include_str!)
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm --filter nteract-mcp-app install && pnpm --filter nteract-mcp-app run build
- name: Build external binaries
shell: bash
run: |
cargo build --release -p runtimed -p runt-cli -p mcpb-runt
TARGET=$(rustc --print host-tuple)
mkdir -p crates/notebook/binaries
if [[ "$RUNNER_OS" == "Windows" ]]; then
cp target/release/runtimed.exe "crates/notebook/binaries/runtimed-$TARGET.exe"
cp target/release/runt.exe "crates/notebook/binaries/runt-$TARGET.exe"
cp target/release/mcpb-runt.exe "crates/notebook/binaries/mcpb-runt-$TARGET.exe"
else
cp target/release/runtimed "crates/notebook/binaries/runtimed-$TARGET"
cp target/release/runt "crates/notebook/binaries/runt-$TARGET"
cp target/release/mcpb-runt "crates/notebook/binaries/mcpb-runt-$TARGET"
fi
- name: Clippy (notebook crate)
run: cargo clippy -p notebook --all-targets -- -D warnings
- name: Install cargo-binstall
run: curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
- name: Install tauri-cli
run: cargo binstall tauri-cli --no-confirm --locked --force
- name: Upload Linux Rust binaries
uses: actions/upload-artifact@v4
with:
name: linux-rust-binaries
path: |
target/release/runtimed
target/release/runt
target/release/mcpb-runt
crates/notebook/binaries/runtimed-*
crates/notebook/binaries/runt-*
crates/notebook/binaries/mcpb-runt-*
retention-days: 1
- name: Build Tauri E2E app
run: cd crates/notebook && cargo tauri build --ci --no-bundle --features e2e-webdriver --config '{"build":{"beforeBuildCommand":""}}'
- name: Stage E2E artifacts
run: |
mkdir -p target/release/binaries
cp crates/notebook/binaries/runtimed-* target/release/binaries/
cp crates/notebook/binaries/runt-* target/release/binaries/
cp crates/notebook/binaries/mcpb-runt-* target/release/binaries/
- name: Upload E2E app
uses: actions/upload-artifact@v4
with:
name: e2e-app-linux
path: |
target/release/notebook
target/release/binaries/
retention-days: 1
- name: Test notebook crate
run: cargo test -p notebook --verbose
clippy-and-tests:
name: Clippy & Tests (Linux)
needs: [changes]
if: needs.changes.outputs.source_changed == 'true'
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v6
with:
lfs: true
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libxdo-dev
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install rust
uses: dsherret/rust-toolchain-file@v1
- uses: Swatinem/rust-cache@v2
with:
shared-key: ubuntu-clippy
# Build MCP output widget HTML (needed by runt-mcp's include_str!)
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm --filter nteract-mcp-app install && pnpm --filter nteract-mcp-app run build
# Excludes: notebook (needs bundled binaries, checked in build-linux),
# runtimed-wasm (needs wasm-pack, tested in wasm-deno),
# runtimed-py (needs Python/maturin, tested in runtimed-py-integration).
- name: Clippy
run: cargo clippy --workspace --exclude notebook --exclude runtimed-wasm --exclude runtimed-py --all-targets -- -D warnings
- name: Run tests
run: cargo test --workspace --exclude notebook --exclude runtimed-wasm --exclude runtimed-py --verbose
build:
name: ${{ matrix.platform.name }}
needs: [changes, build-ui]
if: ${{ always() && (needs.changes.outputs.source_changed != 'true' || needs.build-ui.result == 'success') }}
continue-on-error: ${{ matrix.platform.non_blocking }}
runs-on: ${{ needs.changes.outputs.source_changed == 'true' && (github.event_name != 'pull_request' || matrix.platform.run_on_pr) && matrix.platform.runner || 'ubuntu-latest' }}
strategy:
matrix:
platform:
- name: macOS
runner: macos-latest
setup: echo "No extra deps needed on macOS"
run_on_pr: false
non_blocking: false
- name: Windows
runner: windows-latest
setup: echo "No extra deps needed on Windows"
run_on_pr: false
non_blocking: true
steps:
- name: Skip non-source changes
if: needs.changes.outputs.source_changed != 'true'
run: echo "No source changes detected; skipping this platform leg."
- name: Skip this platform on pull requests
if: needs.changes.outputs.source_changed == 'true' && github.event_name == 'pull_request' && !matrix.platform.run_on_pr
run: echo "Skipping this platform for pull_request events."
- uses: actions/checkout@v6
if: needs.changes.outputs.source_changed == 'true' && (github.event_name != 'pull_request' || matrix.platform.run_on_pr)
with:
lfs: true
- name: Download UI build artifacts
if: needs.changes.outputs.source_changed == 'true' && (github.event_name != 'pull_request' || matrix.platform.run_on_pr)
uses: actions/download-artifact@v4
with:
name: ui-build-dist
path: apps/notebook/dist
- name: Install system dependencies
if: needs.changes.outputs.source_changed == 'true' && (github.event_name != 'pull_request' || matrix.platform.run_on_pr)
run: ${{ matrix.platform.setup }}
- name: Install uv
if: needs.changes.outputs.source_changed == 'true' && (github.event_name != 'pull_request' || matrix.platform.run_on_pr)
uses: astral-sh/setup-uv@v7
- name: Install rust
if: needs.changes.outputs.source_changed == 'true' && (github.event_name != 'pull_request' || matrix.platform.run_on_pr)
uses: dsherret/rust-toolchain-file@v1
- uses: Swatinem/rust-cache@v2
if: needs.changes.outputs.source_changed == 'true' && (github.event_name != 'pull_request' || matrix.platform.run_on_pr)
with:
shared-key: ${{ matrix.platform.runner }}
# Build MCP output widget HTML (needed by runt-mcp's include_str!)
- uses: pnpm/action-setup@v4
if: needs.changes.outputs.source_changed == 'true' && (github.event_name != 'pull_request' || matrix.platform.run_on_pr)
- uses: actions/setup-node@v4
if: needs.changes.outputs.source_changed == 'true' && (github.event_name != 'pull_request' || matrix.platform.run_on_pr)
with:
node-version: 22
cache: pnpm
- run: pnpm --filter nteract-mcp-app install && pnpm --filter nteract-mcp-app run build
if: needs.changes.outputs.source_changed == 'true' && (github.event_name != 'pull_request' || matrix.platform.run_on_pr)
- name: Build external binaries
if: needs.changes.outputs.source_changed == 'true' && (github.event_name != 'pull_request' || matrix.platform.run_on_pr)
shell: bash
run: |
cargo build --release -p runtimed -p runt-cli -p mcpb-runt
TARGET=$(rustc --print host-tuple)
mkdir -p crates/notebook/binaries
if [[ "$RUNNER_OS" == "Windows" ]]; then
cp target/release/runtimed.exe "crates/notebook/binaries/runtimed-$TARGET.exe"
cp target/release/runt.exe "crates/notebook/binaries/runt-$TARGET.exe"
cp target/release/mcpb-runt.exe "crates/notebook/binaries/mcpb-runt-$TARGET.exe"
else
cp target/release/runtimed "crates/notebook/binaries/runtimed-$TARGET"
cp target/release/runt "crates/notebook/binaries/runt-$TARGET"
cp target/release/mcpb-runt "crates/notebook/binaries/mcpb-runt-$TARGET"
fi
- name: Clippy
if: needs.changes.outputs.source_changed == 'true' && (github.event_name != 'pull_request' || matrix.platform.run_on_pr)
run: cargo clippy --workspace --all-targets -- -D warnings
- name: Build
if: needs.changes.outputs.source_changed == 'true' && (github.event_name != 'pull_request' || matrix.platform.run_on_pr)
run: cargo build --release
- name: Run tests
if: needs.changes.outputs.source_changed == 'true' && (github.event_name != 'pull_request' || matrix.platform.run_on_pr)
run: cargo test --workspace --verbose
# Build Tauri app once and share with E2E shards
# E2E smoke test - verifies basic app functionality
e2e:
name: "E2E: ${{ matrix.name }}"
runs-on: blacksmith-4vcpu-ubuntu-2404
needs: [changes, build-linux]
if: needs.changes.outputs.source_changed == 'true'
strategy:
fail-fast: false
matrix:
include:
- name: Smoke
spec: ""
notebook: ""
uv_pool: 3
conda_pool: 0
timeout: 12
- name: UI (Cell Visibility)
spec: "e2e/specs/cell-visibility.spec.js"
notebook: "crates/notebook/fixtures/audit-test/14-cell-visibility.ipynb"
uv_pool: 0
conda_pool: 0
timeout: 5
- name: UV Prewarmed
spec: "e2e/specs/prewarmed-uv.spec.js"
notebook: "crates/notebook/fixtures/audit-test/1-vanilla.ipynb"
uv_pool: 3
conda_pool: 0
timeout: 12
- name: Deno
spec: "e2e/specs/deno.spec.js"
notebook: "crates/notebook/fixtures/audit-test/10-deno.ipynb"
uv_pool: 0
conda_pool: 0
timeout: 8
# UV/Conda Inline and Trust Dialog: disabled — trust dialog
# never appears in CI despite banner click and execute fallbacks.
# The daemon correctly reads untrusted status from the fixture file
# (verify_trust_from_file), but the frontend trust flow doesn't
# complete. Needs CI log access to diagnose. See #1275.
# - name: UV Inline Deps
# spec: "e2e/specs/uv-inline.spec.js"
# notebook: "crates/notebook/fixtures/audit-test/2-uv-inline.ipynb"
# uv_pool: 3
# conda_pool: 0
# timeout: 12
# - name: Conda Inline Deps
# spec: "e2e/specs/conda-inline.spec.js"
# notebook: "crates/notebook/fixtures/audit-test/3-conda-inline.ipynb"
# uv_pool: 0
# conda_pool: 3
# timeout: 15
# - name: Trust Dialog
# spec: "e2e/specs/trust-dialog-dismiss.spec.js"
# notebook: "crates/notebook/fixtures/audit-test/2-uv-inline.ipynb"
# uv_pool: 3
# conda_pool: 0
# timeout: 12
- name: UV Pyproject
spec: "e2e/specs/uv-pyproject.spec.js"
notebook: "crates/notebook/fixtures/audit-test/pyproject-project/5-pyproject.ipynb"
uv_pool: 3
conda_pool: 0
timeout: 12
steps:
- uses: actions/checkout@v6
with:
lfs: true
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
libgtk-3-dev \
libwebkit2gtk-4.1-dev \
libxdo-dev \
xvfb \
webkit2gtk-driver
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "20"
- name: Enable corepack
run: corepack enable
- name: Set pnpm store directory
run: pnpm config set store-dir ~/.pnpm-store
- name: Cache pnpm store
uses: actions/cache@v5
with:
path: ~/.pnpm-store
key: pnpm-store-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
pnpm-store-${{ runner.os }}-
- name: Install dependencies
run: pnpm install
- name: Download E2E artifacts
uses: actions/download-artifact@v4
with:
name: e2e-app-linux
path: ./target/release
- name: Make binaries executable
run: |
chmod +x target/release/notebook
chmod +x target/release/binaries/*
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Run E2E test
timeout-minutes: ${{ matrix.timeout }}
run: |
set -o pipefail
mkdir -p e2e-logs
# Pre-seed settings to skip onboarding
mkdir -p ~/.config/nteract-nightly
echo '{"onboarding_completed": true}' > ~/.config/nteract-nightly/settings.json
# Start Xvfb (headless display for WebKitGTK)
Xvfb :99 -screen 0 1920x1080x24 2>/dev/null &
export DISPLAY=:99
sleep 2
# Start daemon with pool configuration.
# Unset UV_CACHE_DIR/UV_PYTHON_INSTALL_DIR so the daemon uses its own
# env paths (runtimed-uv-*) instead of the CI uv action's temp cache.
TARGET=$(ls target/release/binaries/ | grep runtimed | head -1)
env -u UV_CACHE_DIR -u UV_PYTHON_INSTALL_DIR \
RUNTIMED_WORKSPACE_PATH="${GITHUB_WORKSPACE}" \
./target/release/binaries/$TARGET --dev run \
--uv-pool-size ${{ matrix.uv_pool }} --conda-pool-size ${{ matrix.conda_pool }} \
> e2e-logs/daemon.log 2>&1 &
DAEMON_PID=$!
# Wait for pool warm-up (skip for tests with no pool)
if [ "${{ matrix.uv_pool }}" = "0" ] && [ "${{ matrix.conda_pool }}" = "0" ]; then
echo "No pool to warm, sleeping 5s..."
sleep 5
else
echo "Waiting for daemon pool to warm (90s on cold CI)..."
sleep 90
fi
# Start the app (with notebook if specified)
if [ -n "${{ matrix.notebook }}" ]; then
env -u UV_CACHE_DIR -u UV_PYTHON_INSTALL_DIR \
RUNTIMED_WORKSPACE_PATH="${GITHUB_WORKSPACE}" \
RUST_LOG=info,notebook=debug \
./target/release/notebook "${{ matrix.notebook }}" > e2e-logs/app.log 2>&1 &
else
env -u UV_CACHE_DIR -u UV_PYTHON_INSTALL_DIR \
RUNTIMED_WORKSPACE_PATH="${GITHUB_WORKSPACE}" \
RUST_LOG=info,notebook=debug \
./target/release/notebook > e2e-logs/app.log 2>&1 &
fi
APP_PID=$!
# Wait for WebDriver server
for i in $(seq 1 60); do
curl -s http://localhost:4445/status >/dev/null 2>&1 && break
kill -0 $APP_PID 2>/dev/null || { echo "App died"; cat e2e-logs/app.log; exit 1; }
sleep 1
done
echo "WebDriver ready"
# Run tests
if [ -n "${{ matrix.spec }}" ]; then
WEBDRIVER_PORT=4445 E2E_SPEC="${{ matrix.spec }}" \
pnpm test:e2e 2>&1 | tee e2e-logs/test-output.log
else
WEBDRIVER_PORT=4445 pnpm test:e2e 2>&1 | tee e2e-logs/test-output.log
fi
EXIT=$?
# Cleanup
kill $APP_PID $DAEMON_PID 2>/dev/null || true
exit $EXIT
env:
NO_AT_BRIDGE: 1
LIBGL_ALWAYS_SOFTWARE: 1
WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS: 1
WEBKIT_DISABLE_COMPOSITING_MODE: 1
- name: Collect daemon logs
if: always()
run: |
mkdir -p e2e-logs
# Find and copy daemon logs from worktree cache
find ~/.cache/runt/worktrees -name "runtimed.log" -exec cp {} e2e-logs/ \; 2>/dev/null || true
find ~/.cache/runt/worktrees -name "daemon.json" -exec cp {} e2e-logs/ \; 2>/dev/null || true
# Also capture any app logs
ls -la ~/.cache/runt/worktrees/*/ 2>/dev/null || true
echo "=== Daemon log ===" && cat e2e-logs/runtimed.log 2>/dev/null || echo "No daemon log found"
- name: Upload failure screenshots
if: failure()
uses: actions/upload-artifact@v4
with:
name: e2e-screenshots-${{ matrix.name }}
path: e2e-screenshots/failures/
retention-days: 7
- name: Upload daemon logs
if: always()
uses: actions/upload-artifact@v4
with:
name: e2e-logs-${{ matrix.name }}
path: e2e-logs/
retention-days: 7
# Python daemon integration tests — builds its own runtimed binary
runtimed-py-integration:
name: runtimed-py Integration Tests
runs-on: blacksmith-4vcpu-ubuntu-2404
needs: [changes]
if: needs.changes.outputs.source_changed == 'true'
steps:
- uses: actions/checkout@v6
with:
lfs: true
- name: Install rust
uses: dsherret/rust-toolchain-file@v1
- uses: Swatinem/rust-cache@v2
with:
shared-key: ubuntu-py-integration
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install pixi
uses: prefix-dev/setup-pixi@v0.9.4
with:
run-install: false
- name: Build runtimed binary
run: cargo build --release -p runtimed
- name: Build runtimed-py
working-directory: python/runtimed
run: uv run maturin develop --manifest-path ../../crates/runtimed-py/Cargo.toml
- name: Run integration tests
timeout-minutes: 30
working-directory: python/runtimed
run: |
set -o pipefail
mkdir -p integration-logs
# Set environment for CI mode
export RUNTIMED_INTEGRATION_TEST=1
export RUNTIMED_BINARY="${GITHUB_WORKSPACE}/target/release/runtimed"
export RUNTIMED_LOG_LEVEL=debug
export RUNTIMED_WORKSPACE_PATH="${GITHUB_WORKSPACE}"
# Run tests (daemon is spawned by the test fixture)
uv run pytest tests/test_daemon_integration.py -v --tb=short 2>&1 | tee integration-logs/test-output.log || FAIL=1
exit ${FAIL:-0}
- name: Upload test logs
if: always()
uses: actions/upload-artifact@v4
with:
name: runtimed-py-integration-logs
path: python/runtimed/integration-logs/
retention-days: 7