fix: real install steps + depsgraph-export joins the gallery #29
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: Blender Smoke Test | |
| # Executes the snippets' and skills' headline examples inside REAL Blender, headless, | |
| # on the current stable (5.1.x) and the active LTS (4.5.x), and fails on any error or | |
| # empty-output assertion. py_compile (in validate.yml) cannot catch API-level regressions | |
| # like the EEVEE-id inversion, the slotted-actions boundary, the driver TypeError, or the | |
| # dead SDF link -- this gate runs the code so those surface in CI, not in users' files. | |
| on: | |
| workflow_dispatch: {} | |
| schedule: | |
| - cron: "0 7 * * 1" # weekly, Monday 07:00 UTC | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: blender-smoke-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| smoke: | |
| name: Blender ${{ matrix.series }} smoke | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - series: "5.1" # current stable | |
| - series: "4.5" # active LTS | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install Blender runtime libraries | |
| run: | | |
| set -euo pipefail | |
| sudo apt-get update | |
| # Blender needs these shared libs even in --background (GPU/GL module init); | |
| # xvfb provides a virtual display so GL/EGL init does not abort the process. | |
| sudo apt-get install -y --no-install-recommends \ | |
| xvfb libgl1 libegl1 libxrender1 libxxf86vm1 libxfixes3 libxi6 \ | |
| libxkbcommon0 libsm6 libice6 | |
| - name: Resolve and download Blender ${{ matrix.series }} | |
| run: | | |
| set -euo pipefail | |
| series="${{ matrix.series }}" | |
| base="https://download.blender.org/release/Blender${series}/" | |
| echo "Listing $base" | |
| # pick the highest point release for this series (linux x64 portable) | |
| file=$(curl -fsSL "$base" \ | |
| | grep -oE "blender-${series}\.[0-9]+-linux-x64\.tar\.xz" \ | |
| | sort -V | uniq | tail -1) | |
| if [ -z "$file" ]; then | |
| echo "::error::Could not resolve a linux-x64 build for Blender ${series} at $base" | |
| exit 1 | |
| fi | |
| url="${base}${file}" | |
| echo "Downloading $url" | |
| mkdir -p "$RUNNER_TEMP/bl" | |
| curl -fSL --retry 3 -o "$RUNNER_TEMP/bl.tar.xz" "$url" | |
| tar -xf "$RUNNER_TEMP/bl.tar.xz" -C "$RUNNER_TEMP/bl" | |
| bl=$(find "$RUNNER_TEMP/bl" -maxdepth 2 -type f -name blender | head -1) | |
| if [ -z "$bl" ]; then | |
| echo "::error::blender binary not found after extraction" | |
| exit 1 | |
| fi | |
| echo "BLENDER=$bl" >> "$GITHUB_ENV" | |
| - name: Print Blender version | |
| run: | | |
| set -euo pipefail | |
| "$BLENDER" --version | head -1 | |
| # series guard: confirm we actually got the matrix series | |
| "$BLENDER" --version | head -1 | grep -q "Blender ${{ matrix.series }}\." \ | |
| || { echo "::error::version does not match series ${{ matrix.series }}"; exit 1; } | |
| - name: Run in-Blender smoke driver | |
| run: | | |
| set -euo pipefail | |
| mkdir -p "$RUNNER_TEMP/out" | |
| xvfb-run -a "$BLENDER" --background --python tests/smoke/run_smoke.py -- "$RUNNER_TEMP/out" | |
| - name: Build template input scene | |
| run: | | |
| set -euo pipefail | |
| xvfb-run -a "$BLENDER" --background --python tests/smoke/make_input.py -- "$RUNNER_TEMP/out/input.blend" | |
| - name: Headless glTF template runs (exit 0, .glb produced) | |
| run: | | |
| set -euo pipefail | |
| xvfb-run -a "$BLENDER" --background "$RUNNER_TEMP/out/input.blend" \ | |
| --python tests/smoke/tmpl_gltf.py -- \ | |
| --output "$RUNNER_TEMP/out/out.glb" --apply-modifier SUBSURF | |
| test -s "$RUNNER_TEMP/out/out.glb" || { echo "::error::glTF output missing/empty"; exit 1; } | |
| head -c4 "$RUNNER_TEMP/out/out.glb" | grep -q "glTF" || { echo "::error::not a glTF binary"; exit 1; } | |
| - name: Headless template no-mesh path returns exit 2 | |
| run: | | |
| set +e | |
| xvfb-run -a "$BLENDER" --background "$RUNNER_TEMP/out/empty.blend" \ | |
| --python tests/smoke/tmpl_gltf.py -- --output "$RUNNER_TEMP/out/none.glb" | |
| code=$? | |
| set -e | |
| [ "$code" -eq 2 ] || { echo "::error::expected exit 2 for no-mesh input, got $code"; exit 1; } | |
| echo "no-mesh exit code = $code (correct)" | |
| - name: Headless render template runs (exit 0, PNG produced) | |
| run: | | |
| set -euo pipefail | |
| # Cycles (CPU) so this is reliable on GPU-less runners; the EEVEE-id regression | |
| # itself is gated in run_smoke.py via engine assignment. | |
| xvfb-run -a "$BLENDER" --background "$RUNNER_TEMP/out/input.blend" \ | |
| --python tests/smoke/tmpl_render.py -- \ | |
| --output "$RUNNER_TEMP/out/render.png" --engine CYCLES | |
| test -s "$RUNNER_TEMP/out/render.png" || { echo "::error::render PNG missing/empty"; exit 1; } | |
| - name: Shipped example - swatch grid renders and self-verifies | |
| run: | | |
| set -euo pipefail | |
| # Run the SHIPPED example file (not a copy). It asserts non-black AND | |
| # distinct-region-count == material-count internally and exits non-zero on | |
| # failure. Cycles (CPU) for pixels on the GPU-less runner; the example still | |
| # asserts the version-correct EEVEE engine id before rendering. Small/low-sample | |
| # for speed -- region detection holds at this size. | |
| xvfb-run -a "$BLENDER" --background \ | |
| --python examples/swatch-grid/swatch_grid.py -- \ | |
| --output "$RUNNER_TEMP/out/swatch.png" --engine cycles --samples 8 --width 640 | |
| test -s "$RUNNER_TEMP/out/swatch.png" || { echo "::error::swatch grid output missing/empty"; exit 1; } | |
| - name: Shipped example - turntable correctness (slotted actions) | |
| run: | | |
| set -euo pipefail | |
| # Frame-independent check only (no render): asserts the rotation keys drive | |
| # playback via the cross-version channelbag path; exits non-zero on failure. | |
| xvfb-run -a "$BLENDER" --background \ | |
| --python examples/turntable/turntable.py -- | |
| - name: Shipped example - GN SDF remesh correctness (GridToMesh) | |
| run: | | |
| set -euo pipefail | |
| # Frame-independent check only (no render): asserts the SDF->GridToMesh remesh | |
| # yields geometry (eval vcount > 0 and != base); exits non-zero on failure. | |
| xvfb-run -a "$BLENDER" --background \ | |
| --python examples/gn-sdf-remesh/gn_sdf_remesh.py -- | |
| - name: Shipped example - depsgraph-evaluated export | |
| run: | | |
| set -euo pipefail | |
| # Frame-independent check only (no render): asserts wm.obj_export ships the | |
| # depsgraph-evaluated (modifier-applied) geometry -- exported vcount == evaluated | |
| # > base. Exits non-zero on failure. | |
| xvfb-run -a "$BLENDER" --background \ | |
| --python examples/depsgraph-export/depsgraph_export.py -- |