docs/Design/Autoupdate/Platforms.md
A WeKan release ships three kinds of artifact, and they are built in this order because each one is made out of the one before it:
wekan-<version>-<arch>.zip the bundle: the app, its Node.js, its database
│
├──────────────► the snap (takes its Node.js from the bundle)
└──────────────► the Docker image (unpacks the bundle for that arch)
So a platform can only have a snap or an image if it has a bundle, and it can only have a bundle if it has the two binaries a bundle carries: a database and a Node.js runtime.
FerretDB v1 — wekan/FerretDB
builds ferretdb-<arch> for sixteen targets, and that is the widest of the two
lists. Every non-amd64, non-arm64 platform uses it: MongoDB ships no server for
any of them.
Node.js 24 — three sources, tried in this order by the bundle job, which prints which one served:
node.yml in wekan/node for the platforms
the first two do not publish at all.The first two ship a tarball (node, npm, the whole runtime). The fork ships the bare binary it built, because that is the only part missing — so when the fork serves, npm is taken from the official amd64 tarball of the same version. npm is JavaScript and runs on whatever node executes it, so an npm built for one CPU drives a node built for another.
| Platform | Bundle | Snap | Docker | FerretDB asset | Node.js from |
|---|---|---|---|---|---|
| amd64 | ✅ | ✅ | ✅ | ferretdb-amd64 | official |
| arm64 | ✅ | ✅ | ✅ | ferretdb-arm64 | official |
| ppc64le | ✅ | ✅ ppc64el | ✅ | ferretdb-ppc64le | official |
| s390x | ✅ | ✅ | ✅ | ferretdb-s390x | official |
| riscv64 | ✅ | ✅ | ✅ | ferretdb-riscv64 | unofficial |
| i386 | ✅ | ✅ | ✅ linux/386 | ferretdb-i386 | fork (node-i386) |
| armhf | ✅ | ✅ | ✅ linux/arm/v7 | ferretdb-armhf | fork (node-armv7) |
| loong64 | ✅ | — | — | ferretdb-loong64 | fork (node-loong64) |
Three vocabularies meet in that table and they disagree, which is why the build
matrix names all three separately (arch, node_arch, ferretdb_arch):
A row that named only one of them would download another CPU's binary and the mistake would not show until somebody ran it.
armel (ARMv5, soft-float) — FerretDB builds it; Node.js cannot. V8 has not supported ARMv5 for many years, nobody publishes a runtime for it, and the fork cannot make one either. A bundle with no runtime in it is not a bundle.
loong64 snap and image — the bundle exists, but loong64 is not a snap
architecture, and buildx and the three registries do not agree on it yet. It
ships as a .zip.
Windows, macOS x64, FreeBSD — out of scope for these three artifacts rather
than impossible: the snap and the image are Linux, and a Windows or FreeBSD
Node.js needs its own host to build on rather than a cross compiler on a Linux
runner. macOS arm64 has a bundle of its own already (build-mac-arm64).
tests/releaseSnapArches.test.cjs reads the four lists — the bundle matrix, the
snap platforms: block and its arch mapping, the snap-launchpad matrix and the
Docker --platform list — and checks they agree: that every snap arch has a
bundle behind it, that every bundle row names all three vocabularies, and that
buildx builds exactly the platforms whose push is then verified. They were
edited one at a time before, which is how an arch ends up with a .zip and no
snap, or a snap that downloads a bundle nobody built.
.github/workflows/release-all.yml — the bundle, snap and image jobsnode.yml in wekan/node — the fork's builds