Skip to content

Gate build-sdcpp.yml on the staged sd-server generating a real image #1994

Closed

Description

@MODSetter

The gap

docs/architecture/packaging.md lists this under Known gaps:

No CI job generates an image with the staged sd-server; its gates are --help and the platform floors, not a picture.

Why it matters

A binary that prints its help text and links only permitted libraries is not a binary that can diffuse. A ggml backend library pruned one file too far, a recipe that stopped building an operation a model needs, or a pin bump that changed a tensor name all survive both gates. test_audiocpp_voicing.py exists because the same was true of audio.cpp: starting and listing devices proved nothing about sound.

Today a broken sd-server reaches the user as Studio failing on its first image, after a three gigabyte download the app told them to make.

Where

What done looks like

  • build-sdcpp.yml fails when the staged sd-server starts but cannot produce a usable image.
  • The result is checked as a picture: it decodes, it is the size that was asked for, and it is not one flat colour. A byte-length assertion passes on a blank canvas.
  • Which curated model, and at how many steps, is yours to choose. Stable Diffusion 1.5 is the cheapest in the manifest — 512 px, v1-5-pruned_Q4_0.gguf, 3.05 GB — and the runners have no GPU, so wall-clock time is the constraint. Put the run's cost in the PR so the next person can judge it.
  • The pinned file is checked against the manifest's sha256 before it is used, as the voicing test does.
  • Delete the Known gaps line from docs/architecture/packaging.md in the same PR, and add the test to the Packaging tests table there.

What not to change

The --help and platform-floor gates stay. They catch a different failure — a binary that will not start on Ubuntu 22.04 or macOS 13.3 — and they cost seconds. Windows is a pinned download staged by the release job rather than this workflow, so leaving it out of this gate is deliberate, not an oversight.

How to verify

Write the failing test first: a packaging-marked test that asserts an image comes back, which fails while nothing generates one. pyproject.toml pins -m 'not packaging' in addopts, so the marker on the command line is what runs it. The workflow's own paths filter includes .github/workflows/build-sdcpp.yml, so the pull request that adds the gate runs the gate.

python scripts/check_docs.py          # from the repo root, for the doc edit
cd surfsense_local/backend
uv run pytest tests/packaging/test_sdcpp_image.py -m packaging
uv run pytest -m unit
uv run ruff check .

Before you start

Read CONTRIBUTING.md and the packaging doc. Open your PR against dev, not main. Comment here to claim this.

Activity

  1. added
    help wantedExtra attention is needed
    testAdding or improving automated tests
    desktopSurfSense desktop app (surfsense_local)
    on Sep 28, 2026
  2. ybai08 commented on Oct 2, 2026

    @ybai08
    Contributor

    I'd like to take this. Plan: a packaging test shaped like test_audiocpp_voicing.py that starts the staged sd-server with the sidecar's own flags on the manifest's Stable Diffusion 1.5 build (checked against its sha256), asks for one small image at few steps, and checks it as a picture: it decodes, is the size asked for, and is not one flat colour. I will write it failing first, run it on an Apple Silicon Mac against a locally compiled stage, wire it into build-sdcpp.yml after the floor gates, and put the Linux and macOS runners' wall-clock cost from the PR's own run in the description.

  3. MODSetter commented on Oct 7, 2026

    @MODSetter
    OwnerAuthor

    Fixed by #2159, merged into dev, by @ybai08.

    build-sdcpp.yml now starts the staged sd-server with the app's own launch arguments and has it generate a real image from a pinned, sha256-checked Stable Diffusion 1.5 model on Linux and macOS. The image has to decode, be the requested size and not be one flat colour, and a failure stops Pack and the release that depends on it. The test is in the Packaging tests table.

    The Known gaps line this issue quoted is deleted in the same PR. Closing by hand: GitHub only auto-closes on a merge to the default branch, and we merge through dev.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    desktopSurfSense desktop app (surfsense_local)help wantedExtra attention is neededtestAdding or improving automated tests

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions