• v3.11.4 6ee2bb9118

    v3.11.4
    All checks were successful
    CI / Backend lint (ruff) (push) Successful in 26s
    CI / Bot/backend version sync (push) Successful in 23s
    CI / Docker image build (push) Successful in 11s
    CI / Bot tests and audit (push) Successful in 2m27s
    CI / Frontend tests, audit, and build (push) Successful in 2m36s
    CI / Backend migration, tests, and audit (push) Successful in 6m9s
    Release / Create Forgejo release (push) Successful in 12s
    Release / Build and push versioned images (push) Successful in 21s
    Stable

    rbrooks released this 2026-08-07 06:18:26 +00:00 | 511 commits to main since this release

    Silent failures made visible, and a frontend toolchain that had been building
    on an end-of-life runtime.

    No migrations; BOT_CONTRACT_VERSION stays 1, so the backend and bot images can
    be upgraded independently. Self-hosters who build their own images will pick up
    Node 22 for the frontend stages automatically — nothing to change by hand.

    Changed

    • [webapp] Migrated the router from react-router-dom 7 to react-router 8.
      In v8 the react-router-dom package was folded into react-router itself and
      is no longer published, so staying on 7.x meant staying on a line that will
      receive no further fixes. This also clears the last allowlisted advisory
      (GHSA-qwww-vcr4-c8h2): the allowlist is now empty, so the audit gate is a
      real check rather than a formality. No behaviour change — every routing API in
      use is exported unchanged from the new package. (#284)

    • [webapp] The frontend is now built and tested on Node 22 instead of Node 20.
      Node 20 reached end-of-life on 2026-04-30 and no longer receives security
      patches, so the production frontend image was being built on an unsupported
      runtime. CI and both Dockerfile frontend stages move together, deliberately —
      testing on one major while building the image with another is how a
      runtime-only break ships green. This also unblocks #284, since react-router v8
      requires Node ≥ 22.22.0. (#284)

    Fixed

    • [webapp] Approving a wiki proposal with no working LLM quietly produced a
      worse entry.
      When an LLM was unavailable, approving a proposal that updates
      an existing entry pasted both versions together instead of merging them, and
      said nothing — the result was indistinguishable from a successful merge. It
      still falls back to appending, since that beats refusing the approval, but it
      now records that it did. This also covers a misconfigured endpoint rather
      than merely an unconfigured one: a malformed URL was silently treated as "no
      LLM configured", sending GMs to a settings page that already had a value in
      it. That case is now logged too. (#287)

    • [ops] Docker builds no longer ship the whole working tree as build context.
      The repository had no .dockerignore, so every build of every target sent
      ~226 MB of node_modules plus the full .git history to the daemon. On a
      Windows host it also failed outright, because npm's symlinks under
      node_modules/.bin do not survive the bind mount — making it impossible to
      build the production image locally to verify a change. CI never saw it, since
      a fresh checkout has no node_modules.

    • [webapp] A response the model cut short was silently turned into a partial
      result.
      When an LLM stopped because it hit its output budget, the transport
      returned the half-finished body as though it were complete. The tolerant JSON
      parser then salvaged the longest valid prefix from it, so a reply that should
      have carried twelve wiki proposals could arrive as three — indistinguishable
      from a session that genuinely produced three, and logged as a successful
      recovery. Truncated structured responses are now rejected so the caller fails
      loudly and can retry, rather than persisting a quietly incomplete result.
      Truncated prose is still returned, since it is shortened rather than
      corrupted. Covers all four providers — llama.cpp, OpenAI, Anthropic and
      Ollama, each of which signals this condition differently. (#293)

    Downloads