Commit Graph

12442 Commits

Author SHA1 Message Date
Fernando Lins
0db33b0df5 fix(ci): ignore HTML comments when detecting linked issues 2026-08-21 16:24:15 -03:00
Abdo
ad88eff794 chore: Move .github/scripts/*.py to tools/ (#5375)
## Linked issue

Closes #5374

## Summary

Move .github/scripts to tools/ so they are included in static checking
and testing.

## Steps to reproduce (before)

- Make a formatting/typing error in prepare_release.py and confirm
`ninja check` does not report that.
- Modify test_validate_version.py to fail tests and confirm it's not
caught by ninja check.

## How to test (after)

The scripts should now be included in the checks as the tools/ directory
is already included by the build system.
2026-08-21 18:01:42 +03:00
Abdo
a2ea416089 fix: MSI install is blocked if uninstall.exe exists at a drive root (#5360)
## Linked issue

Closes #5359

## Summary

The Windows installer searches for an old elevated install location at
the `Software\WOW6432Node\Anki` registry key and looks for
`uninstall.exe` there to decide if installation should be blocked. If
the registry key is missing though, the file search was falling back to
looking for any file named uninstall.exe in the root of every drive,
which was never intended.

See template diff:
5c1ced97ff

## Steps to reproduce (before)

1. Create an empty file at `C:\uninstall.exe` or any drive.
2. Try to install
[26.08.1](https://github.com/ankitects/anki/releases/tag/26.08.1) and
confirm it fails with the message "A previous Anki version needs to be
uninstalled first".

## How to test (after)

1. Build the installer with this PR: `./tools/ninja installer:package`.
2. Run `./out/installer/dist/anki-26.08.1-win-x64.msi` and confirm
installation is not blocked.
2026-08-20 21:05:56 +03:00
Fernando Lins
27dc497286 fix: replace asserts inside except clauses with explicit error handling (#5365)
## Linked issue 

Fixes #5355

## Summary / motivation

Two locations used `assert` statements inside broad `except` blocks,
flagged by SonarCloud rule
[python:S5779](https://sonarcloud.io/project/issues?rules=python%3AS5779&issueStatuses=OPEN%2CCONFIRMED&id=ankitects_anki).
This is problematic because:

- `AssertionError` is caught by the surrounding `except`, so the
assertion is silently swallowed instead of surfacing a meaningful error.
- Under `python -O`, `assert` statements are stripped entirely, so the
check disappears in optimized builds and the failure resurfaces later as
an opaque `AttributeError`.

Changes:

- **`qt/aqt/addons.py`** (`download_addon`): replace `assert match is
not None` with `if match is None: raise ValueError(...)` naming the
unexpected `content-disposition` header. The raise is still caught by
the existing handler and returned as a `DownloadError`, now with a
descriptive message.
- **`qt/aqt/editor_legacy.py`** (`setup_mask_editor`): replace `assert
self.note is not None` with a guard that warns the user
(`tr.browsing_no_selection()`) and returns early.

## How to test (required)

### Details

- `just lint` 
- `just test-py`  — includes a new regression test,
`test_download_addon_rejects_bad_content_disposition`, covering the
malformed `content-disposition` path in `download_addon`.
- No test added for the `editor_legacy.py` guard: it defends an
effectively unreachable state (a missing note while editing an existing
note), and that Qt-side method isn't reachable from the web e2e harness.

## Before / after behavior

- **addons.py** — Before: malformed header → empty/opaque
`DownloadError` (or `AttributeError` under `-O`). After: `DownloadError`
carrying a `ValueError` that names the offending header.
- **editor_legacy.py** — Before: missing note → empty warning dialog
(blank `AssertionError` message). After: a clear warning, and early
return.

## Scope

- [x] This PR is focused on one change (no unrelated edits).
2026-08-20 15:04:19 -03:00
Fernando Lins
f046da0ce0 fix: avoid KeyError on missing Content-type header in mediasrv (#5366)
## Linked issue

Fixes #5353

## Summary / motivation

`_check_dynamic_request_permissions` in `qt/aqt/mediasrv.py` read the
`Content-type` header via direct indexing:

```python
if request.headers["Content-type"] != "application/binary":
```

When a request omits that header, `Headers.__getitem__` raises a
`KeyError`, which surfaces as an unhandled `500 Internal Server Error`
instead of the intended `abort(403)`. Flagged by SonarCloud rule
[python:S8371](https://sonarcloud.io/project/issues?rules=python%3AS8371&issueStatuses=OPEN%2CCONFIRMED&id=ankitects_anki)
(unsafe direct header access).

The fix uses `.get()`, which returns None for a missing header. Since
`None != "application/binary"`, a request without the header now
correctly falls through to the `403` rejection path — the desired
behavior for an opaque cross-origin request.

## Steps to reproduce 
1. Send a non-GET request to a dynamic /_anki/ endpoint (e.g. a POST)
without a Content-type header.
2. Server hits request.headers["Content-type"] and raises KeyError.
3. Client receives 500 Internal Server Error instead of 403 Forbidden.

## How to test 
### Details
- Ran `just fmt`, `just lint`, and `just test-py` — all pass.
- Added `TestCheckDynamicRequestPermissions` in
qt/tests/test_mediasrv.py, asserting a POST without a `Content-type`
header raises `Forbidden` (403) rather than `KeyError`.

## Before / after behavior 

**Before**: request with no `Content-type` header → unhandled `KeyError`
→ `500`.

**After**: same request → `abort(403)` as intended.
2026-08-20 14:54:20 -03:00
user1823
5865db4adf Fix: Recompute FSRS data after changing deck (#5339)
## Linked issue (required)

Fixes https://github.com/ankitects/anki/issues/5327

## Summary / motivation (required)

Moving cards between decks used to clear the old FSRS data, without
recomputing the new FSRS data. This led to some unwanted behavior like
absence of memory states in card info, inaccurate searching and sorting
in the browser, etc.

## Steps to reproduce (required, use N/A if not applicable)

1. Move some cards from one deck to another
2. The browser doesn't show any memory states.

## How to test (required)

<!--- How to test: how you verified the change (checks, unit tests,
manual steps, edge cases — the "after" or general validation). --->

### Checklist (minimum)

- [ ] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

<!-- Commands, manual steps, edge cases, and what you observed -->

## Before / after behavior (optional)

<!-- For bugfixes: behavior before vs after. For other types: N/A or a
short note. -->

## Risk / compatibility / migration (optional)

<!-- Breaking changes, rollout notes, or N/A for small / low-risk PRs
-->

## UI evidence (required for visual changes; otherwise N/A)

<!-- Screenshot or short video -->

## Scope

- [x] This PR is focused on one change (no unrelated edits).

---------

Co-authored-by: Luc Mcgrady <lucmcgrady@gmail.com>
Co-authored-by: Fernando Lins <1887601+fernandolins@users.noreply.github.com>
2026-08-20 14:51:23 -03:00
Fernando Lins
a306f84ccc bump(deps): drop vulnerable h2 0.3.x, update h2 to 0.4.17 (RUSTSEC-2026-0258) (#5376)
## Linked issue (required)

Fixes #5364

## Summary / motivation (required)

CI (`check (linux)` → `Run cargo-deny check`) started failing on
[RUSTSEC-2026-0258](https://rustsec.org/advisories/RUSTSEC-2026-0258) —
"h2 unbounded empty DATA frames". No code change of ours introduced it:
cargo-deny fetches the advisory DB at run time, so the same commit began
failing once the advisory was published (2026-08-19).

Two vulnerable `h2` copies were in the tree:

- `h2 0.4.12` — the shipped stack (`hyper 1.x`). Bumped to the patched
`0.4.17`.
- `h2 0.3.27` — pulled in **only** by the internal `linkchecker` dev
tool, via `linkcheck → reqwest 0.11 → hyper 0.14 → h2 0.3`. The `h2 0.3`
series has **no fix** (patched only in `>= 0.4.16`).

As #5364 anticipated, the fix is to move our `linkcheck` fork off
`reqwest 0.11`. `ankitects/linkcheck` was bumped to `reqwest 0.12` /
`http 1` (no source changes required — the APIs used are unchanged), and
this PR pins `linkcheck` to the new `anchors` tip. That removes the old
subtree at the root instead of suppressing the advisory via a
`deny.toml` ignore (which would also force an explicit license
allow-list on the project, since cargo-deny switches to strict license
checking once a config file exists).

## Steps to reproduce (required, use N/A if not applicable)

1. Check out `main` at any recent commit.
2. Run `cargo deny check` (or push and let `check (linux)` run in CI).
3. It fails with `error[vulnerability]: h2 unbounded empty DATA frames`
(RUSTSEC-2026-0258) for both `h2 0.3.27` and `h2 0.4.12`.

## How to test (required)

### Details

- `cargo deny check` → `advisories ok, bans ok, licenses ok, sources
ok`.
- `cargo build -p linkchecker` succeeds against the updated `linkcheck`.
- Full `just check` (`./ninja check`) passes, including
`check:minilints` (`cargo/licenses.json` regenerated for the updated
tree).

## Before / after behavior

**Before**: `cargo deny check` fails on RUSTSEC-2026-0258 (two `h2`
copies), breaking
CI.
**After**: `h2` resolves to a single patched `0.4.17`; the `reqwest
0.11` subtree is gone; cargo-deny is clean.

## Risk / compatibility / migration

Low. Dependency-only change. `linkcheck` (used only by the `linkchecker`
test tool) now builds on `reqwest 0.12` / `http 1`, which the rest of
the workspace already uses; `Cargo.lock` shrinks as the duplicate old
subtree is dropped.
2026-08-20 14:39:51 -03:00
Fernando Lins
5367eec660 docs: document dependabot update process (#5370)
## Linked issue

Closes #5368

## Summary / motivation

Document how maintainers should handle Dependabot PRs.
2026-08-20 13:40:29 -03:00
Abdo
2245e0d4a5 chore: set strict_optional = True for editor_legacy.py (#5367)
Fix a small type checking regression introduced by #4029 that I
noticed while checking #5365
2026-08-19 15:55:52 +03:00
Abdo
5f3a102f05 fix: Ensure editor is initialized before triggering browser hooks (#5348)
## Linked issue

https://community.ankihub.net/t/error/607154

## Summary

The browser adds its hooks (setupHooks) before the editor is initialized
(setupEditor). The operation_did_execute hook's handler assumes the
editor is already initialized and tries to access it, triggering an
AttributeError in rare cases.
Moving the setupHooks() call down one line should guard against this
(assuming it's not the case of some add-on patching `Browser.editor`).

## Steps to reproduce

No reliable way to reproduce it, but I managed to trigger it once by
installing the following add-ons and clicking the AnkiHub sync button
(or just calling `aqt.mw.reset()`):

```
1322529746 1102281552 1374772155 1556734708 1709973686 1730200873 1746010116 1771074083 1788670778 1810938259 2040501954 24411424 300884351 374005964 46611790 594329229 613684242 738807903
```
2026-08-18 12:53:46 +03:00
Abdo
166ba47201 Add missing dependencies to ninja's cog actions (#5341)
The `check:format:cog` and `format:cog` Ninja actions did not rerun
after changes to docs/, docs-site/. This fixes it.

---------

Co-authored-by: Fernando Lins <1887601+fernandolins@users.noreply.github.com>
2026-08-18 12:51:26 +03:00
GithubAnon0000
bfaf62d4dd fix: set webview font size to system font size in preferences menu (#5174)
## Linked issue (required)

Fixes ankitects/anki#5173

## Summary / motivation (required)

This PR removed a hard coded font size value. That way the font size
changes dynamically, which is also important for A11Y. The issue had
been initally introduced in
[https://github.com/ankitects/anki/pull/5057](<https://github.com/ankitects/anki/pull/5057>).
@Luc-Mcgrady and @focushover, pinging you FYI.

## Steps to reproduce (required, use N/A if not applicable)

1. Open preferences.
2. Go to experiments tab.
3. See that font size is different from other tabs.

## How to test (required)

Tested with `./run --safemode`, then visual check.

### Checklist (minimum)

- [X] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

It has also been successfully tested against changes in "user interface
size" preference in Anki.

## Before / after behavior (optional)

Before: inconsistent font size  <br>After: consistent font size

## Risk / compatibility / migration (optional)

None.

## UI evidence (required for visual changes; otherwise N/A)

With this PR:

<img
src="https://github.com/user-attachments/assets/cad67197-0793-4392-8b7e-a9d1f580c29b
" alt="A" width="951" data-linear-height="905" />

<img
src="https://github.com/user-attachments/assets/55144931-3b70-45c6-8616-2d0966dbe397
" alt="B" width="951" data-linear-height="905" />

## Scope

- [X] This PR is focused on one change (no unrelated edits).

---------

Co-authored-by: Luc Mcgrady <lucmcgrady@gmail.com>
2026-08-17 14:42:18 +01:00
dependabot[bot]
967aa0d578 chore(deps): bump tar from 7.5.7 to 7.5.22 (#5239)
Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.7 to 7.5.21.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0cd9cc3c58"><code>0cd9cc3</code></a>
7.5.21</li>
<li><a
href="631ae59121"><code>631ae59</code></a>
list: prevent unbounded recursion</li>
<li><a
href="ebbb720941"><code>ebbb720</code></a>
7.5.20</li>
<li><a
href="2f271963a7"><code>2f27196</code></a>
fix: fully disable and dispose of unzip when aborting parser</li>
<li><a
href="be440da64e"><code>be440da</code></a>
7.5.19</li>
<li><a
href="2812e93386"><code>2812e93</code></a>
add maxDecompressionRatio guard against explosive decompression</li>
<li><a
href="9ecd4d2956"><code>9ecd4d2</code></a>
7.5.18</li>
<li><a
href="9e78bf058b"><code>9e78bf0</code></a>
refuse to let header size be less than 0</li>
<li><a
href="e02a4e9e01"><code>e02a4e9</code></a>
pax: parse values according to known types</li>
<li><a
href="9cbdb31e5e"><code>9cbdb31</code></a>
7.5.17</li>
<li>Additional commits viewable in <a
href="https://github.com/isaacs/node-tar/compare/v7.5.7...v7.5.21">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~isaacs">isaacs</a>, a new releaser for tar
since your current version.</p>
</details>
<details>
<summary>Install script changes</summary>
<p>This version adds <code>prepare</code> script that runs during
installation. Review the package contents before updating.</p>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=tar&package-manager=npm_and_yarn&previous-version=7.5.7&new-version=7.5.21)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/ankitects/anki/network/alerts).

</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Fernando Lins <1887601+fernandolins@users.noreply.github.com>
2026-08-14 18:04:12 -03:00
dependabot[bot]
74836724b8 chore(deps): bump vitest from 3.2.4 to 3.2.6 (#4973)
Bumps
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)
from 3.2.4 to 3.2.6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases">vitest's
releases</a>.</em></p>
<blockquote>
<h2>v3.2.6</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li>Pin last supported vite-node version  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> <a
href="https://github.com/vitest-dev/vitest/commit/16f120d05"><!-- raw
HTML omitted -->(16f12)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v3.2.5...v3.2.6">View
changes on GitHub</a></h5>
<h2>v3.2.5</h2>
<h3>   🚀 Features</h3>
<ul>
<li><strong>api</strong>: Add <code>allowWrite</code> and
<code>allowExec</code> options to <code>api</code> [backport to v3]  - 
by <a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> and
<strong>Codex</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10445">vitest-dev/vitest#10445</a>
<a href="https://github.com/vitest-dev/vitest/commit/af88b1f5d"><!-- raw
HTML omitted -->(af88b)<!-- raw HTML omitted --></a></li>
</ul>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>browser</strong>: Disable client <code>cdp</code> API when
<code>allowWrite/allowExec: false</code> [backport to v3]  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> and
<strong>Codex</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10456">vitest-dev/vitest#10456</a>
<a href="https://github.com/vitest-dev/vitest/commit/385a1aefd"><!-- raw
HTML omitted -->(385a1)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v3.2.4...v3.2.5">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="b6d56f8171"><code>b6d56f8</code></a>
chore: release v3.2.6</li>
<li><a
href="16f120d058"><code>16f120d</code></a>
fix: pin last supported vite-node version</li>
<li><a
href="2cbad0a923"><code>2cbad0a</code></a>
chore: release v3.2.5</li>
<li><a
href="385a1aefd4"><code>385a1ae</code></a>
fix(browser): disable client <code>cdp</code> API when
<code>allowWrite/allowExec: false</code> [ba...</li>
<li><a
href="af88b1f5d8"><code>af88b1f</code></a>
feat(api): add <code>allowWrite</code> and <code>allowExec</code>
options to <code>api</code> [backport to v3]...</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v3.2.6/packages/vitest">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for vitest since your current version.</p>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=vitest&package-manager=npm_and_yarn&previous-version=3.2.4&new-version=3.2.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

You can trigger a rebase of this PR by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/ankitects/anki/network/alerts).

</details>

> **Note**
> Automatic rebases have been disabled on this pull request as it has
been open for over 30 days.

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Fernando Lins <1887601+fernandolins@users.noreply.github.com>
2026-08-14 17:42:01 -03:00
Abdo
67e853ce6b chore: Configure mypy extension for VS Code (#5317)
## Linked issue

Closes #5304

## Summary

This configures the official VS Code extension for mypy to run in daemon
mode.

## How to test

- Install the `ms-python.mypy-type-checker` extension and **switch to
the pre-release version** (This is important for daemon mode to work
according to my tests).
- Copy .vscode.dist/settings.json to .vscode/
- Restart the MyPy server using the "MyPy: Restart server" command.
- Edit any Python code to add a typing error and confirm the error is
visually reported. (Note: initial mypy run might take a few seconds).



<img width="1305" height="361" alt="image"
src="https://github.com/user-attachments/assets/e8f431b0-b2ae-483d-b305-cf19c9dd013d"
/>
2026-08-14 22:02:00 +03:00
Ian
e16fc17b3c fix: don't let ftl string copy/move land new strings in deprecated sections (#5332)
## Linked issue (required)

Closes #5177 

## Summary / motivation (required)

See #5177, as well as
https://github.com/ankitects/anki-core-i18n/pull/18

## Steps to reproduce (required, use N/A if not applicable)

N/A

## How to test (required)

1. Run the newly added tests (`cargo test -p ftl string::tests`)
2. Run the following:

```sh
mkdir -p /tmp/ftl-demo/en
cat > /tmp/ftl-demo/en/errors.ftl <<'EOF'
errors-collection-too-new = This collection requires a newer version of Anki to open.

## NO NEED TO TRANSLATE. This text is no longer used by Anki, and will be removed in the future.

errors-invalid-input-empty = Invalid input.
EOF

cargo run -p ftl -- string copy /tmp/ftl-demo /tmp/ftl-demo errors-collection-too-new errors-demo-key

cat /tmp/ftl-demo/en/errors.ftl
```

Expected output — the new key lands above the deprecated section, not
inside it.

### Checklist (minimum)

- [X] I ran `./ninja check` or an equivalent relevant check locally.
- [X] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

See "how to test"

## Before / after behavior (optional)

BEFORE: Strings were appended to the file, sometimes landing them in the
deprecated section.

AFTER: Strings are added after the initial global comments if they
exist, ensuring new strings do not land in a deprecated section.

## Risk / compatibility / migration (optional)

Currently the deprecated section markers are all over the place;
suggesting a one-off followup PR in the i18n repo to clean them, then
another change to lint for the standardized deprecation titling to
prevent drift, and/or some other way of keeping that section highly
specific.

## UI evidence (required for visual changes; otherwise N/A)

N/A

## Scope

- [X] This PR is focused on one change (no unrelated edits).
2026-08-14 11:45:50 -05:00
Abdo
46df7b2916 fix: new editor not playing pasted/dropped audio (#5329)
## Linked issue

A small follow-up to #5320

## Summary

#5320 fixed autoplay for attached files and recordings but missed
pasted/dropped files.

## How to test

Paste and drag & drop of audio files is currently broken (#5203) so
there's no easy way to test this right now.
2026-08-14 18:38:50 +03:00
Luc Mcgrady
29ffaaed47 fix: missing issue bot does not allow url in linked issues (#5287)
[Example](https://regex101.com/?regex=%5Cb%28closes%7Cclose%7Cclosed%7Cfixes%7Cfix%7Cfixed%7Cresolves%7Cresolve%7Cresolved%7Crefs%7Cref%7Creferences%29%3A%3F%5Cs%2B%28%3F%3A%28%3F%3A%5Ba-zA-Z0-9_.-%5D%2B%5C%2F%5Ba-zA-Z0-9_.-%5D%2B%29%3F%23%5Cd%2B%7Chttps%3F%3A%5C%2F%5C%2Fgithub%5C.com%5C%2F%5Ba-zA-Z0-9_.-%5D%2B%5C%2F%5Ba-zA-Z0-9_.-%5D%2B%5C%2Fissues%5C%2F%5Cd%2B%29&testString=closes+https%3A%2F%2Fgithub.com%2Fankitects%2Fanki%2Fissues%2F5285%0A&flags=gm&flavor=pcre2&delimiter=%2F)

closes #5286
2026-08-14 11:52:43 +01:00
llama
29b9970157 fix: fallback to DataTransfer.files for audio (#5337)
## Linked issue (required)

Refs: #5203

## Summary / motivation (required)

The new editor falls back to DataTransfer.files for images but not for
audio, which this pr fixes

## Steps to reproduce (required, use N/A if not applicable)

See linked issue

## How to test (required)

Copypasting/drag-dropping an audio file into a field in the new editor

### Checklist (minimum)

- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.

## Scope

- [x] This PR is focused on one change (no unrelated edits).
2026-08-14 10:20:57 +03:00
Luc Mcgrady
f086fe89fb feat: update memory state when card info opened. (#5326)
closes #3521

Previously when a card was moved between decks, it would be possible
that the FSRS data could be cleared from the card so that it wouldn't
display when the card stats were shown.

With this pr the memory state is attempted to be calculated when the
stats screen is opened if the state doesn't already exist.

## Testing steps

1. Create and review a card
2. Move it to a different deck
3. This card will now lack a memory state
4. Open the card stats
5. You will see the memory state there.

## Drawbacks
Notably means that the cards in the deck browser will still be missing
the memory state related columns after they're moved. It also introduces
an operation that modifies the card to the card_info function which
seems like a weird thing to do, although a similar thing is also done
when the user try's to simulate cards which are missing memory states.

This changed is predicated on what Dae said in the aformentioned issue:

> Deck changing is a common operation, and we don't want expensive
calculations every time it happens.
>
> Keeping the old memory state would require some extra flag so we know
to discard it at study time. And it would mean your stats are still
wrong - they'd just contain stale data, instead of missing data.

However with the memory state speed improvements introduced in #4335.
Maybe it is worth calculating the state when the cards are moved decks
rather than in this way?
2026-08-14 00:35:24 +01:00
Abdo
3190c34d18 docs: Update e2e docs (#5331)
This moves docs/e2e-testing.md to docs-site/developers/e2e-testing.mdx
and updates some notes about the editor/congrats page.
2026-08-13 20:17:37 +03:00
roostwp07
59ce8556b8 docs: document import_anki_package and export_anki_package (closes #5307) (#5328)
Closes #5307

## Summary
- Documents `import_anki_package()` and `export_anki_package()` in
`the-anki-module.mdx`

---------

Co-authored-by: Abdo <abdo@abdnh.net>
2026-08-13 16:55:54 +03:00
Jakson Souza
3a5d285821 fix: play audio immediately when attached in the editor (#5320)
## Linked issue (required)

Closes #5321

## Summary / motivation (required)

In the old Qt-based editor, attaching an audio file (paperclip button or
the mic recording button) played the file immediately, before the card
was saved. This was handled by `Editor.fnameToLink()` in
`qt/aqt/editor.py`, which called `av_player.play_file_with_caller()`
right after building the `[sound:...]` tag.

That method was removed in 4dd402334 ("Remove legacy editor code") once
the editor moved to the Svelte/TS implementation. Its replacement,
`filenameToLink()` in
`ts/routes/editor/rich-text-input/data-transfer.ts`, only builds the
`[sound:...]` string and never carried the playback call forward. So
today, attaching audio inserts the tag silently and you only hear it
after saving and reopening the card (or opening the Cards preview).

This restores the immediate playback, using the same `av_player`
mechanism the rest of the app uses (so it respects the configured audio
backend/volume), by:

- Adding a `PlayFile` RPC to `FrontendService` in `frontend.proto`,
following the same pattern as the existing Python-only
`RecordAudio`/`OpenMedia` RPCs (no Rust implementation needed,
`FrontendService` is filtered out of Rust codegen in
`rslib/rust_interface.rs`).
- Implementing `play_file()` in `qt/aqt/mediasrv.py`. It resolves the
path relative to the media folder the same way
`open_media`/`show_in_media_folder` do, then plays it on the main
thread. When the active window is the editor, it uses
`av_player.play_file_with_caller(path, window.editor.editorMode)`
instead of a plain `play_file()`, the same pattern already used by
`open_cards_dialog`/`open_fields_dialog` in the same file. This ties
playback to `Editor.cleanup()`'s existing
`av_player.stop_and_clear_queue_if_caller(self.editorMode)` call, so the
sound is stopped if the editor closes mid-playback.
- Calling the new `playFile()` binding from `attachPath()` in
`TemplateButtons.svelte` right after the media is inserted, only when
the attached file is audio (added an `isAudio()` helper next to
`filenameToLink()`, reusing the existing `audioSuffixes` list).

## Steps to reproduce (required, use N/A if not applicable)

1. Open the Add or Edit dialog for a note.
2. Click the paperclip (attach) button in the field toolbar.
3. Pick an audio file.
4. Notice nothing plays. The `[sound:...]` tag is inserted silently, and
you only hear the audio after saving/reviewing or opening the Cards
preview.

## How to test (required)

### Checklist (minimum)

- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [x] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

Ran `just check` locally, everything passed, including a new vitest
covering `isAudio()` in `data-transfer.test.ts`. Manually verified in
`just run`: opened Add dialog, attached an audio file via the paperclip
button and it plays as soon as it's inserted into the field, before
saving. Also tested the mic recording button (F5), which goes through
the same `attachPath()` function; recording and playback both work as
expected.

## Before / after behavior (optional)

Before: attaching audio via the paperclip inserts the `[sound:...]` tag
silently.
After: the audio plays immediately after being inserted, matching the
old Qt editor's behavior.

## Risk / compatibility / migration (optional)

Low risk. New RPC is additive (no changes to existing `FrontendService`
methods), and playback only triggers for files already classified as
audio/video by the existing suffix list used elsewhere in the same file.

## UI evidence (required for visual changes; otherwise N/A)

N/A, behavior-only change (audio playback), nothing visual to show.

## Scope

- [x] This PR is focused on one change (no unrelated edits).
2026-08-13 13:50:58 +03:00
Luc Mcgrady
5b1a2c322e fix: Hide ease when fsrs is enabled but there is no memory state (#5277)
closes #5285 

I noticed this was still causing some confusion
https://forums.ankiweb.net/t/ignore-cards-reviewed-before-question/70596?u=a_blokee

This adds an extra check to see if "desired retention" is set before
showing the ease value. It should prevent SM2 values from being shown
when FSRS is enabled.
2026-08-12 13:11:56 +01:00
Abdo
3c9b1daf35 CI: Apply a consistent Cargo profile (#5133)
## Linked issue

Related:
https://github.com/ankitects/anki/pull/5102#issuecomment-4923922894

## Summary / motivation


This adds a new Cargo profile (`ci`) for use in all Rust build commands
on CI. The goal is to reduce unnecessary recompilation of the same
crates in dev/release profiles.

## Steps to reproduce (before)

View the logs of the last CI run on main and notice that some crates are
getting compiled with the `release` profile, e.g. compilation ends with
"Finished `release` profile [optimized]".

## How to test (after)

View the logs of the last CI run in this PR and confirm all Rust
compilation commands end with "Finished `ci` profile [unoptimized]",
indicating that only a single profile is being used.

### Checklist (minimum)

- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.

## Scope

- [x] This PR is focused on one change (no unrelated edits).
2026-08-12 10:17:29 +03:00
llama
054ce44868 chore: bump rust toolchain to 1.97.1 (#5316)
## Linked issue (required)

Closes #5308 

### Checklist (minimum)

- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.

## Scope

- [x] This PR is focused on one change (no unrelated edits).

---------

Co-authored-by: Abdo <abdo@abdnh.net>
2026-08-11 14:06:50 +03:00
Christos Longros
2d88e386dc build: portability fixes for FreeBSD (#5300)
Two build fixes found while getting the build working on FreeBSD. 

1. **Remove hardcoded `#!/bin/bash` paths and use /usr/bin/env instead
/**
2. **env_remove("YARN_BINARY")**

Tested on FreeBSD 16.0-CURRENT amd64.

A second series adds FreeBSD support with `platform` variants,
environment overrides, PyQt6 handling and docs.

Closes #5301
2026-08-11 13:13:56 +03:00
Abdo
abd339a59f fix: minilints exclusion for docs changes is not working (#5315)
## Linked issue

Follow-up fixes to #5267

## Summary

#5267 didn't work reliably as can be seen in #5158 due to two issues:
1. The `files` option is not set, which made `any_changed` always
evaluate to `true`.
2. The `*.md` and `*.mdx` patterns only matched root files.


## How to test

Hard to verify locally, but here's a POC written by Claude. Save as
`micromatch-files-ignore-poc.cjs` in the root directory and run using:
`npm install micromatch && node micromatch-files-ignore-poc.cjs`.

<details>

<summary>POC</summary>

```js
// POC: tj-actions/changed-files' `files_ignore`-only config never filters
// anything, because it hands micromatch an array of ONLY negated patterns.
//
// Run with:
//   node micromatch-files-ignore-poc.cjs
//
// Requires the `micromatch` package to be resolvable (the version actually
// used by tj-actions/changed-files@v47.0.6 is 4.0.8). If you don't have it
// globally, run this from inside a project that depends on it (e.g. the
// anki repo root), or `npm install micromatch` next to this file first.

const mm = require("micromatch");

function assert(cond, msg) {
  if (!cond) {
    throw new Error("FAILED: " + msg);
  }
  console.log("ok   - " + msg);
}

// This mirrors ci.yml's `Check for non-documentation changes` step, which
// sets only `files_ignore` (no `files`), and the 14 files actually changed
// in https://github.com/ankitects/anki/pull/5158 ("docs: fix typos").
const changedFiles = [
  "docs-site/addons/support.mdx",
  "docs-site/developers/development.mdx",
  "docs/development.md",
  "rslib/backend/lib.rs", // stand-in for a real, non-doc source file
];

// Copied verbatim from .github/workflows/ci.yml's files_ignore list.
const filesIgnoreOnly = [
  "!**.md",
  "!**.mdx",
  "!docs/**/*.png",
  "!docs/**/*.svg",
  "!docs-site/**/*.png",
  "!docs-site/**/*.jpg",
  "!docs-site/**/*.svg",
  "!docs-site/**/*.mp4",
];

// This is the exact call tj-actions/changed-files makes internally
// (getFilteredChangedFiles in dist/index.js) to decide which changed files
// "count" for the `any_changed` output.
const matchOpts = { dot: true, windows: false, noext: true };

console.log("--- Bug 1: files_ignore with no positive `files` pattern ---");
const filteredIgnoreOnly = mm(changedFiles, filesIgnoreOnly, matchOpts);
console.log("input files:   ", changedFiles);
console.log("filesIgnore:   ", filesIgnoreOnly);
console.log("matched (kept):", filteredIgnoreOnly);
assert(
  filteredIgnoreOnly.length === changedFiles.length,
  "an ignore-only pattern array matches EVERY file, including the ones " +
  "it was supposed to exclude (docs/*.md, docs-site/*.mdx) -- any_changed " +
  "is always 'true'",
);

console.log();
console.log("--- Bug 2: adding a positive base, but keeping bare `**.md` ---");
const filesWithBadGlobstar = [
  "**", // positive base pattern, as tj-actions' own README recommends pairing
  ...filesIgnoreOnly,
];
const filteredBadGlobstar = mm(changedFiles, filesWithBadGlobstar, matchOpts);
console.log("patterns:      ", filesWithBadGlobstar);
console.log("matched (kept):", filteredBadGlobstar);
assert(
  filteredBadGlobstar.includes("docs/development.md"),
  "bare `**.md` (globstar with no following '/') fails to exclude a " +
  "nested path once it's negated inside an array match -- " +
  "'docs/development.md' incorrectly survives",
);

console.log();
console.log("--- Fix: positive `**` base + `**/*.md` (slash before the star) ---");
const filesFixed = [
  "**",
  "!**/*.md",
  "!**/*.mdx",
  "!docs/**/*.png",
  "!docs/**/*.svg",
  "!docs-site/**/*.png",
  "!docs-site/**/*.jpg",
  "!docs-site/**/*.svg",
  "!docs-site/**/*.mp4",
];
const filteredFixed = mm(changedFiles, filesFixed, matchOpts);
console.log("patterns:      ", filesFixed);
console.log("matched (kept):", filteredFixed);
assert(
  filteredFixed.length === 1 && filteredFixed[0] === "rslib/backend/lib.rs",
  "with a positive `**` base and `**/*.ext` patterns, only the real " +
  "non-doc file survives -- any_changed correctly becomes 'false' for " +
  "docs-only PRs like #5158",
);

console.log();
console.log("All assertions passed: files_ignore-only config in ci.yml never");
console.log("filters anything, so minilints can never actually be skipped.");

```

</details>
2026-08-10 22:28:54 +03:00
znmz
625eefdd42 docs: fix typos (#5158)
closes #5160

## Summary / motivation (required)

This PR fixes typos, misspelings and (in one place) formatting in files
under `docs-site/` and one file under `docs/`.

I've found these using `codespell` and `typos` CLI utilities (+ spotted
a few myself).

## Scope

- [x] This PR is focused on one change (no unrelated edits).

***

Note: I've installed mdbook following the updated installation steps
(a4d6fb39a7),
but now i face a new error:
```rust
$ mdbook build
2026-07-15 14:48:28 [ERROR] (mdbook::utils): Error: Couldn't open SUMMARY.md in "/home/user/anki-source/docs-site/src" directory
2026-07-15 14:48:28 [ERROR] (mdbook::utils): 	Caused By: No such file or directory (os error 2)
```
I don't have time right now to figure out what is the difference between
`ankitects/anki-manual` and `ankitects/anki` directory structure and how
to merge them to make the mdbook build, but *I think that my changes are
trivial enough* that no thorough testing is needed.

Co-authored-by: Abdo <abdo@abdnh.net>
2026-08-10 16:08:17 -03:00
Luc Mcgrady
d6c108c0c7 test: fix_card_properties_last_review_time (#5146)
closes #5148
2026-08-10 16:00:27 -03:00
Luc Mcgrady
0fba26bf22 test: simulate_workload_varies (#5150)
closes #5149

`simulate_workload` spawns ~30 threads so might be a little expensive
for a test in that regard. It seems to work ok though.

---------

Co-authored-by: Fernando Lins <fernandolins@users.noreply.github.com>
2026-08-10 15:59:43 -03:00
roostwp07
389829ed58 fix(coverage): use cargo-nextest for Rust coverage tests (closes #5162) (#5169)
Closes #5162

Pass `nextest` to `cargo-llvm-cov` so Rust coverage tests run with
`cargo-nextest`.

---------

Co-authored-by: Fernando Lins <1887601+fernandolins@users.noreply.github.com>
2026-08-10 15:37:24 -03:00
Abdo
0a6ea5d735 Reapply: Correct "1 tags" to "1 tag" (#4967) (#5305)
This reapplies #4967, which was accidentally reverted in #4029:
https://github.com/ankitects/anki/pull/4967#issuecomment-5221940372

Co-authored-by: Arthur Milchior <arthur@milchior.fr>
2026-08-10 21:28:09 +03:00
roostwp07
ade1066690 chore: replace prepare-release workflow with local script (closes #5273) (#5288)
Closes #5273

## Summary
- Replaces `.github/workflows/prepare-release.yml` with
`.github/scripts/prepare_release.py`, a script run locally by the
maintainer
- Removes the need for the `RELEASE_TOKEN` personal access token
- Script performs the same steps: version validation, CI status check,
duplicate tag/release check, translation sync, and version commit + push

---------

Co-authored-by: Abdo <abdo@abdnh.net>
2026-08-10 21:16:53 +03:00
Peter Szilvasi
8bf7d91a50 chore: exclude docs contributions from BSD license check (#5267)
<!--
Title (for the Pull Request title field at the top):
Use a short prefix so the change type is obvious. You do not need to
repeat it in the body below.

Examples:
- fix: — bugfix
- feat: — feature
- refactor: — internal change without user-facing feature
- docs: — documentation only
- chore: — tooling, CI, deps, build housekeeping
- test: — tests only
-->

## Linked issue (required)

Fixes #5265
<!-- Fixes #123 / Closes #123 / Refs #123 -->

## Summary / motivation (required)

The document only changes are under the CC BY-SA 4 license, therefore no
need to enforce BSD 3 license contribution agreement.
<!-- What this PR does and why. For larger changes, add enough context
for reviewers. -->

## Steps to reproduce (required, use N/A if not applicable)

N/A

<!-- Steps to reproduce: how to trigger the bug in the broken state (the
"before").
 - Mainly for bugfixes;
    - For bugs: numbered steps before the fix. For non-bugs: write N/A.
 - use N/A for features, refactors, docs, chore, etc.
-->

## How to test (required)

End-to-end local GH action:
1. Install the [act](https://github.com/nektos/act) tool to run GH
action locally
2. Install ubuntu container: `podman pull
ghcr.io/catthehacker/ubuntu:act-24.04`
3. Create a clean working tree from this branch: `git checkout -b
test-docs`
4. Add a doc only change: `echo x >> README.md && git add README.md`
5. Commit the changes: `git -c user.email=nobody@example.com commit -m
"docs only"`
6. Run the minilints step: `act -j minilints --container-daemon-socket
unix:///tmp/podman.sock -P
ubuntu-24.04=ghcr.io/catthehacker/ubuntu:act-24.04`
7. The log should contain the "Run minilints" step.

<!--- How to test: how you verified the change (checks, unit tests,
manual steps, edge cases — the "after" or general validation). --->

### Checklist (minimum)

- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [x] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

<!-- Commands, manual steps, edge cases, and what you observed -->

## Before / after behavior (optional)

Before: The documentation only changes trigger the contribution
agreement check.
After: If the changes are documentation only, it workflow skips the
contribution check.
<!-- For bugfixes: behavior before vs after. For other types: N/A or a
short note. -->

## Risk / compatibility / migration (optional)

N/A
<!-- Breaking changes, rollout notes, or N/A for small / low-risk PRs
-->

## UI evidence (required for visual changes; otherwise N/A)

N/A
<!-- Screenshot or short video -->

## Scope

- [x] This PR is focused on one change (no unrelated edits).
2026-08-10 21:07:35 +03:00
Abdo
cec0e2b705 Update VS Code's settings.json (#5303)
## Linked issue

Fixes #5302

## Summary

This updates the VS Code settings:
- Set Ruff as a Python formatter (`python.formatting.provider` is no
longer used).
- Replace references to the old `.bazel` with `out`.
- Remove unused `python.linting.mypyEnabled` (mypy is no longer part of
the base Python extension).
- Add `unifiedjs.vscode-mdx` to recommended extensions for MDX
highlighting.
- Update `rust-analyzer.files.excludeDirs` to
`rust-analyzer.files.exclude`.
- Set `python-envs.workspaceSearchPaths` to help the Python Environments
extension detect `out/pyenv`.

## How to test

Copy .vscode.dist/settings.json to .vscode/
2026-08-10 20:59:29 +03:00
Abdo
d407e47556 chore: Update Python test coverage threshold (#5299)
Decrease Python test coverage threshold after code removal in #5153

CI failure:
https://github.com/ankitects/anki/actions/runs/31246523150/job/93075937350
2026-08-10 14:47:59 -03:00
Fernando Lins
3fb9c41597 chore(ci): reduce dependabot noise with quarterly schedule and major grouping (#5280)
## What

- Change dependabot `interval` from `monthly` to `quarterly` for all
ecosystems (Cargo, npm, Python, GitHub Actions)
- Add separate groups for major bumps (`rust-major`, `npm-major`,
`python-major`) so they arrive as a single grouped PR instead of
individual ones
- Add `semver-major-days: 30` cooldown for major bumps on all versioned
ecosystems

## Why

Version update PRs were accumulating faster than the team could review
them. Two issues were causing this:

1. Minor/patch grouped PRs were opened monthly. Try moving it to
quarterly may match the actual review cadence better
2. Major bumps fell outside the minor/patch group and opened as
individual PRs per package, adding noise

Security updates are unaffected: they still open immediately regardless
of the schedule, as they bypass the interval setting by design.
2026-08-10 14:23:34 -03:00
Christos Longros
d4fdbefceb refactor: remove legacy importer and exporter (#5153)
## Linked issue (required)

Closes #5167

## Motivation

The `.apkg` media uses `os.path.commonprefix`, which compares
characters, not path components. A media filename resolving to a
*sibling* directory that shares the media folder's name prefix passes
the check, so a malicious `.apkg` can write outside `collection.media`
(path traversal / arbitrary file write).

A second commit removes the legacy importer entirely. The legacy import
option was removed in #3536, leaving pylib/anki/importing,
qt/aqt/importing.py and their dialog forms unreachable.

The third commit removes the legacy exporter and adds a realpath check
instead of the commonprefix.

## Steps to reproduce

1. Make an `.apkg` whose media maps a file into a sibling directory
whose name begins with the media folder's name.
2. Import it.
3. Before: written outside `collection.media`. After: "Invalid file".

## Testing performed
Tested by importing .apkg and .csv decks via File > Import on the main
branch and on the PR branch.
Cards import completes without problems.
Also tested a deck and collection export with support to older Anki
versions enabled. It works fine.
2026-08-08 10:35:52 +03:00
Abdo
de738fa15f fix: Improve GitHub API error reporting (#5295)
## Linked issue

Closes #5293

## Summary / motivation

GitHub API errors were handled by the `From<&reqwest::Error>` impl,
which is intended for AnkiWeb. This adds a basic error handler for
GitHub API requests (showing the raw error messages for most errors).

## Steps to reproduce

The issue was showing when GitHub rate-limits our requests - `403
Forbidden` is returned in that case, and the default error handler
interprets that as an AnkiWeb authentication error and displays "Email
or password was incorrect; please try again.".

See
https://docs.github.com/en/rest/using-the-rest-api/troubleshooting-the-rest-api?apiVersion=2026-03-10#rate-limit-errors
2026-08-07 18:02:35 +03:00
Abdo
d9605e2781 fix: Update list of RTL languages in SvelteKit pages (#5274)
## Linked issue

Noted in
https://github.com/ankitects/anki/pull/5105#pullrequestreview-4861060987

## Summary

RTL languages are tracked in two separate places
(pylib/anki/lang.py:is_rtl and ts/lib/tslib/i18n/utils.ts:direction) but
they are out of sync.

## Steps to reproduce (before)

- Run with Uyghur set as language: `./run -l ug`.
- Open the Deck Options screen and notice the page's direction is
left-to-right.

## How to test (after)

Confirm the Deck Options screen is displayed right-to-left for Uyghur.

### Checklist (minimum)

- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [x] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

A better solution is to keep a single list in the backend or detects the
directionality of the locale name (see [example in
AnkiDroid](eb22e1e6ad/AnkiDroid/src/main/java/com/ichi2/anki/LanguageUtils.kt (L47))).
Both requires moving anki.lang.langs to the backend, which I don't think
is worth the effort.

## UI evidence

### Before
<img width="1406" height="654" alt="image"
src="https://github.com/user-attachments/assets/e9e8aa75-e6b1-4a27-85d5-cfda16c16314"
/>

### After
<img width="1425" height="777" alt="image"
src="https://github.com/user-attachments/assets/48994c54-8209-4c6b-821e-c734c85e96e2"
/>

## Scope

- [x] This PR is focused on one change (no unrelated edits).
2026-08-07 17:47:38 +03:00
Andreas
7c13bc4692 fix: Browse Add-ons URL (#5290)
## Linked issue (required)

Fixes #5289

## Summary / motivation (required)

Updates the Browse Add-ons link to use the current `/shared/addons` URL
directly instead of the legacy `/shared/addons/2.1` URL, which redirects
to it.

## Steps to reproduce (required, use N/A if not applicable)

1. Open Tools → Add-ons.
2. Click Get Add-ons…
3. Click Browse Add-ons.
4. Observe that `/shared/addons/2.1` is opened and redirects to
   `/shared/addons`.

## How to test (required)

### Checklist (minimum)

- [ ] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

Manually verified that `/shared/addons/2.1` redirects to
`/shared/addons`,
and that `/shared/addons` loads directly. No local build or automated
checks
were run; the change was made using GitHub's web editor.

## Before / after behavior (optional)

Before: Browse Add-ons opens the legacy `/shared/addons/2.1` URL and
relies
on a redirect.

After: Browse Add-ons opens `/shared/addons` directly.

## Risk / compatibility / migration (optional)

N/A. This is a one-line URL change.

## UI evidence (required for visual changes; otherwise N/A)

N/A

## Scope

- [x] This PR is focused on one change (no unrelated edits).
2026-08-07 11:30:12 -03:00
Abdo
17357d0fd0 Clarify docs license (#5292)
Clarify license of docs-site/

See #5265
2026-08-07 15:57:00 +03:00
user1823
95c4e8b9a7 Docs: Add tip to disable "check on save" in Rust analyzer on low-end machines (#4489)
Anki's build scripts (ninja) set CARGO_TARGET_DIR for their own
execution. But, when running cargo commands directly (like cargo check),
those commands don't inherit that environment variable and use the
default target/ directory instead, leading to duplicate builds.

After this change, all cargo commands (check, build, test, etc.) will
use the same cache, saving storage space.
2026-08-07 06:05:36 +08:00
krMaynard
2a3f47a45f fix: treat $ literally in non-regex find&replace replacements (#5216)
## Linked issue (required)

Fixes #5215

## Summary / motivation (required)

For a non-regex Find & Replace, the search term is escaped via
`regex::escape` but the replacement was passed through unchanged. The
regex engine interprets `$` in a replacement as a capture-group
reference (e.g. `$1`, `$name`, `${n}`), so a literal replacement such as
`$5` expanded to the (empty) capture group 5, silently dropping the text
instead of inserting `$5`.

The fix escapes `$` to `$$` for non-regex replacements so it is inserted
verbatim.

## Steps to reproduce (required, use N/A if not applicable)

1. Select notes and open Find & Replace with "Treat input as regular
expression" **off**.
2. Replace some text with a literal replacement containing `$`, e.g.
`$5`.
3. Observe the `$5` is dropped/mangled instead of inserted literally.

## How to test (required)

### Checklist (minimum)

- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [x] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

Adds a regression test for literal `$` in non-regex replacements. Full
CI (`check` on Linux/macOS/Windows, `format`, `minilints`) run against
this exact commit on my fork:
https://github.com/krMaynard/anki-fork/actions/runs/30287938613 — all
green except the "Upload SARIF results for complexipy" step on the Linux
job, which fails on every fork run with "Resource not accessible by
integration" (a permissions limitation of running CodeQL uploads outside
the upstream repo, unrelated to this change); the "Build, lint, and
test" step passed on all three `check` jobs.

## Before / after behavior (optional)

Before: `$5` (non-regex) expands to an empty capture group. After: `$5`
is inserted literally.

## Risk / compatibility / migration (optional)

Low risk; only affects non-regex replacement escaping.

## UI evidence (required for visual changes; otherwise N/A)

N/A

## Scope

- [x] This PR is focused on one change (no unrelated edits).
2026-08-07 06:04:49 +08:00
Abdo
e5a6fbe27f 26.08.1 (#5281) 2026-08-06 19:16:54 +03:00
dependabot[bot]
066c91c037 chore(ci): bump the actions group across 1 directory with 14 updates (#5272)
Bumps the actions group with 14 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/github-script](https://github.com/actions/github-script) |
`7.1.0` | `9.0.0` |
| [actions/checkout](https://github.com/actions/checkout) | `4.3.1` |
`7.0.1` |
|
[actions-rust-lang/setup-rust-toolchain](https://github.com/actions-rust-lang/setup-rust-toolchain)
| `1.16.1` | `1.17.0` |
| [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) |
`94527f2e458b27549849d47d273a16bec83a01e9` |
`37802adc94f370d6bfd71619e3f0bf239e1f3b78` |
| [actions/setup-node](https://github.com/actions/setup-node) | `4.4.0`
| `7.0.0` |
| [actions/cache](https://github.com/actions/cache) | `4.3.0` | `6.1.0`
|
| [actions/cache/restore](https://github.com/actions/cache) | `4.3.0` |
`6.1.0` |
| [taiki-e/install-action](https://github.com/taiki-e/install-action) |
`2.83.0` | `2.85.3` |
| [actions/cache/save](https://github.com/actions/cache) | `4.3.0` |
`6.1.0` |
| [actions/upload-artifact](https://github.com/actions/upload-artifact)
| `4.6.2` | `7.0.1` |
|
[tj-actions/changed-files](https://github.com/tj-actions/changed-files)
| `47.0.0` | `47.0.6` |
|
[actions/download-artifact](https://github.com/actions/download-artifact)
| `4.3.0` | `8.0.1` |
|
[pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish)
| `1.14.0` | `1.14.1` |
|
[azure/artifact-signing-action](https://github.com/azure/artifact-signing-action)
| `1.2.0` | `2.0.0` |


Updates `actions/github-script` from 7.1.0 to 9.0.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/github-script/releases">actions/github-script's
releases</a>.</em></p>
<blockquote>
<h2>v9.0.0</h2>
<p><strong>New features:</strong></p>
<ul>
<li><strong><code>getOctokit</code> factory function</strong> —
Available directly in the script context. Create additional
authenticated Octokit clients with different tokens for multi-token
workflows, GitHub App tokens, and cross-org access. See <a
href="https://github.com/actions/github-script#creating-additional-clients-with-getoctokit">Creating
additional clients with <code>getOctokit</code></a> for details and
examples.</li>
<li><strong>Orchestration ID in user-agent</strong> — The
<code>ACTIONS_ORCHESTRATION_ID</code> environment variable is
automatically appended to the user-agent string for request
tracing.</li>
</ul>
<p><strong>Breaking changes:</strong></p>
<ul>
<li><strong><code>require('@actions/github')</code> no longer works in
scripts.</strong> The upgrade to <code>@actions/github</code> v9
(ESM-only) means <code>require('@actions/github')</code> will fail at
runtime. If you previously used patterns like <code>const { getOctokit }
= require('@actions/github')</code> to create secondary clients, use the
new injected <code>getOctokit</code> function instead — it's available
directly in the script context with no imports needed.</li>
<li><code>getOctokit</code> is now an injected function parameter.
Scripts that declare <code>const getOctokit = ...</code> or <code>let
getOctokit = ...</code> will get a <code>SyntaxError</code> because
JavaScript does not allow <code>const</code>/<code>let</code>
redeclaration of function parameters. Use the injected
<code>getOctokit</code> directly, or use <code>var getOctokit =
...</code> if you need to redeclare it.</li>
<li>If your script accesses other <code>@actions/github</code> internals
beyond the standard <code>github</code>/<code>octokit</code> client, you
may need to update those references for v9 compatibility.</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Add ACTIONS_ORCHESTRATION_ID to user-agent string by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/695">actions/github-script#695</a></li>
<li>ci: use deployment: false for integration test environments by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/712">actions/github-script#712</a></li>
<li>feat!: add getOctokit to script context, upgrade
<code>@​actions/github</code> v9, <code>@​octokit/core</code> v7, and
related packages by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/700">actions/github-script#700</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Copilot"><code>@​Copilot</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/695">actions/github-script#695</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/github-script/compare/v8.0.0...v9.0.0">https://github.com/actions/github-script/compare/v8.0.0...v9.0.0</a></p>
<h2>v8.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update Node.js version support to 24.x by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/637">actions/github-script#637</a></li>
<li>README for updating actions/github-script from v7 to v8 by <a
href="https://github.com/sneha-krip"><code>@​sneha-krip</code></a> in <a
href="https://redirect.github.com/actions/github-script/pull/653">actions/github-script#653</a></li>
</ul>
<h2>⚠️ Minimum Compatible Runner Version</h2>
<p><strong>v2.327.1</strong><br />
<a
href="https://github.com/actions/runner/releases/tag/v2.327.1">Release
Notes</a></p>
<p>Make sure your runner is updated to this version or newer to use this
release.</p>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/637">actions/github-script#637</a></li>
<li><a
href="https://github.com/sneha-krip"><code>@​sneha-krip</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/github-script/pull/653">actions/github-script#653</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/github-script/compare/v7.1.0...v8.0.0">https://github.com/actions/github-script/compare/v7.1.0...v8.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="3a2844b7e9"><code>3a2844b</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/github-script/issues/700">#700</a>
from actions/salmanmkc/expose-getoctokit + prepare re...</li>
<li><a
href="ca10bbdd1a"><code>ca10bbd</code></a>
fix: use <code>@​octokit/core/</code>types import for v7
compatibility</li>
<li><a
href="86e48e20ac"><code>86e48e2</code></a>
merge: incorporate main branch changes</li>
<li><a
href="c1084728b5"><code>c108472</code></a>
chore: rebuild dist for v9 upgrade and getOctokit factory</li>
<li><a
href="afff112e4f"><code>afff112</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/github-script/issues/712">#712</a>
from actions/salmanmkc/deployment-false + fix user-ag...</li>
<li><a
href="ff8117e5b7"><code>ff8117e</code></a>
ci: fix user-agent test to handle orchestration ID</li>
<li><a
href="81c6b78760"><code>81c6b78</code></a>
ci: use deployment: false to suppress deployment noise from integration
tests</li>
<li><a
href="3953caf885"><code>3953caf</code></a>
docs: update README examples from <a
href="https://github.com/v8"><code>@​v8</code></a> to <a
href="https://github.com/v9"><code>@​v9</code></a>, add getOctokit docs
and v9 brea...</li>
<li><a
href="c17d55b90d"><code>c17d55b</code></a>
ci: add getOctokit integration test job</li>
<li><a
href="a047196d9a"><code>a047196</code></a>
test: add getOctokit integration tests via callAsyncFunction</li>
<li>Additional commits viewable in <a
href="f28e40c7f3...3a2844b7e9">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/checkout` from 4.3.1 to 7.0.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>skip running unsafe pr check if input is default by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2518">actions/checkout#2518</a></li>
<li>trim only ascii whitespace for branch by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2521">actions/checkout#2521</a></li>
<li>escape values passed to --unset by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2530">actions/checkout#2530</a></li>
<li>Various dependency updates</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v7...v7.0.1">https://github.com/actions/checkout/compare/v7...v7.0.1</a></p>
<h2>v7.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>block checking out fork pr for pull_request_target and workflow_run
by <a href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li>
<li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the
minor-actions-dependencies group across 1 directory by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li>
<li>Bump flatted from 3.3.1 to 3.4.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li>
<li>Bump js-yaml from 4.1.0 to 4.2.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li>
<li>Bump <code>@​actions/core</code> and
<code>@​actions/tool-cache</code> and Remove uuid by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li>
<li>upgrade module to esm and update dependencies by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li>
<li>Bump the minor-npm-dependencies group across 1 directory with 3
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li>
<li>getting ready for checkout v7 release by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2464">actions/checkout#2464</a></li>
<li>update error wording by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2467">actions/checkout#2467</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6.0.3...v7.0.0">https://github.com/actions/checkout/compare/v6.0.3...v7.0.0</a></p>
<h2>v6.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li><strong>[BREAKING]</strong> backport
<code>allow-unsafe-pr-checkout</code> to v6 by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2500">actions/checkout#2500</a></li>
<li>backport fixes to releases-v6 by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2527">actions/checkout#2527</a></li>
</ul>
<p><a
href="https://github.blog/changelog/2026-06-18-safer-pull_request_target-defaults-for-github-actions-checkout/">https://github.blog/changelog/2026-06-18-safer-pull_request_target-defaults-for-github-actions-checkout/</a>
for more details about this breaking change</p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6.0.3...v6.1.0">https://github.com/actions/checkout/compare/v6.0.3...v6.1.0</a></p>
<h2>v6.0.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Update changelog by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2357">actions/checkout#2357</a></li>
<li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
<li>Fix checkout init for SHA-256 repositories by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li>
<li>Update changelog for v6.0.3 by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2446">actions/checkout#2446</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/yaananth"><code>@​yaananth</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6...v6.0.3">https://github.com/actions/checkout/compare/v6...v6.0.3</a></p>
<h2>v6.0.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Add orchestration_id to git user-agent when ACTIONS_ORCHESTRATION_ID
is set by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2355">actions/checkout#2355</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>v7.0.1</h2>
<ul>
<li>Skip running unsafe pr check if input is default by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2518">actions/checkout#2518</a></li>
<li>Trim only ascii whitespace for branch by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2521">actions/checkout#2521</a></li>
<li>Escape values passed to --unset by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2530">actions/checkout#2530</a></li>
<li>Various dependency updates</li>
</ul>
<h2>v7.0.0</h2>
<ul>
<li>Block checking out fork PR for pull_request_target and workflow_run
by <a href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li>
<li>Various dependency updates</li>
</ul>
<h2>v6.0.3</h2>
<ul>
<li>Fix checkout init for SHA-256 repositories by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li>
<li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
</ul>
<h2>v6.0.2</h2>
<ul>
<li>Fix tag handling: preserve annotations and explicit fetch-tags by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li>
</ul>
<h2>v6.0.1</h2>
<ul>
<li>Add worktree support for persist-credentials includeIf by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li>
</ul>
<h2>v6.0.0</h2>
<ul>
<li>Persist creds to a separate file by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li>
<li>Update README to include Node.js 24 support details and requirements
by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li>
</ul>
<h2>v5.0.1</h2>
<ul>
<li>Port v6 cleanup to v5 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li>
</ul>
<h2>v5.0.0</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
</ul>
<h2>v4.3.1</h2>
<ul>
<li>Port v6 cleanup to v4 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2305">actions/checkout#2305</a></li>
</ul>
<h2>v4.3.0</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<h2>v4.2.2</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="https://github.com/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<h2>v4.2.1</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="3d3c42e5aa"><code>3d3c42e</code></a>
prep v7.0.1 release (<a
href="https://redirect.github.com/actions/checkout/issues/2531">#2531</a>)</li>
<li><a
href="28802689a1"><code>2880268</code></a>
escape values passed to --unset (<a
href="https://redirect.github.com/actions/checkout/issues/2530">#2530</a>)</li>
<li><a
href="12cd2235ef"><code>12cd223</code></a>
trim only ascii whitespace for branch (<a
href="https://redirect.github.com/actions/checkout/issues/2521">#2521</a>)</li>
<li><a
href="62661c4e71"><code>62661c4</code></a>
skip running unsafe pr check if input is default (<a
href="https://redirect.github.com/actions/checkout/issues/2518">#2518</a>)</li>
<li><a
href="e8d4307400"><code>e8d4307</code></a>
Bump the minor-actions-dependencies group with 2 updates (<a
href="https://redirect.github.com/actions/checkout/issues/2499">#2499</a>)</li>
<li><a
href="631c942040"><code>631c942</code></a>
eslint 9 (<a
href="https://redirect.github.com/actions/checkout/issues/2474">#2474</a>)</li>
<li><a
href="4f1f4aec02"><code>4f1f4ae</code></a>
Bump actions/upload-artifact from 4 to 7 (<a
href="https://redirect.github.com/actions/checkout/issues/2476">#2476</a>)</li>
<li><a
href="ba097532fb"><code>ba09753</code></a>
Bump actions/checkout from 6 to 7 (<a
href="https://redirect.github.com/actions/checkout/issues/2488">#2488</a>)</li>
<li><a
href="b9e0990d21"><code>b9e0990</code></a>
Bump docker/login-action from 3.3.0 to 4.2.0 (<a
href="https://redirect.github.com/actions/checkout/issues/2479">#2479</a>)</li>
<li><a
href="e8cb398be4"><code>e8cb398</code></a>
Bump docker/build-push-action from 6.5.0 to 7.2.0 (<a
href="https://redirect.github.com/actions/checkout/issues/2478">#2478</a>)</li>
<li>Additional commits viewable in <a
href="34e114876b...3d3c42e5aa">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions-rust-lang/setup-rust-toolchain` from 1.16.1 to 1.17.0
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/CHANGELOG.md">actions-rust-lang/setup-rust-toolchain's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<p>All notable changes to this project will be documented in this
file.</p>
<p>The format is based on <a
href="https://keepachangelog.com/en/1.0.0/">Keep a Changelog</a>,
and this project adheres to <a
href="https://semver.org/spec/v2.0.0.html">Semantic Versioning</a>.</p>
<h2>[Unreleased]</h2>
<h2>[1.17.0] - 2026-06-25</h2>
<ul>
<li>Add new parameter <code>cache-targets</code> that is propagated to
<code>Swatinem/rust-cache</code> as <code>cache-targets</code> (<a
href="https://redirect.github.com/actions-rust-lang/setup-rust-toolchain/issues/84">#84</a>).
This allows disabling caching of the workspace <code>target</code>
directory, e.g. when using <code>sccache</code>, while keeping the rest
of the cache enabled.</li>
</ul>
<h2>[1.16.1] - 2026-05-08</h2>
<ul>
<li>Renamed internally used variable to avoid clashes with globally
existing variables.
This fixes the interference of the TOOLCHAIN variable as reported in <a
href="https://redirect.github.com/actions-rust-lang/setup-rust-toolchain/issues/91">#91</a>.</li>
</ul>
<h2>[1.16.0] - 2026-04-13</h2>
<ul>
<li>Add new parameter <code>cache-save-if</code> that is propagated to
<code>Swatinem/rust-cache</code> as <code>save-if</code> (<a
href="https://redirect.github.com/actions-rust-lang/setup-rust-toolchain/issues/90">#90</a>
by <a
href="https://github.com/ChanTsune"><code>@​ChanTsune</code></a>)</li>
</ul>
<h2>[1.15.4] - 2026-03-15</h2>
<ul>
<li>Bump Swatinem/rust-cache from 2.8.2 to 2.9.1 (<a
href="https://redirect.github.com/actions-rust-lang/setup-rust-toolchain/issues/87">#87</a>
by <a
href="https://github.com/hyperfinitism"><code>@​hyperfinitism</code></a>)
This gets rid of the warnings about Node.js 20.</li>
</ul>
<h2>[1.15.3] - 2026-03-01</h2>
<ul>
<li>Bump Swatinem/rust-cache from 2.8.1 to 2.8.2</li>
</ul>
<h2>[1.15.2] - 2025-10-04</h2>
<ul>
<li>Fix: Run the version detection steps in the selected
<code>rust-src-dir</code> directory.
This should enable the version selection even without a default
toolchain installed.
Fixes <a
href="https://redirect.github.com/actions-rust-lang/setup-rust-toolchain/issues/74">#74</a>.</li>
</ul>
<h2>[1.15.1] - 2025-09-23</h2>
<ul>
<li>Update <code>Swatinem/rust-cache</code> to v2.8.1</li>
</ul>
<h2>[1.15.0] - 2025-09-14</h2>
<ul>
<li>Add support for non-root source directory.
Accept source code and <code>rust-toolchain.toml</code> file in
subdirectories of the repository.
Adds a new parameter <code>rust-src-dir</code> that controls the lookup
for toolchain files and sets a default value for the
<code>cache-workspace</code> input. (<a
href="https://redirect.github.com/actions-rust-lang/setup-rust-toolchain/issues/69">#69</a>
by <a href="https://github.com/Kubaryt"><code>@​Kubaryt</code></a>)</li>
</ul>
<h2>[1.14.1] - 2025-08-28</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="166cdcfd11"><code>166cdcf</code></a>
Update changelog to v1.17.0</li>
<li><a
href="446e959dda"><code>446e959</code></a>
Merge pull request <a
href="https://redirect.github.com/actions-rust-lang/setup-rust-toolchain/issues/97">#97</a>
from actions-rust-lang/dependabot/github_actions/actio...</li>
<li><a
href="29eefe925b"><code>29eefe9</code></a>
Merge pull request <a
href="https://redirect.github.com/actions-rust-lang/setup-rust-toolchain/issues/96">#96</a>
from somaz94/feat/cache-targets</li>
<li><a
href="ed33c05dad"><code>ed33c05</code></a>
Bump actions/checkout from 6.0.3 to 7.0.0</li>
<li><a
href="32bae04c0a"><code>32bae04</code></a>
feat: add cache-targets input propagated to Swatinem/rust-cache</li>
<li><a
href="46a9d261ee"><code>46a9d26</code></a>
Merge pull request <a
href="https://redirect.github.com/actions-rust-lang/setup-rust-toolchain/issues/95">#95</a>
from actions-rust-lang/dependabot/github_actions/actio...</li>
<li><a
href="54531a0d49"><code>54531a0</code></a>
Bump actions/checkout from 6.0.2 to 6.0.3</li>
<li><a
href="dc354b3df5"><code>dc354b3</code></a>
Merge pull request <a
href="https://redirect.github.com/actions-rust-lang/setup-rust-toolchain/issues/94">#94</a>
from actions-rust-lang/dependabot/github_actions/actio...</li>
<li><a
href="cbb9413f8e"><code>cbb9413</code></a>
Bump actions/checkout from 6 to 6.0.2</li>
<li>See full diff in <a
href="46268bd060...166cdcfd11">compare
view</a></li>
</ul>
</details>
<br />

Updates `astral-sh/setup-uv` from
94527f2e458b27549849d47d273a16bec83a01e9 to
37802adc94f370d6bfd71619e3f0bf239e1f3b78
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="94527f2e45...37802adc94">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/setup-node` from 4.4.0 to 7.0.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/setup-node/releases">actions/setup-node's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.0</h2>
<h2>What's Changed</h2>
<h3>Enhancements:</h3>
<ul>
<li>Add cache-primary-key and cache-matched-key as outputs by <a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a> in
<a
href="https://redirect.github.com/actions/setup-node/pull/1577">actions/setup-node#1577</a></li>
<li>Migrate to ESM and upgrade dependencies by <a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a> in
<a
href="https://redirect.github.com/actions/setup-node/pull/1574">actions/setup-node#1574</a></li>
</ul>
<h3>Bug fixes:</h3>
<ul>
<li>Remove dummy NODE_AUTH_TOKEN export by <a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a> in
<a
href="https://redirect.github.com/actions/setup-node/pull/1558">actions/setup-node#1558</a></li>
<li>Only use <code>mirrorToken</code> in <code>getManifest</code> if
it's provided by <a
href="https://github.com/deiga"><code>@​deiga</code></a> in <a
href="https://redirect.github.com/actions/setup-node/pull/1548">actions/setup-node#1548</a></li>
</ul>
<h3>Documentation updates:</h3>
<ul>
<li>Add documentation for publishing to npm with Trusted Publisher
(OIDC) by <a
href="https://github.com/chiranjib-swain"><code>@​chiranjib-swain</code></a>
in <a
href="https://redirect.github.com/actions/setup-node/pull/1536">actions/setup-node#1536</a></li>
<li>docs: Update restore-only cache documentation by <a
href="https://github.com/priya-kinthali"><code>@​priya-kinthali</code></a>
in <a
href="https://redirect.github.com/actions/setup-node/pull/1550">actions/setup-node#1550</a></li>
<li>docs: Update caching recommendations to mitigate cache poisoning
risks by <a
href="https://github.com/chiranjib-swain"><code>@​chiranjib-swain</code></a>
in <a
href="https://redirect.github.com/actions/setup-node/pull/1567">actions/setup-node#1567</a></li>
</ul>
<h3>Dependency update:</h3>
<ul>
<li>Upgrade <code>@​actions/cache</code> to 5.1.0, log cache write
denied by <a
href="https://github.com/jasongin"><code>@​jasongin</code></a> in <a
href="https://redirect.github.com/actions/setup-node/pull/1569">actions/setup-node#1569</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/chiranjib-swain"><code>@​chiranjib-swain</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/setup-node/pull/1536">actions/setup-node#1536</a></li>
<li><a href="https://github.com/deiga"><code>@​deiga</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/setup-node/pull/1548">actions/setup-node#1548</a></li>
<li><a href="https://github.com/jasongin"><code>@​jasongin</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/setup-node/pull/1569">actions/setup-node#1569</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-node/compare/v6...v7.0.0">https://github.com/actions/setup-node/compare/v6...v7.0.0</a></p>
<h2>v6.5.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update <code>@​actions/cache</code> to 5.1.0 and add security
overrides for undici and fast-xml-parser by <a
href="https://github.com/HarithaVattikuti"><code>@​HarithaVattikuti</code></a>
in <a
href="https://redirect.github.com/actions/setup-node/pull/1579">actions/setup-node#1579</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-node/compare/v6.4.0...v6.5.0">https://github.com/actions/setup-node/compare/v6.4.0...v6.5.0</a></p>
<h2>v6.4.0</h2>
<h2>What's Changed</h2>
<h3>Dependency updates:</h3>
<ul>
<li>Upgrade <a
href="https://github.com/actions"><code>@​actions</code></a>
dependencies by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/actions/setup-node/pull/1525">actions/setup-node#1525</a></li>
<li>Update Node.js versions in versions.yml and bump package to v6.4.0
by <a
href="https://github.com/priya-kinthali"><code>@​priya-kinthali</code></a>
in <a
href="https://redirect.github.com/actions/setup-node/pull/1533">actions/setup-node#1533</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Copilot"><code>@​Copilot</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/setup-node/pull/1525">actions/setup-node#1525</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-node/compare/v6...v6.4.0">https://github.com/actions/setup-node/compare/v6...v6.4.0</a></p>
<h2>v6.3.0</h2>
<h2>What's Changed</h2>
<h3>Enhancements:</h3>
<ul>
<li>Support parsing <code>devEngines</code> field by <a
href="https://github.com/susnux"><code>@​susnux</code></a> in <a
href="https://redirect.github.com/actions/setup-node/pull/1283">actions/setup-node#1283</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="8207627860"><code>8207627</code></a>
Migrate to ESM and upgrade dependencies (<a
href="https://redirect.github.com/actions/setup-node/issues/1574">#1574</a>)</li>
<li><a
href="04be95cf35"><code>04be95c</code></a>
Add cache-primary-key and cache-matched-key as outputs (<a
href="https://redirect.github.com/actions/setup-node/issues/1577">#1577</a>)</li>
<li><a
href="7c2c68d20d"><code>7c2c68d</code></a>
docs: Update caching recommendations to mitigate cache poisoning risks
(<a
href="https://redirect.github.com/actions/setup-node/issues/1567">#1567</a>)</li>
<li><a
href="6a61c0375d"><code>6a61c03</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/setup-node/issues/1569">#1569</a>
from jasongin/update-actions-cache-5.1.0</li>
<li><a
href="30eb73b41d"><code>30eb73b</code></a>
Resolve high-severity audit issues</li>
<li><a
href="4e1a87a501"><code>4e1a87a</code></a>
Update dist</li>
<li><a
href="360237f0c0"><code>360237f</code></a>
Strict equality</li>
<li><a
href="4f8aac5beb"><code>4f8aac5</code></a>
Bump <code>@​actions/cache</code> to 5.1.0, log cache write denied</li>
<li><a
href="f4a67bbeca"><code>f4a67bb</code></a>
Only use <code>mirrorToken</code> in <code>getManifest</code> if it's
provided (<a
href="https://redirect.github.com/actions/setup-node/issues/1548">#1548</a>)</li>
<li><a
href="0355742c94"><code>0355742</code></a>
Remove dummy NODE_AUTH_TOKEN export (<a
href="https://redirect.github.com/actions/setup-node/issues/1558">#1558</a>)</li>
<li>Additional commits viewable in <a
href="49933ea528...8207627860">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/cache` from 4.3.0 to 6.1.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/cache/releases">actions/cache's
releases</a>.</em></p>
<blockquote>
<h2>v6.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump <code>@​actions/cache</code> to v6.1.0 - handle read-only cache
access by <a
href="https://github.com/jasongin"><code>@​jasongin</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1768">actions/cache#1768</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v6...v6.1.0">https://github.com/actions/cache/compare/v6...v6.1.0</a></p>
<h2>v6.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update packages, migrate to ESM by <a
href="https://github.com/Samirat"><code>@​Samirat</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1760">actions/cache#1760</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v5...v6.0.0">https://github.com/actions/cache/compare/v5...v6.0.0</a></p>
<h2>v5.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump <code>@​actions/cache</code> to v5.1.0 - handle read-only cache
access by <a
href="https://github.com/jasongin"><code>@​jasongin</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1775">actions/cache#1775</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v5...v5.1.0">https://github.com/actions/cache/compare/v5...v5.1.0</a></p>
<h2>v5.0.5</h2>
<h2>What's Changed</h2>
<ul>
<li>Update ts-http-runtime dependency by <a
href="https://github.com/yacaovsnc"><code>@​yacaovsnc</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1747">actions/cache#1747</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v5...v5.0.5">https://github.com/actions/cache/compare/v5...v5.0.5</a></p>
<h2>v5.0.4</h2>
<h2>What's Changed</h2>
<ul>
<li>Add release instructions and update maintainer docs by <a
href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/cache/pull/1696">actions/cache#1696</a></li>
<li>Potential fix for code scanning alert no. 52: Workflow does not
contain permissions by <a
href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/cache/pull/1697">actions/cache#1697</a></li>
<li>Fix workflow permissions and cleanup workflow names / formatting by
<a href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/cache/pull/1699">actions/cache#1699</a></li>
<li>docs: Update examples to use the latest version by <a
href="https://github.com/XZTDean"><code>@​XZTDean</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1690">actions/cache#1690</a></li>
<li>Fix proxy integration tests by <a
href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/cache/pull/1701">actions/cache#1701</a></li>
<li>Fix cache key in examples.md for bun.lock by <a
href="https://github.com/RyPeck"><code>@​RyPeck</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1722">actions/cache#1722</a></li>
<li>Update dependencies &amp; patch security vulnerabilities by <a
href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/cache/pull/1738">actions/cache#1738</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/XZTDean"><code>@​XZTDean</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/cache/pull/1690">actions/cache#1690</a></li>
<li><a href="https://github.com/RyPeck"><code>@​RyPeck</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/cache/pull/1722">actions/cache#1722</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v5...v5.0.4">https://github.com/actions/cache/compare/v5...v5.0.4</a></p>
<h2>v5.0.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump <code>@actions/cache</code> to v5.0.5 (Resolves: <a
href="https://github.com/actions/cache/security/dependabot/33">https://github.com/actions/cache/security/dependabot/33</a>)</li>
<li>Bump <code>@actions/core</code> to v2.0.3</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/cache/blob/main/RELEASES.md">actions/cache's
changelog</a>.</em></p>
<blockquote>
<h1>Releases</h1>
<h2>How to prepare a release</h2>
<blockquote>
<p>[!NOTE]
Relevant for maintainers with write access only.</p>
</blockquote>
<ol>
<li>Switch to a new branch from <code>main</code>.</li>
<li>Run <code>npm test</code> to ensure all tests are passing.</li>
<li>Update the version in <a
href="https://github.com/actions/cache/blob/main/package.json"><code>https://github.com/actions/cache/blob/main/package.json</code></a>.</li>
<li>Run <code>npm run build</code> to update the compiled files.</li>
<li>Update this <a
href="https://github.com/actions/cache/blob/main/RELEASES.md"><code>https://github.com/actions/cache/blob/main/RELEASES.md</code></a>
with the new version and changes in the <code>## Changelog</code>
section.</li>
<li>Run <code>licensed cache</code> to update the license report.</li>
<li>Run <code>licensed status</code> and resolve any warnings by
updating the <a
href="https://github.com/actions/cache/blob/main/.licensed.yml"><code>https://github.com/actions/cache/blob/main/.licensed.yml</code></a>
file with the exceptions.</li>
<li>Commit your changes and push your branch upstream.</li>
<li>Open a pull request against <code>main</code> and get it reviewed
and merged.</li>
<li>Draft a new release <a
href="https://github.com/actions/cache/releases">https://github.com/actions/cache/releases</a>
use the same version number used in <code>package.json</code>
<ol>
<li>Create a new tag with the version number.</li>
<li>Auto generate release notes and update them to match the changes you
made in <code>RELEASES.md</code>.</li>
<li>Toggle the set as the latest release option.</li>
<li>Publish the release.</li>
</ol>
</li>
<li>Navigate to <a
href="https://github.com/actions/cache/actions/workflows/release-new-action-version.yml">https://github.com/actions/cache/actions/workflows/release-new-action-version.yml</a>
<ol>
<li>There should be a workflow run queued with the same version
number.</li>
<li>Approve the run to publish the new version and update the major tags
for this action.</li>
</ol>
</li>
</ol>
<h2>Changelog</h2>
<h3>6.1.0</h3>
<ul>
<li>Bump <code>@actions/cache</code> to v6.1.0 to pick up <a
href="https://redirect.github.com/actions/toolkit/pull/2435">actions/toolkit#2435
Handle cache write error due to read-only token</a></li>
<li>Switch redundant &quot;Cache save failed&quot; warning to debug log
in save-only</li>
</ul>
<h3>6.0.0</h3>
<ul>
<li>Updated <code>@actions/cache</code> to ^6.0.1,
<code>@actions/core</code> to ^3.0.1, <code>@actions/exec</code> to
^3.0.0, <code>@actions/io</code> to ^3.0.2</li>
<li>Migrated to ESM module system</li>
<li>Upgraded Jest to v30 and test infrastructure to be ESM
compatible</li>
</ul>
<h3>5.0.4</h3>
<ul>
<li>Bump <code>minimatch</code> to v3.1.5 (fixes ReDoS via globstar
patterns)</li>
<li>Bump <code>undici</code> to v6.24.1 (WebSocket decompression bomb
protection, header validation fixes)</li>
<li>Bump <code>fast-xml-parser</code> to v5.5.6</li>
</ul>
<h3>5.0.3</h3>
<ul>
<li>Bump <code>@actions/cache</code> to v5.0.5 (Resolves: <a
href="https://github.com/actions/cache/security/dependabot/33">https://github.com/actions/cache/security/dependabot/33</a>)</li>
<li>Bump <code>@actions/core</code> to v2.0.3</li>
</ul>
<h3>5.0.2</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="55cc834586"><code>55cc834</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/cache/issues/1768">#1768</a>
from jasongin/readonly-cache</li>
<li><a
href="d8cd72f230"><code>d8cd72f</code></a>
Bump <code>@​actions/cache</code> to v6.1.0 - handle cache write error
due to RO token</li>
<li><a
href="2c8a9bd745"><code>2c8a9bd</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/cache/issues/1760">#1760</a>
from actions/samirat/esm_migration_and_package_update</li>
<li><a
href="e9b91fdc3f"><code>e9b91fd</code></a>
Prettier fixes</li>
<li><a
href="e4884b8ff7"><code>e4884b8</code></a>
Rebuild dist</li>
<li><a
href="10baf0191a"><code>10baf01</code></a>
Fixed licenses</li>
<li><a
href="e39b386c90"><code>e39b386</code></a>
Fix test mock return order</li>
<li><a
href="b692820337"><code>b692820</code></a>
PR feedback</li>
<li><a
href="60749128a4"><code>6074912</code></a>
Rebuild dist bundles as ESM to match type:module</li>
<li><a
href="5a912e8b4a"><code>5a912e8</code></a>
Fix lint and jest issues</li>
<li>Additional commits viewable in <a
href="0057852bfa...55cc834586">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/cache/restore` from 4.3.0 to 6.1.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/cache/releases">actions/cache/restore's
releases</a>.</em></p>
<blockquote>
<h2>v6.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump <code>@​actions/cache</code> to v6.1.0 - handle read-only cache
access by <a
href="https://github.com/jasongin"><code>@​jasongin</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1768">actions/cache#1768</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v6...v6.1.0">https://github.com/actions/cache/compare/v6...v6.1.0</a></p>
<h2>v6.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update packages, migrate to ESM by <a
href="https://github.com/Samirat"><code>@​Samirat</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1760">actions/cache#1760</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v5...v6.0.0">https://github.com/actions/cache/compare/v5...v6.0.0</a></p>
<h2>v5.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump <code>@​actions/cache</code> to v5.1.0 - handle read-only cache
access by <a
href="https://github.com/jasongin"><code>@​jasongin</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1775">actions/cache#1775</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v5...v5.1.0">https://github.com/actions/cache/compare/v5...v5.1.0</a></p>
<h2>v5.0.5</h2>
<h2>What's Changed</h2>
<ul>
<li>Update ts-http-runtime dependency by <a
href="https://github.com/yacaovsnc"><code>@​yacaovsnc</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1747">actions/cache#1747</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v5...v5.0.5">https://github.com/actions/cache/compare/v5...v5.0.5</a></p>
<h2>v5.0.4</h2>
<h2>What's Changed</h2>
<ul>
<li>Add release instructions and update maintainer docs by <a
href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/cache/pull/1696">actions/cache#1696</a></li>
<li>Potential fix for code scanning alert no. 52: Workflow does not
contain permissions by <a
href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/cache/pull/1697">actions/cache#1697</a></li>
<li>Fix workflow permissions and cleanup workflow names / formatting by
<a href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/cache/pull/1699">actions/cache#1699</a></li>
<li>docs: Update examples to use the latest version by <a
href="https://github.com/XZTDean"><code>@​XZTDean</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1690">actions/cache#1690</a></li>
<li>Fix proxy integration tests by <a
href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/cache/pull/1701">actions/cache#1701</a></li>
<li>Fix cache key in examples.md for bun.lock by <a
href="https://github.com/RyPeck"><code>@​RyPeck</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1722">actions/cache#1722</a></li>
<li>Update dependencies &amp; patch security vulnerabilities by <a
href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/cache/pull/1738">actions/cache#1738</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/XZTDean"><code>@​XZTDean</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/cache/pull/1690">actions/cache#1690</a></li>
<li><a href="https://github.com/RyPeck"><code>@​RyPeck</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/cache/pull/1722">actions/cache#1722</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v5...v5.0.4">https://github.com/actions/cache/compare/v5...v5.0.4</a></p>
<h2>v5.0.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump <code>@actions/cache</code> to v5.0.5 (Resolves: <a
href="https://github.com/actions/cache/security/dependabot/33">https://github.com/actions/cache/security/dependabot/33</a>)</li>
<li>Bump <code>@actions/core</code> to v2.0.3</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/cache/blob/main/RELEASES.md">actions/cache/restore's
changelog</a>.</em></p>
<blockquote>
<h1>Releases</h1>
<h2>How to prepare a release</h2>
<blockquote>
<p>[!NOTE]
Relevant for maintainers with write access only.</p>
</blockquote>
<ol>
<li>Switch to a new branch from <code>main</code>.</li>
<li>Run <code>npm test</code> to ensure all tests are passing.</li>
<li>Update the version in <a
href="https://github.com/actions/cache/blob/main/package.json"><code>https://github.com/actions/cache/blob/main/package.json</code></a>.</li>
<li>Run <code>npm run build</code> to update the compiled files.</li>
<li>Update this <a
href="https://github.com/actions/cache/blob/main/RELEASES.md"><code>https://github.com/actions/cache/blob/main/RELEASES.md</code></a>
with the new version and changes in the <code>## Changelog</code>
section.</li>
<li>Run <code>licensed cache</code> to update the license report.</li>
<li>Run <code>licensed status</code> and resolve any warnings by
updating the <a
href="https://github.com/actions/cache/blob/main/.licensed.yml"><code>https://github.com/actions/cache/blob/main/.licensed.yml</code></a>
file with the exceptions.</li>
<li>Commit your changes and push your branch upstream.</li>
<li>Open a pull request against <code>main</code> and get it reviewed
and merged.</li>
<li>Draft a new release <a
href="https://github.com/actions/cache/releases">https://github.com/actions/cache/releases</a>
use the same version number used in <code>package.json</code>
<ol>
<li>Create a new tag with the version number.</li>
<li>Auto generate release notes and update them to match the changes you
made in <code>RELEASES.md</code>.</li>
<li>Toggle the set as the latest release option.</li>
<li>Publish the release.</li>
</ol>
</li>
<li>Navigate to <a
href="https://github.com/actions/cache/actions/workflows/release-new-action-version.yml">https://github.com/actions/cache/actions/workflows/release-new-action-version.yml</a>
<ol>
<li>There should be a workflow run queued with the same version
number.</li>
<li>Approve the run to publish the new version and update the major tags
for this action.</li>
</ol>
</li>
</ol>
<h2>Changelog</h2>
<h3>6.1.0</h3>
<ul>
<li>Bump <code>@actions/cache</code> to v6.1.0 to pick up <a
href="https://redirect.github.com/actions/toolkit/pull/2435">actions/toolkit#2435
Handle cache write error due to read-only token</a></li>
<li>Switch redundant &quot;Cache save failed&quot; warning to debug log
in save-only</li>
</ul>
<h3>6.0.0</h3>
<ul>
<li>Updated <code>@actions/cache</code> to ^6.0.1,
<code>@actions/core</code> to ^3.0.1, <code>@actions/exec</code> to
^3.0.0, <code>@actions/io</code> to ^3.0.2</li>
<li>Migrated to ESM module system</li>
<li>Upgraded Jest to v30 and test infrastructure to be ESM
compatible</li>
</ul>
<h3>5.0.4</h3>
<ul>
<li>Bump <code>minimatch</code> to v3.1.5 (fixes ReDoS via globstar
patterns)</li>
<li>Bump <code>undici</code> to v6.24.1 (WebSocket decompression bomb
protection, header validation fixes)</li>
<li>Bump <code>fast-xml-parser</code> to v5.5.6</li>
</ul>
<h3>5.0.3</h3>
<ul>
<li>Bump <code>@actions/cache</code> to v5.0.5 (Resolves: <a
href="https://github.com/actions/cache/security/dependabot/33">https://github.com/actions/cache/security/dependabot/33</a>)</li>
<li>Bump <code>@actions/core</code> to v2.0.3</li>
</ul>
<h3>5.0.2</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="55cc834586"><code>55cc834</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/cache/issues/1768">#1768</a>
from jasongin/readonly-cache</li>
<li><a
href="d8cd72f230"><code>d8cd72f</code></a>
Bump <code>@​actions/cache</code> to v6.1.0 - handle cache write error
due to RO token</li>
<li><a
href="2c8a9bd745"><code>2c8a9bd</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/cache/issues/1760">#1760</a>
from actions/samirat/esm_migration_and_package_update</li>
<li><a
href="e9b91fdc3f"><code>e9b91fd</code></a>
Prettier fixes</li>
<li><a
href="e4884b8ff7"><code>e4884b8</code></a>
Rebuild dist</li>
<li><a
href="10baf0191a"><code>10baf01</code></a>
Fixed licenses</li>
<li><a
href="e39b386c90"><code>e39b386</code></a>
Fix test mock return order</li>
<li><a
href="b692820337"><code>b692820</code></a>
PR feedback</li>
<li><a
href="60749128a4"><code>6074912</code></a>
Rebuild dist bundles as ESM to match type:module</li>
<li><a
href="5a912e8b4a"><code>5a912e8</code></a>
Fix lint and jest issues</li>
<li>Additional commits viewable in <a
href="0057852bfa...55cc834586">compare
view</a></li>
</ul>
</details>
<br />

Updates `taiki-e/install-action` from 2.83.0 to 2.85.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/taiki-e/install-action/releases">taiki-e/install-action's
releases</a>.</em></p>
<blockquote>
<h2>2.85.3</h2>
<ul>
<li>
<p>Update <code>xh@latest</code> to 0.26.2.</p>
</li>
<li>
<p>Update <code>ubi@latest</code> to 0.10.0.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.7.14.</p>
</li>
<li>
<p>Update <code>martin@latest</code> to 1.13.0.</p>
</li>
<li>
<p>Update <code>cargo-shear@latest</code> to 1.13.3.</p>
</li>
<li>
<p>Update <code>cargo-binstall@latest</code> to 1.21.1.</p>
</li>
</ul>
<h2>2.85.2</h2>
<ul>
<li>
<p>Update <code>prek@latest</code> to 0.4.11.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.7.13.</p>
</li>
<li>
<p>Update <code>kingfisher@latest</code> to 1.109.0.</p>
</li>
</ul>
<h2>2.85.1</h2>
<ul>
<li>
<p>Update <code>vacuum@latest</code> to 0.30.0.</p>
</li>
<li>
<p>Update <code>uv@latest</code> to 0.11.32.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.7.12.</p>
</li>
<li>
<p>Update <code>cyclonedx@latest</code> to 0.33.1.</p>
</li>
<li>
<p>Update <code>cargo-neat@latest</code> to 0.5.2.</p>
</li>
</ul>
<h2>2.85.0</h2>
<ul>
<li>
<p>Support <code>wild</code> (alias: <code>wild-linker</code>). (<a
href="https://redirect.github.com/taiki-e/install-action/pull/1949">#1949</a>)</p>
</li>
<li>
<p>Support <code>bpf-linker</code>. (<a
href="https://redirect.github.com/taiki-e/install-action/pull/1950">#1950</a>)</p>
</li>
<li>
<p>Support <code>rafn</code>. (<a
href="https://redirect.github.com/taiki-e/install-action/pull/1935">#1935</a>,
thanks <a
href="https://github.com/DarkWanderer"><code>@​DarkWanderer</code></a>)</p>
</li>
<li>
<p>Update <code>cargo-neat@latest</code> to 0.5.1.</p>
</li>
<li>
<p>Update <code>zizmor@latest</code> to 1.28.0.</p>
</li>
<li>
<p>Update <code>wasmtime@latest</code> to 47.0.2.</p>
</li>
<li>
<p>Update <code>uv@latest</code> to 0.11.31.</p>
</li>
<li>
<p>Update <code>syft@latest</code> to 1.49.0.</p>
</li>
</ul>
<h2>2.84.1</h2>
<ul>
<li>Update <code>wasmtime@latest</code> to 47.0.1.</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md">taiki-e/install-action's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<p>All notable changes to this project will be documented in this
file.</p>
<p>This project adheres to <a href="https://semver.org">Semantic
Versioning</a>.</p>
<!-- raw HTML omitted -->
<h2>[Unreleased]</h2>
<h2>[2.85.7] - 2026-08-02</h2>
<ul>
<li>
<p>Update <code>wasmtime@latest</code> to 47.0.3.</p>
</li>
<li>
<p>Update <code>uv@latest</code> to 0.12.1.</p>
</li>
<li>
<p>Update <code>rclone@latest</code> to 1.75.0.</p>
</li>
<li>
<p>Update <code>kingfisher@latest</code> to 1.110.0.</p>
</li>
</ul>
<h2>[2.85.6] - 2026-08-01</h2>
<ul>
<li>
<p>Update <code>wasm-tools@latest</code> to 1.255.0.</p>
</li>
<li>
<p>Update <code>tombi@latest</code> to 1.2.5.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.7.18.</p>
</li>
<li>
<p>Update <code>cargo-neat@latest</code> to 0.5.3.</p>
</li>
<li>
<p>Update <code>cargo-crap@latest</code> to 0.4.0.</p>
</li>
</ul>
<h2>[2.85.5] - 2026-07-30</h2>
<ul>
<li>
<p>Update <code>uv@latest</code> to 0.12.0.</p>
</li>
<li>
<p>Update <code>syft@latest</code> to 1.50.0.</p>
</li>
<li>
<p>Update <code>sccache@latest</code> to 0.17.0.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.7.16.</p>
</li>
</ul>
<h2>[2.85.4] - 2026-07-29</h2>
<ul>
<li>
<p>Update <code>uv@latest</code> to 0.11.33.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.7.15.</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="18b1216eba"><code>18b1216</code></a>
Release 2.85.3</li>
<li><a
href="3a7eb9d7de"><code>3a7eb9d</code></a>
Update <code>xh@latest</code> to 0.26.2</li>
<li><a
href="3d4a0c1c70"><code>3d4a0c1</code></a>
Update uv manifest</li>
<li><a
href="9e4a53cd83"><code>9e4a53c</code></a>
Update <code>ubi@latest</code> to 0.10.0</li>
<li><a
href="9f2f6a3c93"><code>9f2f6a3</code></a>
Update <code>mise@latest</code> to 2026.7.14</li>
<li><a
href="e026bd26ee"><code>e026bd2</code></a>
Update <code>martin@latest</code> to 1.13.0</li>
<li><a
href="f72efa0e99"><code>f72efa0</code></a>
Update <code>cargo-shear@latest</code> to 1.13.3</li>
<li><a
href="d19664f75e"><code>d19664f</code></a>
Update <code>cargo-binstall@latest</code> to 1.21.1</li>
<li><a
href="4d9bbfb56a"><code>4d9bbfb</code></a>
Update biome manifest</li>
<li><a
href="41049aa566"><code>41049aa</code></a>
Release 2.85.2</li>
<li>Additional commits viewable in <a
href="https://github.com/taiki-e/install-action/compare/v2.83.0...18b1216eba7f8039b0f8d131d5473787f0edce68">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/cache/save` from 4.3.0 to 6.1.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/cache/releases">actions/cache/save's
releases</a>.</em></p>
<blockquote>
<h2>v6.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump <code>@​actions/cache</code> to v6.1.0 - handle read-only cache
access by <a
href="https://github.com/jasongin"><code>@​jasongin</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1768">actions/cache#1768</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v6...v6.1.0">https://github.com/actions/cache/compare/v6...v6.1.0</a></p>
<h2>v6.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update packages, migrate to ESM by <a
href="https://github.com/Samirat"><code>@​Samirat</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1760">actions/cache#1760</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v5...v6.0.0">https://github.com/actions/cache/compare/v5...v6.0.0</a></p>
<h2>v5.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump <code>@​actions/cache</code> to v5.1.0 - handle read-only cache
access by <a
href="https://github.com/jasongin"><code>@​jasongin</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1775">actions/cache#1775</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v5...v5.1.0">https://github.com/actions/cache/compare/v5...v5.1.0</a></p>
<h2>v5.0.5</h2>
<h2>What's Changed</h2>
<ul>
<li>Update ts-http-runtime dependency by <a
href="https://github.com/yacaovsnc"><code>@​yacaovsnc</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1747">actions/cache#1747</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v5...v5.0.5">https://github.com/actions/cache/compare/v5...v5.0.5</a></p>
<h2>v5.0.4</h2>
<h2>What's Changed</h2>
<ul>
<li>Add release instructions and update maintainer docs by <a
href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/cache/pull/1696">actions/cache#1696</a></li>
<li>Potential fix for code scanning alert no. 52: Workflow does not
contain permissions by <a
href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/cache/pull/1697">actions/cache#1697</a></li>
<li>Fix workflow permissions and cleanup workflow names / formatting by
<a href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/cache/pull/1699">actions/cache#1699</a></li>
<li>docs: Update examples to use the latest version by <a
href="https://github.com/XZTDean"><code>@​XZTDe...

_Description has been truncated_

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Fernando Lins <1887601+fernandolins@users.noreply.github.com>
2026-08-05 17:48:37 -03:00
Abdo
898902cdaf Remove debug print 2026-08-05 17:25:41 +03:00
Abdo
815e8fdcc8 Limit CSP in SvelteKit pages to new editor (#5278)
## Linked issue

Closes #5275

## Summary

Inline `bridgeCommand` links are no longer allowed after
a809304e38

Initially I replaced the inline JS with an event listener, but it turned
out CSP might be too intrusive for add-ons adding their bridge command
handlers to Svelte pages, so I decided to limit CSP to the new editor.

## Steps to reproduce (before)

- Open a deck with no due cards.
- Click on the "custom study" and "unbury" links (if shown) in the text
and notice nothing happens.

## How to test (after)

- Confirm the congrats screen's links work.
Open the new editor and try running inline JS, e.g. `<button
onclick="alert('test')">click</button>` and confirm no user script
execution happens.
2026-08-05 17:17:50 +03:00
Abdo
9f97884893 fix: broken OK button in help modals (#5279)
## Linked issue

Closes #5276

## Summary

Fix broken OK button in help modals (e.g. in the Deck Options screen).

## Steps to reproduce (before)

1. Open the Deck Options screen.
2. Click on any of the "?" icons.
3. Click "OK" and notice the modal is not closed.

## How to test (after)

Confirm the modal is closed.
2026-08-05 16:45:32 +03:00