Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
12ec79a
fix(callbacks): use \u002e instead of \. for dots in dict ID callback…
Mukller Jul 29, 2026
48ad23b
Merge branch 'dev' into fix/dict-id-dot-escape
Mukller Aug 17, 2026
9336d29
test: add regression tests for dict-id JSON dot escaping in create_ca…
Mukller Aug 17, 2026
9eab452
Add optional scroll-to-top behavior to dcc.Link #3974
CNFeffery Sep 5, 2026
2cd348a
Update CHANGELOG.md
CNFeffery Sep 5, 2026
150d850
Merge branch 'dev' into dev
CNFeffery Sep 9, 2026
3896a7f
Merge branch 'dev' into fix/dict-id-dot-escape
T4rk1n Sep 11, 2026
a90bfef
Serialize `Dash._setup_server` under a lock and publish its flag last
mokashang Sep 12, 2026
7b771ac
Forward FastAPI reload scope options
dajiaohuang Sep 17, 2026
374bc45
Merge branch 'dev' into fix/3962-forward-fastapi-reload-options
T4rk1n Sep 18, 2026
6ad48ed
Serialize router_sync and router_async under a lock, mirror _setup_se…
mokashang Sep 20, 2026
b980c87
Merge branch 'dev' into fix/setup-server-race-3971
T4rk1n Sep 21, 2026
e9f8c52
Bump lerna in the npm-dependencies group across 1 directory
dependabot[bot] Sep 21, 2026
6bc8e6d
Merge pull request #3992 from plotly/dependabot/npm_and_yarn/npm-depe…
T4rk1n Sep 22, 2026
96418e4
Group @plotly workspace packages into one Dependabot job
T4rk1n Sep 22, 2026
abe3d37
Update .github/dependabot.yml
T4rk1n Sep 22, 2026
9c56933
Merge pull request #4005 from plotly/deps/dependabot-group-plotly
T4rk1n Sep 22, 2026
dcae82b
Fix resource paths under Windows extended-length paths
SulimanAbdulrazzaq Sep 22, 2026
df45f7e
Run the resource unit tests on Windows CI and narrow the changelog entry
SulimanAbdulrazzaq Sep 23, 2026
da8ef9d
Give the Windows unit test step the built component folders
SulimanAbdulrazzaq Sep 23, 2026
89563d0
docs: add FastAPI reload scope changelog entry
dajiaohuang Sep 24, 2026
1afde44
Merge plotly/dash dev into FastAPI reload scope PR
dajiaohuang Sep 24, 2026
93063dd
Merge pull request #3987 from dajiaohuang/fix/3962-forward-fastapi-re…
T4rk1n Sep 24, 2026
d840f24
Merge branch 'dev' into fix/setup-server-race-3971
T4rk1n Sep 25, 2026
73fb42d
Merge branch 'dev' into fix/windows-extended-path-resources
T4rk1n Sep 25, 2026
7de3f91
Extend include_pages_meta to regular apps
AnnMarieW Sep 26, 2026
1954b98
Set autoComplete="off" in date pickers
AnnMarieW Sep 26, 2026
9f61256
added changelog
AnnMarieW Sep 26, 2026
5c586ff
Fix pages test isolation and black formatting on router_sync
mokashang Sep 27, 2026
cd6bf96
Convert test_callback_unit.py back to LF line endings
Sep 27, 2026
3ebd180
Merge pull request #4007 from SulimanAbdulrazzaq/fix/windows-extended…
T4rk1n Sep 28, 2026
9818de3
Release idle shared-storage topics (#4010)
T4rk1n Sep 28, 2026
c2c3eeb
Bump @types/node
dependabot[bot] Sep 28, 2026
e5475d2
Merge pull request #4017 from plotly/dependabot/npm_and_yarn/componen…
T4rk1n Sep 28, 2026
e000a9f
Bump the npm-dependencies group across 1 directory with 2 updates
dependabot[bot] Sep 28, 2026
8d70eb7
Skip the main module alias when the parent is not a package
jamalkamaladdin Sep 28, 2026
68200fc
Merge branch 'dev' into date-pickers-autocomplete-off
AnnMarieW Sep 28, 2026
1db98ac
Merge pull request #4018 from plotly/dependabot/npm_and_yarn/dash/das…
T4rk1n Sep 28, 2026
7fe581b
Bump the npm-dependencies group across 1 directory with 9 updates
dependabot[bot] Sep 28, 2026
b09b175
Merge pull request #4019 from plotly/dependabot/npm_and_yarn/componen…
T4rk1n Sep 28, 2026
a8173d1
Bump the npm-dependencies group across 1 directory with 3 updates
dependabot[bot] Sep 28, 2026
128ede9
Merge pull request #4020 from plotly/dependabot/npm_and_yarn/componen…
T4rk1n Sep 29, 2026
9fbdf37
Merge branch 'dev' into date-pickers-autocomplete-off
T4rk1n Sep 29, 2026
fc3fe8c
Merge pull request #4014 from AnnMarieW/date-pickers-autocomplete-off
T4rk1n Sep 29, 2026
bab9649
Merge branch 'dev' into fix/setup-server-race-3971
T4rk1n Sep 29, 2026
f647f2d
Merge pull request #3980 from mokashang/fix/setup-server-race-3971
T4rk1n Sep 29, 2026
b4e041b
Merge branch 'dev' into dev
T4rk1n Sep 29, 2026
9f61b15
Merge pull request #3976 from CNFeffery/dev
T4rk1n Sep 29, 2026
304c383
Test the main module alias with a sibling module named after its folder
jamalkamaladdin Sep 29, 2026
bab9d1f
Support social meta tags for regular apps
AnnMarieW Sep 29, 2026
6ae22e0
Merge branch 'dev' into fix/4011-alias-same-name-script
T4rk1n Sep 30, 2026
60e60ef
lint
AnnMarieW Sep 30, 2026
7665f2a
Merge pull request #4023 from jamalkamaladdin/fix/4011-alias-same-nam…
T4rk1n Sep 30, 2026
7558400
Merge branch 'dev' into fix/dict-id-dot-escape
T4rk1n Sep 30, 2026
4cc49f8
Add DASH_SECRET_KEY and DASH_SHARED_STORAGE platform hooks
T4rk1n Sep 30, 2026
9a2f54d
Add PR number to CHANGELOG
T4rk1n Sep 30, 2026
2595fdb
Merge pull request #3923 from Mukller/fix/dict-id-dot-escape
camdecoster Sep 30, 2026
305f89d
Support async hook routes and bind the request for FastAPI hook routes
T4rk1n Sep 30, 2026
52fb685
Add changelog entry for #4027
T4rk1n Sep 30, 2026
c449581
add test
AnnMarieW Oct 1, 2026
e93fe13
Merge branch 'dev' into extend-social-meta-tags
AnnMarieW Oct 1, 2026
babecd5
Merge pull request #4024 from AnnMarieW/extend-social-meta-tags
T4rk1n Oct 2, 2026
0567529
Add changelog for #4024 and update register_page docstrings
AnnMarieW Oct 2, 2026
0f2e6d7
update docstrings
AnnMarieW Oct 2, 2026
fdedbbf
Merge pull request #4034 from AnnMarieW/update-changelog
T4rk1n Oct 5, 2026
bf9dc70
Alias the running main module when Dash() gets an explicit name
raashish1601 Oct 6, 2026
93c5fea
Add changelog entry for #4053
raashish1601 Oct 6, 2026
3830ce0
Bump the npm-dependencies group across 1 directory with 4 updates
dependabot[bot] Oct 6, 2026
00ee048
Stream on multi-worker ASGI with Redis without starving the executor
T4rk1n Oct 6, 2026
f13b3f7
Merge pull request #4045 from plotly/dependabot/npm_and_yarn/dash/das…
T4rk1n Oct 7, 2026
e0e09ac
Bump the npm-dependencies group across 1 directory with 4 updates
dependabot[bot] Oct 7, 2026
56365de
Make topic ttl per publish and expire topics as a whole
T4rk1n Oct 7, 2026
6c182ea
Merge pull request #4044 from plotly/dependabot/npm_and_yarn/componen…
T4rk1n Oct 7, 2026
7f4267c
Address SonarCloud findings and CI pylint on the Redis reader
T4rk1n Oct 7, 2026
de5daba
Bump the npm-dependencies group across 1 directory with 5 updates
dependabot[bot] Oct 7, 2026
15cd814
Merge pull request #4047 from plotly/dependabot/npm_and_yarn/componen…
T4rk1n Oct 8, 2026
adac472
Merge branch 'dev' into fix/3912-alias-main-explicit-name
T4rk1n Oct 8, 2026
6dd5f29
Merge pull request #4053 from raashish1601/fix/3912-alias-main-explic…
T4rk1n Oct 8, 2026
5e6be57
Keep waiting readers' topics alive and sweep empty topics
T4rk1n Oct 8, 2026
a9afdfc
Merge branch 'dev' into fix/4010-free-shared-storage-topics
T4rk1n Oct 9, 2026
6b7287c
fixes `set_props` to merge the existing payload instead of dropping w…
BSd3v Oct 9, 2026
f9343fd
adding changelog
BSd3v Oct 9, 2026
8f3f735
Merge pull request #4016 from plotly/fix/4010-free-shared-storage-topics
T4rk1n Oct 9, 2026
7a12165
updating test and fixing lint
BSd3v Oct 9, 2026
38c22e6
Merge branch 'dev' into fix/3104-set_props-background-callback
BSd3v Oct 9, 2026
6128888
fixing color of green
BSd3v Oct 9, 2026
b44d5ac
adjustment for green color
BSd3v Oct 9, 2026
3686ae3
adjusting color to red
BSd3v Oct 9, 2026
8427d42
Merge branch 'dev' into feat/platform-streaming-env
T4rk1n Oct 9, 2026
5d72135
Address review: Redis key_prefix from URL, drop value from errors, de…
T4rk1n Oct 9, 2026
089b967
Raise InvalidConfig for a malformed DASH_SHARED_STORAGE URL
T4rk1n Oct 9, 2026
ce81314
wrapping set_background_callback for graceful error handling
BSd3v Oct 9, 2026
2f07f95
fix for lint
BSd3v Oct 9, 2026
085118d
adjustment for exception linting
BSd3v Oct 9, 2026
0e366fb
fix for celery manager
BSd3v Oct 9, 2026
b598172
fixing arb async app
BSd3v Oct 12, 2026
c568166
Merge pull request #4057 from BSd3v/fix/3104-set_props-background-cal…
T4rk1n Oct 13, 2026
469ee92
Merge branch 'dev' into feat/async-hook-routes
T4rk1n Oct 13, 2026
cade1e8
Fix mypy arg-type error on Redis kwargs in DASH_SHARED_STORAGE parsing
T4rk1n Oct 13, 2026
2054db5
Merge pull request #4027 from plotly/feat/async-hook-routes
T4rk1n Oct 13, 2026
f4770ad
Merge remote-tracking branch 'origin/dev' into feat/platform-streamin…
T4rk1n Oct 13, 2026
ff54d79
Merge pull request #4026 from plotly/feat/platform-streaming-env
T4rk1n Oct 13, 2026
997a04c
Bump @percy/cli
dependabot[bot] Oct 8, 2026
87fb820
Bump the npm-dependencies group in /components/dash-table with 3 updates
dependabot[bot] Oct 5, 2026
c5febac
Bump the npm-dependencies-security group across 6 directories with 16…
dependabot[bot] Oct 5, 2026
d0c0b75
Bump selenium to 4.49.0 and pyright to 1.1.414
T4rk1n Oct 13, 2026
6af40c8
Merge pull request #4058 from plotly/chore/dependabot-batch-2026-10
T4rk1n Oct 13, 2026
5217007
Merge origin/dev into fix/asgi-redis-streaming
T4rk1n Oct 13, 2026
8c873a5
Keep Redis XREAD blocks under the socket timeout
T4rk1n Oct 14, 2026
c392938
Use parseCookie from cookie v2
T4rk1n Oct 14, 2026
3f8f426
Merge pull request #4054 from plotly/fix/asgi-redis-streaming
T4rk1n Oct 14, 2026
548d2f4
Merge branch 'dev' into fix/cookie-v2-parse
T4rk1n Oct 15, 2026
86472aa
Merge pull request #4066 from plotly/fix/cookie-v2-parse
T4rk1n Oct 15, 2026
42e23b6
version 4.5.0rc1
T4rk1n Oct 13, 2026
0e013cc
Bump npm package versions for 4.5.0rc1
T4rk1n Oct 15, 2026
6429db0
Add missing PR references to CHANGELOG
T4rk1n Oct 15, 2026
c388ddf
Merge pull request #4068 from plotly/release/4.5.0rc1
T4rk1n Oct 15, 2026
518d777
Merge remote-tracking branch 'origin/dev' into master-4.5.0rc1
T4rk1n Oct 15, 2026
f617f85
Version 4.5.0rc1 build artifacts
T4rk1n Oct 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 74 additions & 6 deletions .ai/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,8 @@ Special handling for Colab:
| `DASH_PRUNE_ERRORS` | Simplify tracebacks |
| `HOST` | Server host |
| `PORT` | Server port |
| `DASH_SECRET_KEY` | Signing secret for page, background and stream tokens when `server.secret_key` is unset |
| `DASH_SHARED_STORAGE` | Shared-storage backend when `shared_storage=` is not passed (see Shared Storage) |

## Stores and Client-Side State

Expand Down Expand Up @@ -850,7 +852,7 @@ outputs. Messages are encoded with `msgspec` (msgpack), a hard dependency.
| `get(key, default=None)` | Read a value |
| `set(key, value, ttl=None)` | Write a value; `ttl` = optional lifetime in seconds |
| `delete(key)` | Remove a key |
| `publish(topic, message)` | Append a message to a topic |
| `publish(topic, message, ttl=None)` | Append a message to a topic; `ttl` = release the topic after that long idle |
| `subscribe(topic, replay_from=None)` | Return a `Subscription` |

**Key expiry (TTL).** `set(key, value, ttl=<seconds>)` gives a key a bounded
Expand Down Expand Up @@ -925,6 +927,27 @@ deployment is its own owner and pays no socket overhead. Knobs: `namespace`
purpose, since each topic retains that many arbitrary payloads; raise it for a
wider reconnect window).

**Topic lifetime.** `publish(topic, message, ttl=None)` takes an optional ttl
(seconds, at least `MIN_TOPIC_TTL` = 1s, so a reconnecting reader is not
outrun). A topic with a ttl is released, buffer and sequence both, once nobody
has published to or read from it for that long; a later publish starts it over
at 1, so a consumer returning with an old cursor gets `SharedStorageGap`.
Without a ttl a topic lives as long as the store. The latest publish's ttl
wins. Streaming publishes with `STREAM_TOPIC_TTL` (300s); user topics default
to no ttl. Every backend expires a topic as a whole, never message by message
while it is read (`tests/shared_storage/test_topic_ttl.py` runs the same cases
on all three). Local: the engine records the ttl on the topic and sweeps idle
ones (no publish, head or poll, and no call holding it) at most once a second,
on the next pub/sub call. The sweep also drops empty, unheld topics, such as
the one a returning reader's poll recreates after a release. Redis: the ttl sits in a third key; the publish
script `PEXPIRE`s all three to 1.25 ttl, and a poll script renews them. A poll
on such a topic blocks in `XREAD` for at most a third of that lifetime, not the
usual 5s, so a waiting reader renews it in time. Diskcache: the ttl
sits in a key; on publish or poll, once less than one ttl is left, every key of
the topic (counter, ttl, buffered messages) is renewed to 1.25 ttl, and at
once when a publish changes the ttl. A poll on such a topic waits at most half
a ttl before it renews again.

*Durability* is controlled by `mode` (the key/value store only — pub/sub is
always transient):

Expand Down Expand Up @@ -959,7 +982,13 @@ the replay window; a subscriber past the trimmed floor gets `SharedStorageGap`).
Redis is the single source of truth, so no owner election. Pass a `url`
(defaults to `$REDIS_URL`) or an existing `client` to reuse a connection pool.
This is the only backend correct for **horizontally-scaled, multi-pod**
deployments.
deployments. On an event loop it uses `redis.asyncio` (one client per loop),
and one reader task per loop serves every async subscription with a single
multi-stream `XREAD`; a new subscription interrupts it through a private wake
stream. Never park a blocking read in the executor per subscription: at a dozen
open downlinks that starved every other store call in the worker (25-50% failed
streams at 25 browsers on uvicorn `--workers 4`). Diskcache's async
subscriptions likewise poll without blocking and sleep on the loop.

### Deployment Topology and Shared Storage

Expand All @@ -976,13 +1005,31 @@ election only reaches processes in the same network + filesystem namespace.
This works at 1 pod and fragments silently once it scales — use
`RedisSharedStorage` (one Redis shared by all pods) instead.

A hosting platform can switch the backend without editing the app through
`DASH_SHARED_STORAGE` (`_shared_storage/_env.py`), read only when the app did
not pass `shared_storage=` (the default is a sentinel, so an explicit argument,
`None` included, always wins): `local`, `none`, `diskcache:///abs/path`, or a
`redis://` / `rediss://` URL. A `key_prefix` query parameter on the Redis URL
(`redis://host/0?key_prefix=myapp`) sets `RedisSharedStorage(key_prefix=)` and
is stripped before the URL reaches redis-py; the diskcache path is
percent-decoded. `cluster://` is reserved and raises; anything else raises
`InvalidConfig` at construction, without echoing the value (it can hold
credentials). The value becomes a zero-argument
factory, so nothing is built or connected until `app.shared_storage` is first
read, but a missing extra (`dash[redis]`, `dash[diskcache]`) fails at
construction with the backend's own `ImportError`.

### Custom and Out-of-Tree Backends

`BaseSharedStorage` is the stable, public extension point. A backend — shipped
in-tree or as a **separate package** — implements:

- `get(key, default)` / `set(key, value)` / `delete(key)` — JSON-compatible values
- `publish(topic, message)` and `subscribe(topic, replay_from=None) -> Subscription`
- `publish(topic, message, ttl=None)` and `subscribe(topic, replay_from=None) -> Subscription`
- topic expiry: with a `ttl`, release the topic as a whole once nobody has
published to or read from it for that long, never message by message while
it is read; reject a ttl under `MIN_TOPIC_TTL` (run `test_topic_ttl.py`
against a new backend)
- optional `start()` / `close()` (idempotent, called once per worker)

and returns a `Subscription` (`__iter__` / `__aiter__` / `close`) that raises
Expand Down Expand Up @@ -1010,6 +1057,7 @@ same way as a built-in: `Dash(shared_storage=PostgresSharedStorage(...))`.
| `_shared_storage/_polling.py` | `PollingSubscription`: shared poll-loop subscription for the diskcache/Redis backends |
| `_shared_storage/_transport.py` | Length-prefixed, token-gated socket transport (local backend) |
| `_shared_storage/_codec.py` | msgspec msgpack codec (data-only) |
| `_shared_storage/_env.py` | `DASH_SHARED_STORAGE` parsing |
| `dash.py` | `shared_storage` constructor arg + lazy `app.shared_storage` property |
| `_callback_context.py` | `dash.ctx.shared_storage` accessor |

Expand Down Expand Up @@ -1380,8 +1428,24 @@ The connection id is never chosen by the client: every stream request rides on
`?endId=`, the server-signed per-page-load token, and the backend derives the
id from it (`get_stream_connection_id`), answering 403 when it is missing or
forged -- otherwise a client could read or inject into another page's topic.
Across worker processes every worker must resolve the same signing secret
(`secret_key`).
Across worker processes every worker must resolve the same signing secret.
`_get_signing_secret` resolves, in order: `server.secret_key`, then
`DASH_SECRET_KEY` (for Dash's signing only, never copied onto
`server.secret_key`, so Flask sessions are untouched), then a secret persisted
in the background-callback store, then a per-process random one. With the last,
tokens only verify on the worker that issued them: stream requests 403 on the
other workers, and the first failure in each process logs a warning pointing at
`DASH_SECRET_KEY` (`_warn_unverified_stream_token`). A request with no token at
all is not logged.

Each run of streams (from the first stream after idle until none is in flight)
also carries `&downlinkId=`, picked fresh by the client, and the connection id
is `<end_id>:<downlinkId>`: every run gets its own topic and the client's
cursor restarts at 0. Without it a page that sat idle past `STREAM_TOPIC_TTL` would
resume a cursor into a topic the store released, get `{reset: true}`, and fail
its new stream. The id only partitions the page's own space, so it is not
signed (just checked against `[A-Za-z0-9_-]{1,64}`). The downlink lifecycle
record (`connection_key`) stays keyed on the `end_id` alone.

The downlink is hosted in a SharedWorker (`dash-stream-worker.js`, served like
the WebSocket worker; `config.stream.worker_url`) so **one connection per
Expand All @@ -1399,7 +1463,10 @@ back to a downlink of its own.
- `stream` (ASGI: Quart, FastAPI): one long-lived NDJSON response per
browser. It costs no thread -- the subscription parks the task on a future
the store resolves (`StoreEngine.apoll`; asyncio streams to the owner from
other workers) -- so a single uvicorn worker holds thousands.
other workers; the per-loop Redis reader) -- so a single uvicorn worker
holds thousands. The downlink's connection record is written with the
store's async calls, and its closed record from a task of its own, since a
client disconnect cancels the response.
- `poll` (WSGI: Flask): a WSGI response holds a worker thread for its whole
life, so an open downlink per browser exhausts a thread pool at a few dozen
browsers (gunicorn `--threads 2`: the second browser hung everything).
Expand Down Expand Up @@ -1478,6 +1545,7 @@ the right tool: constant latency and a fraction of the CPU.
- `dash/_streaming.py` - `StreamedCallbackResponse` marker, context-safe iteration, NDJSON helpers, keepalives, shutdown flag
- `dash/_stream_hub.py` - multiplexed transport: `Downlink`, `poll_downlink`, pumps (`pump_to_storage`/`apump_to_storage`), `cancel_stream`, `shutdown_active_streams`/`install_stream_shutdown_handler`
- `dash/_shared_storage/_engine.py`, `local.py` - `poll`/`apoll`, loop-native `aget`/`aset`/`apublish`, async client connection
- `dash/_shared_storage/redis.py` - `redis.asyncio` path, `_StreamReader` (one multi-stream `XREAD` per loop)
- `dash/backends/_flask.py`, `_quart.py`, `_fastapi.py` - streaming dispatch branches
- `dash/backends/ws.py` - `make_stream_frame_emitter`, `consume_stream_frames`/`aconsume_stream_frames`
- `dash/dash-renderer/src/actions/callbacks.ts` - `applyStreamFrame`, NDJSON reader, WS frame handling
Expand Down
54 changes: 48 additions & 6 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ updates:
# NOTE: Dependabot's npm updater recurses from "/" into every nested
# package.json, and neither the singular `directory` nor plural `directories`
# with `!` exclusion globs stops that recursion. So the ONLY reliable way to
# keep this entry from bumping the components/renderer (which carry their own
# narrow allow/ignore lists, e.g. react-docgen is pinned) is the `allow` list
# below: it names only packages that exist SOLELY in the root package.json, so
# even while recursing, Dependabot opens root-only PRs. npm-run-all, rimraf and
# @types/jest are intentionally omitted — they also live in the components and
# would produce duplicate PRs.
# keep this entry from bumping the components/renderer/@plotly packages (which
# each carry their own narrow allow/ignore lists, e.g. react-docgen is pinned)
# is the `allow` list below: it names only packages that exist SOLELY in the
# root package.json, so even while recursing, Dependabot opens root-only PRs.
# npm-run-all, rimraf and @types/jest are intentionally omitted: they also live
# in the components and would produce duplicate PRs.
- package-ecosystem: "npm"
directory: "/"
schedule:
Expand Down Expand Up @@ -194,6 +194,48 @@ updates:
- dependency-name: "babel-loader"
versions: [">=10.0.0"]

# @plotly workspace packages (build helpers, jupyterlab, and the generator /
# test-component fixtures). These have no per-package config, so without this
# entry Dependabot's root "/" recursion opens an individual, ungrouped PR for
# each one. The `directories` glob claims every /@plotly/* manifest and folds
# them into a single grouped PR.
- package-ecosystem: "npm"
directories:
- "/@plotly/*"
schedule:
interval: "weekly"
day: "monday"
cooldown:
default-days: 14
groups:
npm-dependencies:
applies-to: version-updates
patterns:
- "*"
npm-dependencies-security:
applies-to: security-updates
patterns:
- "*"
ignore:
# react-docgen is pinned for legacy metadata extraction (extract-meta.js uses
# the react-docgen 5 API) and must never be updated.
- dependency-name: "react-docgen"
# The test/generator fixtures pin React 16 (react-jsx-parser peer-deps on
# 16/17); a major bump breaks them. Stay on 16.x.
- dependency-name: "react"
versions: [">=17.0.0"]
- dependency-name: "react-dom"
versions: [">=17.0.0"]
# typescript 6+ (and the native tsc 7) break the type-check. Stay on 5.x.
- dependency-name: "typescript"
versions: [">=6.0.0"]
# Babel 8 / babel-loader 10 break the build (the class-properties plugin
# peer-deps on @babel/core ^7). Stay on the 7.x / 9.x line.
- dependency-name: "@babel/*"
versions: [">=8.0.0"]
- dependency-name: "babel-loader"
versions: [">=10.0.0"]

# Python dependencies
- package-ecosystem: "pip"
directory: "/"
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,7 @@ jobs:
build-windows:
name: Build on Windows
runs-on: windows-latest
needs: build
timeout-minutes: 30

steps:
Expand Down Expand Up @@ -1012,6 +1013,15 @@ jobs:
npm ci
npm run build

- name: Download built component folders
uses: actions/download-artifact@v4
with:
name: dash-components
path: ${{ github.workspace }}/dash

- name: Run Windows-specific unit tests
run: python -m pytest tests/unit/test_resources.py

dcc-lint:
name: DCC Lint Tests (Python ${{ matrix.python-version }})
needs: [build, changes_filter]
Expand Down
Loading
Loading