Commit Graph
184 Commits
Author SHA1 Message Date
wofiporiaandAbdo e6fefb2962 docs: improve manual translation instructions (#5519)
## Linked issue (required)

Fixes #5510

## Summary / motivation (required)

Expands the manual translation instructions as requested in #5510:

- `docs-site/translators/anki/manual.mdx` now contains detailed
instructions for translating the documentation: forking the repository,
working in a language subdirectory (existing or new), keeping Markdown
formatting intact while translating the MDX pages, registering
translated pages in `docs.json` (with an example following the shape of
the existing language entries), and submitting a PR. It also notes that
partial translations are welcome, that documentation changes are
licensed under CC BY-SA 4.0, and where to ask questions.
- The Translations section of `docs-site/README.md` now links to that
page instead of holding the details itself, reversing the previous
direction per the issue.
- The Translations sections of `docs-site/developers/contributing.mdx`
and the cog-generated `docs/contributing.md` briefly mention
documentation translations, which were previously only covered for
interface strings.

Also adds myself to the CONTRIBUTORS file in a separate commit, as
requested for first pull requests.

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

N/A

## How to test (required)

Documentation-only change. Verified that:

- All paths referenced in the new instructions exist in the repository
(e.g. `docs-site/ru/manual/`, `docs-site/manual/`, and the other
language subdirectories).
- The `docs.json` example matches the structure of the existing language
entries under `navigation.languages`.
- Both internal links resolve to pages registered in
`docs-site/docs.json` (`/translators/anki/manual`,
`/translators/anki/developers`).
- No MDX-special characters (`{`, `<`) appear outside fenced code blocks
in the new content, so `mintlify validate` should pass.
- `docs/contributing.md` stays in sync with
`docs-site/developers/contributing.mdx` under the transformation in
`docs/cogdocs.py`.

### Checklist (minimum)

- [ ] I ran `./ninja check` or an equivalent relevant check locally.
*Not applicable for a documentation-only change; the relevant check is
the Docs Site workflow (`mintlify validate` / `mintlify a11y`), which
runs in CI.*
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.
*N/A - documentation-only changes are exempt from tests per
`contributing.md`.*

## Before / after behavior (optional)

N/A

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

N/A

## Scope

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

---------

Co-authored-by: Abdo <abdo@abdnh.net>
2026-09-22 12:06:56 +03:00
Fernando Lins f4c684a96e fix(ci): fetch PR base branch so SonarCloud diffs only changed files (#5659)
## Linked issue

Fixes #5657

## Summary / motivation

SonarCloud PR analysis derives the changed-file set from git and
requires the target branch to be present in the local repository. The
scan checks out only the fork's head history (`fetch-depth: 0` on the
head ref), so the base branch was never fetched. Without a base to diff
against, the scanner attributed every analysed file to the PR as new
code, e.g. 977 files on the single-file change in #5641
(`qt/aqt/preferences.py`), and recurring noise in `tools/`.

This adds a step that fetches the target branch from the trusted
upstream repository (`github.repository`, never the fork) and pins it
locally under the name passed as `sonar.pullrequest.base`, so new code
is measured against the real PR diff. It does not disable any rule or
exclude any file.

The isolation boundary is preserved: the upstream branch is read as data
only, nothing is built or executed, the trusted config and
no-fork-code-execution constraints are unchanged, and the Quality Gate
stays informative.

## Steps to reproduce

1. Open a fork PR that changes a single file (e.g. #5641, base `main`).
2. Let CI complete and the SonarCloud workflow run.
3. Observe SonarCloud reporting new-code issues across hundreds of
unchanged files (~977) instead of only the changed file.

## How to test
### Details

Reproduced the scanner's git-based new-code computation locally against
the exact commits from #5641:

- head = `1e7914a`
- base branch `main` fetched from upstream → `merge-base` = `bdeec0877`,
which matches the PR's `baseRefOid` reported by the GitHub API.
- `git diff --name-only <merge-base> <head>` → **only**
`qt/aqt/preferences.py`.

The new step also logs the analysed commit, base repo/branch, base
commit and merge-base, and fails closed if the base reference cannot be
resolved (no silent fallback to a missing base). YAML parse and the
cog-generated `docs/sonarcloud.md` sync were verified.

## Before / after behavior

- Before: fork/PR scan treats all indexed files as new code (977 files
for a
  one-file PR).
- After: only the files actually changed vs the upstream base are
considered
  new code.
2026-09-22 11:45:03 +03:00
Fernando Lins 4acb5329e6 fix(ci): track releases in the SonarCloud project version (#5634)
## What was happening

When I set up the Sonar PoC, I pinned `sonar.projectVersion` to `0.1`.
The New Code period is "previous version", so with the version never
changing, the baseline stayed frozen at that first analysis. Everything
merged since then kept accumulating as "new code" instead of rolling off
at each release, which is why the Quality Gate on `main` has been red
since August (e.g., coverage for "new code" is at 62%, below the 80%
minimum).

## The fix

Now the Sonar version follows the project version instead of being
pinned, so every release bump gives us a fresh baseline. Pulled from the
trusted default-branch checkout so a fork can't tamper with it.

## How it works from now on

PRs won't change: Sonar already checks only your diff, so the 80%
coverage gate applies just to the lines you touched, not the old debt.

For `main`: the baseline now resets on each release. Just note it moves
on the next version bump, not on this merge, so `main` stays red until
then, and after that "new code" is only what changed since the last
release.
2026-09-17 17:20:11 -03:00
Fernando Lins 587d6ec796 fix: run static SonarCloud analysis on fork PRs (#5596)
## Linked issue

Follow-up to #5498, which was closed in favor of a smaller and more
maintainable implementation.

## Summary / motivation

Run CI-based SonarCloud analysis for internal and fork pull requests
while keeping the Quality Gate informational.

The analysis matrix is:

| Event | Static analysis | Coverage in CI | Coverage in SonarCloud |
| --- | --- | --- | --- |
| Internal pull request | Yes | Yes | Yes |
| Push to `main` or `release/**` | Yes | Yes | Yes |
| Fork pull request | Yes | Yes | No |

Fork pull requests continue to run the full test coverage and
coverage-regression checks in the unprivileged CI workflow. Their
contributor-produced coverage reports are not passed to the privileged
SonarCloud workflow.

The fork scan reports static bugs, vulnerabilities, security hotspots,
and code smells. It:

- validates the PR state, repositories, branches, and tested SHA against
the GitHub API;
- checks out the exact revision tested by CI;
- replaces `sonar-project.properties` with the trusted default-branch
version;
- provides `SONAR_TOKEN` only to the scanner step;
- never builds, installs, or executes contributor code;
- keeps scanner-side Clippy and SCA disabled;
- clears coverage report paths and excludes coverage calculation for
forks.

Automatic Analysis remains disabled because it cannot be combined with
CI-based analysis and does not provide the required Rust and coverage
support.

This also configures Vitest to produce repository-relative LCOV paths
such as `SF:ts/lib/...`, allowing SonarCloud to resolve TypeScript files
when reports are downloaded into a separate checkout.

## How to test

### Checklist

- [x] I ran `just check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed. The remaining behavior is specific to GitHub's
`workflow_run` environment and can only be exercised end-to-end after
the workflow is available on the default branch.

### Details

The following checks passed locally:

- `just test-ts --coverage`
- `just test-ts --coverage --html`
- `just fmt`
- `just check`
- YAML and JSON parsing
- `git diff --check`

Both TypeScript coverage runs passed all 67 tests. The generated LCOV
report was also checked to confirm that source paths are
repository-relative and begin with `SF:ts/`.

After this lands, end-to-end validation should cover:

1. A push to `main`, confirming that Python, TypeScript, and Rust
coverage reports are imported.
2. An internal PR, confirming static analysis and coverage.
3. A fork PR, confirming static analysis while the coverage download is
skipped and no coverage condition is evaluated.

## Before / after behavior

Before:

- fork PR analysis fails at the protected checkout;
- the `actions/checkout` version comments are outdated;
- TypeScript LCOV paths are relative to `ts/` and may not resolve in the
SonarCloud checkout.

After:

- internal PRs and trusted branch pushes receive static analysis and
coverage;
- fork PRs receive static analysis without importing
contributor-produced coverage;
- fork tests and coverage-regression checks continue to run in regular
CI;
- TypeScript LCOV paths resolve from the repository root;
- technical scanner failures remain visible without making the Sonar
Quality Gate a required merge check.

## Risk / compatibility / migration

The fork analysis runs in a privileged `workflow_run` and necessarily
asks the SonarScanner to parse untrusted source while it has access to a
project-scoped token.

The workflow limits this exposure by using GitHub-hosted runners,
read-only permissions, trusted scanner configuration, an exact tested
SHA, API-validated PR metadata, and no builds, dependency installation,
local Actions, caches, or fork-produced coverage artifacts.

This is intentionally a smaller trust boundary than the data-only
snapshot and custom coverage parser proposed in #5498. It prevents
direct execution of contributor code but does not eliminate potential
vulnerabilities in GitHub Actions or Sonar analyzers.

Automatic Analysis must remain disabled, `SONAR_TOKEN` should remain
restricted to this project, and the SonarCloud check must remain
non-required.
2026-09-14 15:30:42 -03:00
dea2a1f93a feat: Docs converter (#5483)
closes #5064 

Should let you quickly import to mintlify from the repos that use the
existing format.

a small problem that `DOCS_RELATIVE_LINK_REPLACEMENTS` needs to be set
manually for links between related translations but other than that
should be good.

I've run it on `en/addons` `en/faqs` `en/manual` and on `ar/manual`
`ar/faqs`. We might need to be careful to not overwrite any changes that
have been merged in this repo if there are any.

I've set it to copy only files where it can find them in the existing
mintlify docs because this allows us to more easily keep the site
structure. It does mean that there are some pages which aren't copied
and I'm going to have to look into that at some point.

But it should be good enough to look through and to import any remaining
changes left in the existing repos.

Example usage:
```
python tools/docs-converter.py [Source repo] [Target tab] [Target language code]
```

```
python tools/docs-converter.py ../anki-manual manual en
python tools/docs-converter.py ../anki-faqs faqs ar
```

---------

Co-authored-by: Abdo <abdo@abdnh.net>
Co-authored-by: Fernando Lins <1887601+fernandolins@users.noreply.github.com>
2026-09-10 15:10:22 +01:00
Fernando Lins 392fdecbb3 docs: add unit testing guidelines (#5522)
## Linked issue

Closes #5521

## Summary / motivation

Adds an Anki-focused unit testing guide for maintainers, contributors,
and coding assistants.

The guide:

- Defines principles for focused, deterministic, and maintainable tests.
- Covers happy paths, error paths, boundaries, regressions, and
test-first development.
- Provides guidance for Python, Python/Qt, Rust, and
Svelte/TypeScript/JavaScript.
- Clarifies the appropriate scope for UI tests and discourages testing
styling or volatile presentation details.
- Links the guide from the shared `CLAUDE.md`/`AGENTS.md` instructions.
2026-09-09 17:03:26 -03:00
Fernando Lins a7f3ffb63a PoC: evaluate SonarCloud as a code quality and coverage tool (#4996)
## Linked issue

Closes #4995

## Summary / motivation

Bedges available:

[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=ankitects_anki&metric=coverage)](https://sonarcloud.io/summary/new_code?id=ankitects_anki)
[![Duplicated Lines
(%)](https://sonarcloud.io/api/project_badges/measure?project=ankitects_anki&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=ankitects_anki)
[![Code
Smells](https://sonarcloud.io/api/project_badges/measure?project=ankitects_anki&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=ankitects_anki)

[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=ankitects_anki&metric=bugs)](https://sonarcloud.io/summary/new_code?id=ankitects_anki)
[![Quality Gate
Status](https://sonarcloud.io/api/project_badges/measure?project=ankitects_anki&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=ankitects_anki)

[![Reliability](https://sonarcloud.io/api/project_badges/measure?project=ankitects_anki&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=ankitects_anki)

[![Security](https://sonarcloud.io/api/project_badges/measure?project=ankitects_anki&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=ankitects_anki)


**[SONAR
DASHBOARD](https://sonarcloud.io/project/overview?id=ankitects_anki)**

Integrates SonarCloud into the CI pipeline as a proof of concept to
evaluate whether
it surfaces actionable quality and security insights for this codebase.

Changes:
- Added `sonar-project.properties` configuring sources (`pylib`, `qt`,
`ts`, `rslib`)
  and coverage report paths
- Extended `tools/coverage/coverage-py` (and `.bat`) to emit
`coverage.xml` (Cobertura)
- Extended `tools/coverage/coverage-ts` (and `.bat`) to emit `lcov.info`
via the V8 provider
- Extended `tools/coverage/coverage-rust` (and `.bat`) to emit
`lcov.info` via
  `cargo-llvm-cov report`
- Added a `SonarCloud Scan` step to the `check-linux` CI job, running
after all
  checks pass and before the build cache is saved

## How to test

### Details

**1. Install sonar-scanner**
```bash
brew install sonar-scanner
```

**2. Generate and configure a token**

Go to [sonarcloud.io](https://sonarcloud.io/) → My Account → Security →
Generate Token
Copy the generated token and export it in your shell:
```
export SONAR_TOKEN=your_token_here
```

**3. Generate coverage reports**
```
just test --coverage
```
Expected output files:

 - out/coverage/python-pylib/coverage.xml
 - out/coverage/python-qt/coverage.xml
 - out/coverage/typescript/lcov.info
 - out/coverage/rust/lcov.info

**4. Run the scanner manually**
```
sonar-scanner
```
Results will appear in the SonarCloud dashboard

To test coverage generation locally:
```bash
just coverage
# verify files exist:
# out/coverage/python-pylib/coverage.xml
# out/coverage/python-qt/coverage.xml
# out/coverage/typescript/lcov.info
# out/coverage/rust/lcov.info
```
2026-08-26 15:48:45 -03:00
Abdo 8e1c571bd1 docs: Document the anki-audio package (#5411)
Some notes about updating the `anki-audio` package.
2026-08-26 21:18:43 +03:00
Abdo c3188ebb67 docs: Fix broken links in dev docs (#5410)
## Linked issue

Closes #5335
Closes #5350

## Summary

Fix broken links in docs/ by replacing relative links (`./linux.md`)
with absolute ones (`/developers/linux`).


## How to test

Confirm all internal links in docs/ work
2026-08-26 21:17:56 +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
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 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
llamaandAbdo 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
znmzandAbdo 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
(https://github.com/ankitects/anki-manual/pull/482/changes/a4d6fb39a76fa6e8b5b3e08c2ade05f4fef92680),
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
roostwp07andAbdo 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
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
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
Luc McgradyandAbdo 7cf1d29896 docs: Replace docs/ with symlinks (#5031)
<!--
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 #123 / Closes #123 / Refs #123 -->
closes #5001

This PR replaces the contents of `docs/` with symlinks to
`docs-site/developers/`

A caveat of this is that the metadata appears at the top of the file
instead of the title.
<img width="885" height="275" alt="image"
src="https://github.com/user-attachments/assets/430f9a71-e5a5-4412-983a-e4cfd7dc4714"
/>

We could either:
- Use ninja to copy the files from docs-site/developers and convert it
from .mdx to .md (Might be a problem with the symlink approach if mdx is
added to the contributor file later)
- Leave placeholder "For contribution instructions see: (link to
mintlify site)"s in the folder, which would have to wait until the
domain of the site is set. (Probably the best solution).

---------

Co-authored-by: Abdo <abdo@abdnh.net>
2026-08-04 22:01:31 +03:00
Jean Khawand 60aa8bf816 fix(syncserver): use built-in --healthcheck instead of wget (#5044)
The wget probe logs a line on every interval, polluting container stdout
in Docker and k3s. The --healthcheck flag exits 0/1 silently, letting
the platform report health without log noise.
2026-06-26 14:02:47 +03:00
RedPine404andAbdo 29a2853f1d fix: Bump rust builder and base image for syncserver (#5036)
## Linked issue (required)

Fixes #5035

## Summary / motivation (required)

Rust builder is outdated an no longer builds the syncserver
successfully.

Bumping the version to match rust-toolchain.toml version 1.92.0 fixes
this issue.

I also bumped the base image to alpine:3.23 as alpine:3.21.0 is over a
year old.

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

docker buildx build -f <Dockerfile> --no-cache --build-arg
ANKI_VERSION=<version> -t anki-sync-server .

## How to test (required)

docker buildx build -f <Dockerfile> --no-cache --build-arg
ANKI_VERSION=<version> -t anki-sync-server .

### Checklist (minimum)

- [x] I ran `docker buildx build -f Dockerfile --no-cache --build-arg
ANKI_VERSION=26.05 -t anki-sync-server .`
- [x] I ran `docker buildx build -f Dockerfile.distroless --no-cache
--build-arg ANKI_VERSION=26.05 -t anki-sync-server .`

### Details

Docker image compiled as expected following the updated versions.

## Scope

- [x] This PR is focused addressing the syncserver docker image.

Co-authored-by: Abdo <abdo@abdnh.net>
2026-06-19 18:10:39 +03:00
Konstantin Tutsch daad13f01f fix: failing syncserver Docker build (#5021)
## Summary / motivation (required)

This PR fixes Docker Image builds for syncserver failing due to a Rust
version being used in both available Dockerfiles that is no longer
supported by the two dependencies `time@0.3.47` and `time-core@0.1.8`.

## Issue

Fixes #5022 

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

1. `cd docs/syncserver`
2. `docker build -f Dockerfile --no-cache --build-arg ANKI_VERSION=26.05
-t anki-sync-server .`
3. Error (see issue)

## How to test (required)

1. `cd docs/syncserver`
2. `docker build -f Dockerfile --no-cache --build-arg ANKI_VERSION=26.05
-t anki-sync-server .`
3. run Docker image

## Scope

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

Signed-off-by: Konstantin Tutsch <mail@konstantintutsch.com>
2026-06-19 18:06:47 +03:00
Abdo 0d7b3fdd96 feat: Remove the uv launcher and old packaging code (#5019)
## Linked issue

Closes #4556
Closes #4557
Closes #4144
Closes #4151
Closes #4152
Closes #4153
Closes #4229
Closes #4356
Closes #4401
Closes #4403
Closes #4519
Closes #4523
Closes #4390
Closes #4414
Closes #4484



## Summary / motivation

After 4 months of exploring Briefcase for packaging, we're confident it
solves most problems with the uv launcher with less complexity and at a
lower maintenance cost, especially with the parallel work on the release
CI, which we already used to make 5 releases.

This also removes platform-specific packaging/signing code used to
produce macOS dmg files and Windows NSIS installers, which is now
largely handled by Briefcase and the release CI.
The custom install scripts for Linux are mostly preserved under
qt/installer/linux-template and used in the Briefcase build.

## How to test

- [ ] No build problems.
- [ ] The `tools/build-installer` scripts still work.
- [ ] No CI/release workflow issues.
- [ ] No user-visible changes in dev environment and Briefcase build.
2026-06-17 03:02:52 +03:00
Luc McgradyandAbdo fbe2d93654 docs: include aqt in tree (#4984)
<!--
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 #123 / Closes #123 / Refs #123 -->
closes #4983

## Summary / motivation (required)

<!-- What this PR does and why. For larger changes, add enough context
for reviewers. -->
This pr adds links to the aqt section of the docs.

### Details

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

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

<img width="306" height="111" alt="image"
src="https://github.com/user-attachments/assets/39111e4f-8aa1-4865-b193-0da949967618"
/>

## Scope

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

---------

Co-authored-by: Abdo <abdo@abdnh.net>
2026-06-10 20:40:29 +03:00
Fernando Lins a62e6f7370 docs: expand contributing guide with PR process and test requirements (#4946)
## Linked issue

Closes #4945

## Summary / motivation 

Two small clarifications to the contributing guide:

- Added a **Pull Request Description** section pointing contributors to
the
  PR template (`.github/pull_request_template.md`), so they know upfront
  what fields are required before opening a PR.
- Strengthened the test coverage requirement from "please consider" to a
clear rule, with explicit exceptions (version bumps, docs, translations,
  dependency updates, chore).
2026-06-02 15:09:47 -03:00
Fernando LinsandAbdo a140d39329 chore(e2e): add Playwright end-to-end test infrastructure (#4864)
## Linked issue

Closes #4863

## Summary / motivation

Adds Playwright as the e2e test framework so contributors can write
browser-based tests against a real headless Anki instance. There was no
automated way to exercise mediasrv pages, SvelteKit routes, or the
`/_anki/` RPC surface from a browser, this PR establishes that harness.

Key pieces:
- `qt/tests/launch_anki_for_e2e.py` — spawns a throwaway Anki instance
(temp `ANKI_BASE`, `QT_QPA_PLATFORM=offscreen`). Pre-seeds `prefs21.db`
so Anki skips the language picker and profile chooser and goes straight
  to serving mediasrv.
- `playwright.config.ts` — points `webServer` at the launcher; polls
  `/favicon.ico` as the readiness probe.
- `ts/tests/e2e/` — `fixtures.ts` base and a sanity spec that verifies
  mediasrv is reachable and a SvelteKit page hydrates.
- `justfile` — `just test-e2e` recipe; Chromium installed to
  `out/playwright-browsers/`.
- CI — e2e step in `check-linux`; failed-run artifacts uploaded for 7
days.
- `docs/e2e-testing.md` — contributor guide covering setup, managed vs
  reuse-server modes, and writing new tests.

## How to test

Build the project once, then run the e2e suite in managed mode (no
separate `./run` needed — the launcher is started automatically):

```shell
just build
just test-e2e
```

## Before / after behavior (optional)
Before: no browser-level test harness existed.
After: `just test-e2e` drives a real headless Anki instance via
Playwright.

## Risk / compatibility / migration
No production code changed. New dev-only files and CI step only.
Chromium is installed to `out/playwright-browsers/` (gitignored) and
does not affect the regular build.

---------

Co-authored-by: Abdo <abdo@abdnh.net>
2026-05-22 15:59:42 -03:00
Fernando LinsandAbdo c1b824258e feat: add test coverage docs (#4844)
## Linked issue

Refs #4838 #4839 #4840

## Summary / motivation

Adds a contributor-facing guide for the test coverage setup introduced
across the three coverage PRs, and updates CLAUDE.md to reflect that
`just` is now the single entry point for all build, test, lint, and
format commands.

## How to test

- Read `docs/testing-coverage.md` — verify it covers all three stacks,
  thresholds, and the known gaps section.
- Run `just docs` and open `out/docs/html/index.html` to confirm
  `testing-coverage` appears in the sidebar under Contributing.
- Read `CLAUDE.md` — verify `./ninja` / `./tools` references are gone
  and `just test-rust`, `just test-py`, `just test-ts` are mentioned.

### Details

- `docs/testing-coverage.md`: documents tools, thresholds, per-stack
  entry points, and known gaps for all three coverage stacks.
- `docs/index.md`: wired `testing-coverage` into the Sphinx toctree
  after `contributing`.
- `CLAUDE.md`: replaced raw `./ninja` / `./tools` invocations with
  `just` equivalents; added top-level note directing contributors to
  `just --list`; added `just test-rust`, `just test-py`, `just test-ts`
  to the Quick iteration section.

---------

Co-authored-by: Abdo <abdo@abdnh.net>
2026-05-20 16:21:23 -03:00
Andrew Sanchez 428406d8a6 Release infrastructure improvements (#4802)
- Run CI automatically on `release/**` branches
- Update just recipes: require `--ref`, add `--version` to prepare, add
`testpypi`/`pypi` recipes
- Document release branch workflow and update releasing docs
- Add `sphinxcontrib-mermaid` for Sphinx doc rendering
2026-05-09 17:34:18 -04:00
Fernando Lins eb942793ae docs: add contributing guidelines for add-ons, linked issues, and AI-assisted PRs (#4782)
## Summary / motivation (required)

Adds three new sections to `docs/contributing.md` to address recurring
pain points in PR reviews:

- **Consider an Add-on First**: encourages contributors to explore the
add-on API before proposing core features, to keep the codebase lean.
- **Linked Issues**: makes it explicit that every non-trivial PR must be
linked to an open issue, with a note that unlinked PRs may be
auto-closed.
- **AI-Assisted Contributions**: sets expectations for AI-generated
code: it's allowed, but contributors must understand and review every
change they submit.

### Details

Read `docs/contributing.md` and verify the three new sections render
correctly and are consistent in tone with the existing content.
2026-05-07 16:12:45 -03:00
f9570d31c2 ci: support releases from non-main branches (#4794)
Closes #4793

- Add `workflow_dispatch` trigger to CI (with macOS/Windows support)
- Allow prepare-release and release workflows from any branch
- Add `skip-ci-check` input for hotfix releases
- Add `just release::prepare` and `just ci` recipes
- Make `qt/release/build.sh` find uv in CI and local builds
- Change publish-testpypi environment from testpypi to release
- Add anki-release wheel build step

---------

Co-authored-by: Andrew Sanchez <andrewsanchez@users.noreply.github.com>
Co-authored-by: Fernando Lins <1887601+fernandolins@users.noreply.github.com>
2026-05-07 14:46:15 -04:00
5a9b54e938 Briefcase Installer (#4629)
migrates Anki Desktop packaging from the legacy
NSIS/uv-based installer to [BeeWare
Briefcase](https://briefcase.readthedocs.io/). This branch integrates
work from many related issues and PRs to deliver cross-platform native
installers (MSI on Windows, .app on macOS, PyInstaller on Linux) with
code signing, notarization, and file association support.

## Integrated PRs

- #4585 — Set up Briefcase
- #4596 — Add Briefcase icons
- #4598 — Handle Briefcase file associations
- #4601 — Add Briefcase app permissions
- #4609 — Customize Briefcase's MSI installer
- #4616 — Set up Briefcase code signing and notarization
- #4618 — Fix Briefcase packaging for x86 Macs
- #4623 — Customize Briefcase's Linux template
- #4627 — List required Debian packages for Briefcase installer
- #4630 — Update Briefcase's Windows template
- #4631 — Rewrite Linux install/uninstall scripts for PyInstaller
- #4638 — Use PyInstaller on Linux
- #4645 — Update installer docs
- #4654 — Disable Briefcase's universal builds for macOS
- #4672 — Deal with existing NSIS installations in MSI installer
- #4676 — Remove duplicate Briefcase icons
- #4677 — Tweak Linux scripts for new installer
- #4709 — Add anki-console.bat to Briefcase's Windows package

## Related Issues

- #4557 — Evaluate BeeWare Briefcase for Anki packaging and distribution
- #4678 — Support native Windows ARM64 builds for Briefcase
- #4688 — Linux installer: migrate to PyInstaller and rewrite install
scripts
- #4689 — Investigate startup performance with Briefcase
- #4690 — Specify required Linux system packages for Briefcase
- #4691 — Investigate Windows ARM64 support with Briefcase
- #4692 — Test on Linux ARM with Briefcase
- #4693 — Separate ARM and Intel macOS releases
- #4694 — Update developer documentation for Briefcase installer
- #4695 — Support upgrade/downgrade with the Briefcase installer
- #4696 — Update user documentation for new installer
- #4702 — Update Briefcase's Windows template with upstream security fix
and OS version check
- #4703 — Follow-up tweaks to Linux install/uninstall scripts

## Related PRs

- #4619 — Enable Windows ARM64 support
- #4632 — Release action

---------

Co-authored-by: Abdo <abdo@abdnh.net>
Co-authored-by: Andrew Sanchez <andrewsanchez@users.noreply.github.com>
Co-authored-by: Fernando Lins <1887601+fernandolins@users.noreply.github.com>
2026-05-05 17:29:18 -04:00
Abdo 81eefc5f71 Render GH Markdown alerts in Sphinx docs (#4663)
See
https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts

We started using this syntax recently: #4466 #4662

## How to test

See preview:
https://anki-core--4663.org.readthedocs.build/en/4663/windows.html
2026-04-08 19:10:17 +03:00
cypher 65f45ea87d Update docker build command for syncserver (#4562)
The command for building the image does not include the` --platform`
flag which prevents the image from running across all architectures. For
example, if I build the image on an ARM system and then try running on
x86, it won’t work.

This issue can be fixed by using `docker buildx` and adding the flag to
include all of the platforms. I have tested this by building the image
with the `linux/arm64` and `linux/amd64` platform flags on an ARM system
and then running a container with that image on an x86 system.

This would be useful in scenarios where the syncserver runs on devices
that cannot do builds.

The correct command would be 
```bash
# Builds for all existing platforms supported by Docker
docker buildx build -f <Dockerfile> --platform linux/amd64,linux/arm64,windows/amd64 --no-cache --build-arg ANKI_VERSION=<version> -t anki-sync-server .
```
Reference: https://docs.docker.com/build/building/multi-platform/
2026-04-07 16:51:28 +03:00
Fernando Lins 447795bbb9 Add pre-commit for automated pre-push checks (#4660)
## Description / motivation

Versioned hook configuration and a single documented install path reduce
friction and drift between machines compared to copy-pasted shell hooks.

## How to test

1. `$ uv sync --group dev`
2. `$ uv run pre-commit install --hook-type pre-push`
3. Make any change, commit it, and push it

<img width="908" height="253" alt="image"
src="https://github.com/user-attachments/assets/d492e2a8-9f33-4adf-866e-04c54cbf57d9"
/>

### Details

- Add `.pre-commit-config.yaml` with a **pre-push** hook that runs
`./ninja check`
- Add `pre-commit` to the `dev` dependency group and refresh `uv.lock`.
- Update `docs/contributing.md`: contributors install hooks via `uv run
pre-commit` / `python -m pre_commit`, and drop the old suggestion of
manual `.git/hooks` scripts.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - -
2026-04-06 12:04:49 -03:00
user1823 869cfad899 Update Windows developer docs (#4662)
When I started building on Windows, I noticed some issues in the
documentation. This fixes most of them.
2026-04-03 15:41:44 +03:00
Daniela Silvaanduser1823 3ecde15621 Add Windows quick start guide for new contributors (#4466)
This pull request adds a beginner-friendly quick start guide for
building Anki on Windows.

The guide is intended to help first-time contributors set up their
development environment more easily, without replacing or modifying the
existing official documentation.

No existing files were changed; this contribution only adds a
complementary Markdown document.

---------

Co-authored-by: user1823 <92206575+user1823@users.noreply.github.com>
2026-04-02 20:44:34 +03:00
Oli f8669fc4be Add punctuation, convert raw URLs to markdown links in READMEs (#4570) 2026-04-01 10:23:23 -03:00
Andrew Sanchez 6b61393d87 Build and publish dev docs (#4579) 2026-03-31 08:26:59 -04:00
user1823 b40c3c8e6b Docs/Add more required packages to Linux build guide (#4432)
* Docs/Add more required packages to Linux build guide

Updated package installation instructions for Debian/Ubuntu to include gcc-12 and libxkbfile1.

* Add Arch Linux requirements
2026-02-11 16:57:11 +07:00
GithubAnon0000andDamien Elmes a203b0b3e5 UPDATE(docs): Add build dependencies and instructions for building / running the launcher (#4380)
* ADD Dependencies for linux when building the launcher

I only downloaded `gcc-aarch64-linux-gnu` (on my x86_64 debian sid) and it was able to successfully build the launcher.

* ADD example build / run instructions for the launcher for linux

* CHORE: ninja format && fix

* ADD: Entries for Mac and Windows

* FIX: Wrong level was applied to a header

* CHORE: ninja fix && format

* FIX: Sentence structure

* FIX: casing (thanks dae)

Co-authored-by: Damien Elmes <dae@users.noreply.github.com>

* FIX: casing

* FIX: binary statement (only linux has amd64 and arm64 versions)

* UPDATE: Include env vars for Win and Mac

* CHANGE: include env vars for Win and Mac in the table instead
2026-02-11 15:14:55 +07:00
Abdo d3ca0cd0b3 Update PyCharm docs (#4389)
* Add .idea.dist

* Update PyCharm docs
2025-10-27 19:27:50 +07:00
Emil Hamrin 7e8a1076c1 Updated Dockerfile to use Ninja build system (#4321)
* Updated Dockerfile to support ninja build

* Install python using uv

* Bumped python version

* Add disclaimer (dae)
2025-09-17 14:02:09 +10:00
Abdo f94d05bcbe Switch to Ruff (#4119)
* Add check:ruff build action

* Add fix:ruff action

* Add Ruff config

Mostly generated by Cursor

* Handle rest of lints

* Fix formatting

* Replace black and isort with ruff-format

* Run ruff-format

* Fix lint errors

* Remove pylint disables

* Remove .pylintrc

* Update docs

* Fix check:format not just checking

* Fix isort rule being ignored

* Sort imports

* Ensure ./ninja format also handles import sorting

* Remove unused isort cfg

* Enable unsafe fixes in fix:ruff, and enable unused var warning

* Re-run on config change; enable unnecessary ARG ignores

* Use all pycodestyle errors, and add some more commented-out ones

Latter logged on https://github.com/ankitects/anki/issues/4135
2025-06-29 14:38:35 +07:00
Damien Elmes 8e20973c52 Drop remaining qt5 code 2025-06-20 16:13:50 +07:00
Damien Elmes 04996c77f3 Migrate build system to uv (#4074)
* Migrate build system to uv

Closes #3787, and is a step towards #3081 and #4022

This change breaks our PyOxidizer bundling process. While we probably
could update it to work with the new venvs & lockfile, my intention
is to use this as a base to try out a uv-based packager/installer.

Some notes about the changes:

- Use uv for python download + venv installation
- Drop python/requirements* in favour of pyproject files / uv.lock
- Bumped to latest Python 3.9 version. The move to 3.13 should be
a fairly trivial change when we're ready.
- Dropped the old write_wheel.py in favour of uv/hatchling. This has
the unfortunate side-effect of dropping leading zeros in our wheels,
which we could try hack around in the future.
- Switch to Qt 6.7 for the dev repo, as it's the first PyQt version
with a Linux/ARM WebEngine wheel.
- Unified our macOS deployment target with minimum required for ARM.
- Dropped unused fluent python files
- Dropped unused python license generation
- Dropped helpers to run under Qt 5, as our wheels were already
requiring Qt 6 to install.

* Build action to create universal uv binary

* Drop some PyOxidizer-related files

* Use Windows ARM64 cargo/node binaries during build

We can't provide ARM64 wheels to users yet due to #4079, but we can
at least speed up the build.

The rustls -> native-tls change on Windows is because ring requires
clang to compile for ARM64, and I figured it's best to keep our Windows
deps consistent. We already built the wheels with native-tls.

* Make libankihelper a universal library

We were shipping a single arch library in a purelib, leading to
breakages when running on a different platform.

* Use Python wheel for mpv/lame on Windows/Mac

This is convenient, but suboptimal on a Mac at the moment. The first
run of mpv will take a number of seconds for security checks to run,
and our mpv code ends up timing out, repeating the process each time.
Our installer stub will need to invoke mpv once first to get it validated.

We could address this by distributing the audio with the installer/stub,
or perhaps by putting the binaries in a .pkg file that's notarized+stapled
and then included in the wheel.

* Add some helper scripts to build a fully-locked wheel

* Initial macOS launcher prototype

* Add a hidden env var to preload our libs and audio helpers on macOS

* qt/bundle -> qt/launcher

- remove more of the old bundling code
- handle app icon

* Fat binary, notarization & dmg

* Publish wheels on testpypi for testing

* Use our Python pin for the launcher too

* Python cleanups

* Extend launcher to other platforms + more

- Switch to Qt 6.8 for repo default, as 6.7 depends on an older
libwebp/tiff which is unavailable on newer installs
- Drop tools/mac-x86, as we no longer need to test against Qt 5
- Add flags to cross compile wheels on Mac and Linux
- Bump glibc target to 2_36, building on Debian Stable
- Increase mpv timeout on macOS to allow for initial gatekeeper checks
- Ship both arm64 and amd64 uv on Linux, with a bash stub to pick
the appropriate arch.

* Fix pylint on Linux

* Fix failure to run from /usr/local/bin

* Remove remaining pyoxidizer refs, and clean up duplicate release folder

* Rust dep updates

- Rust 1.87 for now (1.88 due out in around a week)
- Nom looks involved, so I left it for now
- prost-reflect depends on a new prost version that got yanked

* Python 3.13 + dep updates

Updated protoc binaries + add helper in order to try fix build breakage.
Ended up being due to an AI-generated update to pip-system-certs that
was not reviewed carefully enough:
https://gitlab.com/alelec/pip-system-certs/-/issues/36

The updated mypy/black needed some tweaks to our files.

* Windows compilation fixes

* Automatically run Anki after installing on Windows

* Touch pyproject.toml upon install, so we check for updates

* Update Python deps

- urllib3 for CVE
- pip-system-certs got fixed
- markdown/pytest also updated
2025-06-19 14:03:16 +07:00
Kolby Moroz Liebl 6427ff3db5 Fix dockerimage, by bumping rust version (#3993) 2025-05-15 16:09:27 +10:00
Divyansh Kushwaha 6a07c6e561 docs: correct reference for linux dockerfile (#3982) 2025-05-05 18:57:08 +10:00
Arthur Milchior ab75e3d49b Introduce language_bridge.md (#3572)
This commit explains how to calls a method implemented in a language
from a different language.

This explains how to declare the RPCs, how to call them and how to
implement them. This is based on examples of code at main at the time
of writting. I used permalink to ensure that the links remains
relevant even if the specific examples change later.

The last section is about the special case of calling TypeScript from
Python, which does not use RPC but is still relevant in a bridge
document.

This commit also add a paragraph explaining what protobuf is in the
protobuf documentation, so that new contributors who don't know what
protobuf is can understand why we use it.
2025-04-10 15:30:18 +10:00
llamaandSimon d809ee92db Fix cargo ignoring lockfile when building syncserver image (#3856)
* pass --locked to cargo invocation

* update Dockerfile.distroless as well

Co-authored-by: Simon <8466614+SimonBaars@users.noreply.github.com>

---------

Co-authored-by: Simon <8466614+SimonBaars@users.noreply.github.com>
2025-03-14 17:04:56 +07:00
Omar Kohl eaec53bfc4 Ignore SYNC_PORT and SYNC_BASE in syncserver Dockerfile (#3716)
Hardcode them to:

    SYNC_PORT=8080
    SYNC_BASE=/anki_data

If these env variables are passed into the container with different values,
they are ignored.

The reasons is if the user modifies SYNC_BASE they risk data loss since
anki-sync-server will no longer write data into the volume. If they change
SYNC_PORT they need to also change it when mapping this internal port to the
external port of the container, which could be confusing plus it has no benefit
to allow this since it's always possible to change the external port even if
the internal port is fixed to 8080 (e.g. `-p 1234:8080`).

In both cases there is no benefit to making these values configurable and there
are risks associated.

Unfortunately there is no easy way of implementing this for the
Dockerfile.distroless so it's up to the user not to modify these values.
2025-01-25 19:28:55 +11:00
Omar Kohl 71e2a6f782 Introduce PUID and PGID env variables to syncserver Dockerfile (#3714)
PUID and PGID are optional env variables to specify the user and group id of
the user that the anki-sync-server process should run with.

This gives more flexibility for solving permission problems with volumes and is
a common pattern for Docker images (e.g. see here:
https://docs.linuxserver.io/general/understanding-puid-and-pgid/)

The anki-sync-server process will write any files with the permissions of the
user it's running with, which can be a problem when you need to access those
files from outside the container or when they are being written into a bind
mount that is owned by a particular user on the host system.

To be able to implement this the entrypoint.sh needs to run as root (since it
needs to create a user and change file permissions). anki-sync-server then
needs to be started with the user 'anki', which is why the new dependency
'su-exec' is required. The user 'anki' and group 'anki-group' can no longer be
created at image build time because then their ids would be fixed.

Also update the build instructions to require building the Docker image inside
the directory where the Dockerfile resides since the build now needs to copy
the entrypoint.sh and it seems wrong the specify the path
docs/syncserver/entrypoint.sh inside the Dockerfile.
2025-01-25 18:19:38 +11:00