## 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>
## 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.
## 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.
## 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.
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>
## 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.
## Linked issue
Closes#5335Closes#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
## 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.
## 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>
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>
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>
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.
<!--
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>
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.
## 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>
## 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>
## Linked issue
Closes#4556Closes#4557Closes#4144Closes#4151Closes#4152Closes#4153Closes#4229Closes#4356Closes#4401Closes#4403Closes#4519Closes#4523Closes#4390Closes#4414Closes#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.
<!--
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>
## 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).
## 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>
## 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>
## 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.
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>
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>
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/
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>
* 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
* 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
* 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
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.
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.
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.