Commit graph

10 commits

Author SHA1 Message Date
maziggy
08df660f6c Replace the embedded G-code viewer with the slicer's own renderer
Sliced files previewed through a vendored copy of PrettyGCode in an
iframe. It drew each move as a screen-space line -- a line has no
thickness in the scene, so it cannot occlude the layer behind it, which
is why prints came out stringy and shimmered where layers crossed. Being
a separate app in a frame, it could be neither themed nor translated, and
carried its own machinery for detecting a proxy refusing the embed.

Now built on libvgcode, the renderer OrcaSlicer draws its own preview
with, vendored from three-slicer (AGPL, same as us). It takes the THREE
namespace as an argument and imports nothing, so it runs on our 0.181
rather than the 0.160 its package pins.

The parser is ours; upstream renders its own kernel's output and ships no
G-code parser at all. Two things it has to get right, both found by
checking a real plate rather than assuming:

- BambuStudio does not use the OrcaSlicer/PrusaSlicer annotations. It
  writes "; FEATURE:", "; LINE_WIDTH:", "; CHANGE_LAYER" and
  "; Z_HEIGHT:", not ";TYPE:", ";WIDTH:" and ";LAYER_CHANGE". Reading
  only the latter showed a 52-layer print as 23,165 layers in one colour,
  because with no layer marker recognised every travel Z-hop split a
  layer and every segment took the fallback feature.
- It emits a tenth of its moves as G2/G3 arcs -- 706 extruding ones in a
  single plate. Ignoring them punched holes through curved walls and tree
  supports. Arcs with no X/Y are the helical travel lift and lay down
  nothing, so they interpolate as travels.

Four colour modes: filament (default, from the AMS slots the file was
sliced with), feature, layer height, line width. Speed, fan and
temperature are deliberately absent -- upstream derives those from
settings rather than the toolpath, and guesses dressed as measurements
are worse than an honest omission. The parser now carries the data to do
them properly later.

Legend entries are switches. Hiding removes the records before the mesh
is built rather than recolouring them: the shader packs colour into a
single float with no alpha, so there is no transparent to set, and
removal is the useful behaviour anyway -- a hidden support stops
occluding what it covered.

The scene is built once and only the toolpath rebuilds. Doing otherwise
constructed a new WebGLRenderer on every render, because the buildVolume
default is an object literal and so a fresh identity each time; browsers
cap live WebGL contexts and drop the oldest, which blanked the canvas
after a few interactions.

utils/framing.ts goes with the iframe, along with six now-orphaned
strings in all 13 locales. src/lib/vendor is excluded from eslint --
acting on findings in vendored code makes it impossible to re-copy on the
next upstream release.
2026-08-09 14:10:18 +02:00
maziggy
80ce5fab9c Revert "ci(docker): don't fail the image build when the Tailscale package server is down"
This reverts commit 591310b392.
2026-07-17 08:26:23 +02:00
maziggy
2647408cc4 ci(docker): don't fail the image build when the Tailscale package server is down
pkgs.tailscale.com intermittently returns 504, which aborted the whole
image build even though the Tailscale CLI is optional (the code falls
back to self-signed without it). Retry the fetch, and on sustained
failure continue building without the CLI instead of failing.
2026-07-17 08:26:23 +02:00
maziggy
c0129ef93f chore(docker): silence Trivy DS-0026 on Dockerfile.test via HEALTHCHECK NONE
Trivy raised DS-0026 ("No HEALTHCHECK defined") against Dockerfile.test
  on every run of the security workflow. The test image is a one-shot
  pytest runner — there's no service to probe, so any HEALTHCHECK we
  invented would be cargo-cult noise that fires once and means nothing.

  HEALTHCHECK NONE is the documented Docker directive to explicitly opt
  out of any inherited HEALTHCHECK and is the way Trivy itself expects
  projects to signal "this image is intentionally not a long-running
  service." Adding it closes code-scanning alert #813 cleanly.

  Note: the perl-base CVE-2026-8376 alert (#811) is left open for now
  and dismissed in the GitHub UI as "Won't fix - no upstream patch"
  because Debian Trixie has not yet shipped a fixed perl-base; the
  patched build will land automatically on the next base-image refresh.
2026-05-24 14:30:03 +02:00
maziggy
39a075918a ci(docker): drop -v, -n auto instead of -n 30, pip cache mount
Three things were making the Docker test runs noisier and slower than
  they needed to be:

  1. -v was hardcoded in Dockerfile.test:35 CMD and in docker-compose.
     test.yml's integration-test-runner command. The ci.yml change to
     drop -v from the bare pytest call missed both — Docker runs use
     the image's CMD, not the workflow's.

  2. -n 30 was hardcoded as the xdist worker count. On a 2-vCPU CI box
     that's 30 Python processes fighting over 2 cores — mostly IPC and
     import-thrash overhead. -n auto adapts to the host: 2 on CI, 30
     on a 30-core dev box. Same final-result throughput on the dev
     box, much better on small runners.

  3. pip install had --no-cache-dir and no BuildKit cache mount, so
     every Docker build re-fetched ~50 packages from PyPI (~60-90s
     on a cold pip cache). Adding `RUN --mount=type=cache,target=
     /root/.cache/pip` (with the `# syntax=docker/dockerfile:1.7`
     directive that enables it) makes subsequent builds re-use the
     download cache so they only do install work, ~5s instead of
     ~90s. DOCKER_BUILDKIT=1 is already exported in test_docker.sh
     and is the GHA default since runner image 2023, so the cache
     mount is always honoured.

  Verified locally: Docker build is 19s warm (was ~90s cold each
  time), test run is 102s with 5287 passed / 1 skipped (the
  by-design spoolbuddy importorskip) — clean output, no [gwN]
  worker spam, no "created: 30/30 workers" startup line.

  GHA-side per-run cold-build slowness still happens because GHA
  runners are ephemeral; a follow-up using docker/build-push-action
  with type=gha cache backend would persist the BuildKit cache
  across CI runs but that's a bigger workflow change.
2026-05-24 13:08:43 +02:00
maziggy
07ea69c3f0 test(docker): include gcode_viewer/ in the test image so the packaging assertion actually runs
Dockerfile.test only COPYed backend/ and pyproject.toml, so the
  integration test at tests/integration/test_gcode_viewer.py:63
  silently pytest.skip'd in every Docker run with "gcode_viewer/
  index.html not present at /app/gcode_viewer/index.html".

  That was deliberate fallback behaviour for unit-test environments
  where the assets are intentionally absent, but in CI it meant the
  #1218 packaging regression (3D Preview returning {"detail":"Not
  Found"} because the embedded PrettyGCode viewer wasn't bundled into
  the prod image) had no test guarding against a recurrence — the
  test that was supposed to catch it was the one being skipped.

  Add COPY gcode_viewer/ ./gcode_viewer/ to the backend-test stage,
  matching the path the production Dockerfile uses (static_dir.parent
  / "gcode_viewer" = /app/gcode_viewer/) so the assertion runs against
  the same layout the app sees at runtime. Path-anchored comment in
  the Dockerfile so a future maintainer doesn't strip the COPY as
  unused.
2026-05-24 11:26:14 +02:00
maziggy
c3e4506275 Updated Dockerfile.test 2026-04-23 17:01:33 +02:00
maziggy
964be0eb26 Improved Docker tests 2026-02-05 10:28:06 +01:00
maziggy
88bd020dc9 Improved Docker support; Added Docker test suite 2025-12-14 10:16:33 +01:00
maziggy
58c98b1075 Added docker test suite
Test Summary:
  - Build tests: 3 passed (image build, backend imports, static files)
  - Backend unit tests: 378 passed (9 docker tests excluded)
  - Frontend unit tests: 137 passed
  - Integration tests: 9 passed (health, API endpoints, persistence, WebSocket)

  Changes made to fix the Docker test suite:
  1. Added curl to the production Dockerfile for integration tests
  2. Removed deprecated version attribute from docker-compose.test.yml
  3. Added --pull flag to all build commands to ensure fresh images
  4. Added explicit build step before starting integration container
  5. Fixed WebSocket test to accept 200 as a valid response
  6. Excluded docker-marked tests from backend unit test runs (-m "not docker")
2025-12-14 09:15:49 +01:00