Wekan logo

Wekan

Open source kanban board application built with Meteor

Alternative to: trello


About Versions (218)

v10.81

2026-08-11

Binaries in these bundles

Each bundle carries a Node.js, a FerretDB and the MongoDB Database Tools. Which source has a given CPU varies from release to release - nodejs.org builds some architectures, unofficial-builds others, and the wekan/node-patches build the ones neither of them does - and not every source publishes a checksum. This is what went into this release, and which downloads were checked against a published SHA256.

BundleBinaryFromVersionCheckedSHA256
amd64FerretDBwekan/FerretDBv1.49.0verified7c74941ff043f26a…
amd64Node.jsnodejs.orgv24.19.0verified14b342e71204f811…
arm64FerretDBwekan/FerretDBv1.49.0verified092132531555a39e…
arm64Node.jsnodejs.orgv24.19.0verified01443c1e1a29e531…
armhfFerretDBwekan/FerretDBv1.49.0verified144404fb9793dc8e…
armhfNode.jswekan/node-patchesv24.19.0verifiedb55350f3071b765a…
armv6FerretDBwekan/FerretDBv1.49.0verified7c27b2c15448709a…
armv6Node.jswekan/node-patchesv24.19.0verified128ded0cda638c1f…
armv7FerretDBwekan/FerretDBv1.49.0verified144404fb9793dc8e…
armv7Node.jswekan/node-patchesv24.19.0verified8dbe0a9aa8550ad5…
i386FerretDBwekan/FerretDBv1.49.0verified1f70cb1687411b2a…
i386Node.jswekan/node-patchesv24.19.0verified3b0b3bbfe27daf58…
mac-arm64FerretDBwekan/FerretDBv1.49.0verified576364db59dfce3b…
mac-arm64Node.jsnodejs.orgv24.19.0verified3f1cf157479c1480…
mac-x64FerretDBwekan/FerretDBv1.49.0verified37d70cd90aad6d38…
mac-x64Node.jsnodejs.orgv24.19.0verifiedd35e95230f46f6f0…
ppc64leFerretDBwekan/FerretDBv1.49.0verified7c61d4853d5163ad…
ppc64leNode.jsnodejs.orgv24.19.0verifiedc510c6ce12f07010…
riscv64FerretDBwekan/FerretDBv1.49.0verifiedbd4912da70f5e6c1…
riscv64Node.jsunofficial-builds.nodejs.orgv24.19.0verifiedcd1f14af28121480…
s390xFerretDBwekan/FerretDBv1.49.0verified62900110fc3e8165…
s390xNode.jsnodejs.orgv24.19.0verifieda4792e65962ffa0a…
win-arm64FerretDBwekan/FerretDBv1.49.0verified792166623e774b0a…
win-arm64Node.jsnodejs.orgv24.19.0verified8502f4a50b458d4c…
win64FerretDBwekan/FerretDBv1.49.0verifiedf42c50aa84095a96…
win64Node.jsnodejs.orgv24.19.0verified57f71ab3652e797d…

A row saying no checksum published is not a failed check - it is a source that publishes nothing to check against. Those are the ones worth fixing at the source.

v10.81 2026-08-11 WeKan ® release

In short: the release pipeline, and two bugs that stopped WeKan starting at all. FerretDB advertises its own listen address as the member list of a one-node replica set, so the MongoDB driver threw away the host in MONGO_URL and dialled 0.0.0.0:27017 instead - a fresh docker compose up could not reach its database, and every FerretDB compose file now says directConnection=true. All Boards on a phone could not be scrolled to its last boards, its Table view could not be scrolled at all, single rows of board icons were drawn several times their proper height, and the icons sat too close together - four separate causes, one of them a calc(100dvh - 48px) in layouts.css that guessed at a header height which is measured at runtime precisely because it is never one number. On the release side: the Mac x64 bundle has never once been built, because its runner label was retired by GitHub and a retired label queues forever instead of failing - and cancelling that queue is what silently skipped the charts, ucs and nextcloud jobs. The armv6 bundle was being assembled in a soft-float ARMv5 userland that its own hard-float Node.js cannot start in, and every Launchpad snap was ended by an optional MongoDB-migration part that stages a path it does not build outside amd64 and arm64. Below that: a report of the WeKan releases the Helm chart index is missing, and the duplicate entries found in it. The binaries below are v10.80’s: nothing here rebuilds them.

PlatformBinaryFromVersionSHA256
amd64Node.jsnodejs.orgv24.19.014b342e71204f811bde6153be8e04b62aef63c236fef92b55f9c83154b409647
amd64FerretDBwekan/FerretDBv1.48.02737687fd29a8a761cd960e45f300b68cf7b4a87d50c4cc5280bcbd42b6aa163
arm64Node.jsnodejs.orgv24.19.001443c1e1a29e531ccad5a46fefa6df490d2189c49f7955904aecdbb0fe86fdc
arm64FerretDBwekan/FerretDBv1.48.05ae705dd49515a4ecd4e295c3b9aa4f3b454fad78613ec60fb99316bd7c34e3f
loong64Node.jsunofficial-builds.nodejs.orgv24.19.0c24f224726f2d785bd18a1fd09f5e6d1fecf0269928451a60c5da9eac8e92e68
loong64FerretDBwekan/FerretDBv1.48.006ec86263455a7b598d22a87df0e044ea73ab5a3b72e96ad12ebed03c1374ac2
mac-arm64Node.jsnodejs.orgv24.19.03f1cf157479c1480352083105e13faf9d008ede98e7e157746b6df940d197b94
mac-arm64FerretDBwekan/FerretDBv1.48.09b15f4c10e473cd0a2c4feb4cb43e18042bd60c7035ec66cab3cfbe13edaabab
mac-x64Node.jsnodejs.orgv24.19.0d35e95230f46f6f0751df497c56622c6735e05d5e1fb1630996a005b9d328fe4
mac-x64FerretDBwekan/FerretDBv1.48.04e188246dfa33bccef4cdd86701bc498b037cb3e91f579ff0dccb93aa0ef03ad
ppc64leNode.jsnodejs.orgv24.19.0c510c6ce12f07010f771e6edb22a3fe23f4f2e6f40b1ffd4941aed0646a0d8b3
ppc64leFerretDBwekan/FerretDBv1.48.00400cd6dfc3d10d987a0fe80d75baa86c03c19170770fa2e602c92d558c3cfa6
riscv64Node.jsunofficial-builds.nodejs.orgv24.19.0cd1f14af2812148002f58b58a5f9af512a50e3b8e8c148e0db44019dcb68edfd
riscv64FerretDBwekan/FerretDBv1.48.0d37c35af988670b9ed182b8c5966c06a06362f6c6ace6aebd93ccdfa32c9a26b
s390xNode.jsnodejs.orgv24.19.0a4792e65962ffa0af42627aacf1122a60c3c88dbf4e4184f06820d66f9da8ba4
s390xFerretDBwekan/FerretDBv1.48.06c7d61fbb8c79b2e8733be8f71910f710e8c5cd25208c451bdc513c8313b0340
win64Node.jsnodejs.orgv24.19.057f71ab3652e797d84acddc79c81cc9ff1c6ddb2a1974cdb83f00fee9bff4c73
win64FerretDBwekan/FerretDBv1.48.0ea57e1bcd153b51d2065ab01515b21ec05d8f615444c15603ab8158b8a661dd2

This release fixes the following bugs:

FerretDB - the default database, and how WeKan is told to reach it.

Connect with directConnection=true, so a fresh docker compose up starts. Thanks to Dandrass and xet7.

A new install with nothing changed but the port and ROOT_URL could not reach the database:

MongoServerSelectionError: connect ECONNREFUSED 0.0.0.0:27017
reason: TopologyDescription { type: 'ReplicaSetNoPrimary',
        servers: Map(1) { '0.0.0.0:27017' => [ServerDescription] },
        setName: 'rs0', ... }

0.0.0.0 is in no compose file. It is FerretDB’s own listen address, and the driver was handed it by the server. The ferretdb service runs with --repl-set-name=rs0 - added in #6480 so Meteor can tail an OpLog instead of poll-and-diff - so FerretDB answers the hello handshake as a one-member replica set and fills hosts, me and primary with its --listen-addr. A driver not in direct-connection mode reads that as an invitation to do replica-set discovery: it adopts the advertised member list and drops the seed it was given, because the server reports a name other than the one that was dialled. mongodb://ferretdb:27017 became 0.0.0.0:27017, which inside the wekan-app container is that container itself.

Measured against FerretDB v1.49.0 with the driver the bundle ships: without the parameter the topology ends up ReplicaSetWithPrimary with the seed discarded, with it the topology is Single on the host that was given. It costs nothing else - the handshake still reports setName: rs0, the only thing Meteor checks before it will tail an OpLog. All five FerretDB v1 compose files carry it; the MongoDB ones deliberately do not, being real replica sets whose members are reachable under the names they advertise.

All Boards on a phone - the scroll, the tiles and the spacing between them.

The board list scrolls to its last board, the Table view scrolls at all, and the tiles are their own size. Thanks to mimZD and xet7.

Four things at once, in an issue reopened against 10.10, 10.37, 10.38, 10.72 and 10.77.

THE SCROLL. Every earlier fix removed viewport arithmetic from boardsList.css. The last piece of it was in layouts.css: body.mobile-mode #content { height: calc(100dvh - 48px) }. 48px is a guess at the height of the header, and the header is not 48px and is not any one number - --wekan-header-height is published from a ResizeObserver for exactly this reason. On a phone whose bar wraps, #content was taller than the room under the header, its bottom sat below the screen, and body.mobile-mode is position: fixed and overflow: hidden, so that strip is unreachable. Nothing needs computing: body is a flex column of one viewport and #content is its flex: 1 item.

THE TABLE VIEW. The right column has two branches - the board icons and +tablePage - and only the icons were ever given a scroller, so in Table view the rows past the fold were clipped with nothing to scroll.

THE 4x-TALL TILES. A grid defaults to align-content: stretch, so a list shorter than its column has the leftover height divided among its rows and each tile grown into it - and a board tile paints its colour over the whole cell. This was fixed once, but only on .board-list.mobile-view; the phone media query builds a grid too, and a narrow window that is not a mini screen took that path.

THE SPACING. An 8px grid gap plus a margin-bottom: 0.5rem per tile: 16px between rows and 8px between columns, which reads as crowded sideways. One value now, in both directions. The mobile full-screen popup had the same class of bug as the first and states dvh now too. Desktop is unaffected.

and fixes the following release-pipeline failures:

The release workflow - which jobs run, and on what.

The retired Mac runner, the jobs a cancellation skipped, and the armv6 userland. Thanks to xet7.

build-mac-x64 asked for macos-13, and GitHub has retired that image - actions/runner-images publishes macos-14, macos-15 and macos-26 only. A retired label does not fail: the job QUEUES, for a runner that is never coming. It has been sitting there every release until cancelled by hand, and no WeKan release has ever carried a wekan-<version>-mac-x64.zip because of it. Intel macOS was renamed, not removed: macos-15-intel, which is what TSC already builds on.

Cancelling it is what skipped charts, ucs and nextcloud: a cancelled job cancels the run, and a cancelling run skips every job that has not started - so all three were skipped the second the docker job they wait on succeeded, after everything had already shipped. A job whose if is always() still runs while a run is cancelling, so the three now say always() and name the needs that must have succeeded.

The armv6 bundle died on qemu-arm: Could not open '/lib/ld-linux-armhf.so.3'. Debian has no ARMv6 port

  • debian:trixie publishes arm/v5 and arm/v7 - and containerd treats a lower ARM variant as compatible, so --platform linux/arm/v6 quietly resolved to arm/v5: Debian armel, soft-float, with no hard-float loader in it. The preflight compared the architecture and ignored the variant, so it never said so; it compares both now, and armv6 is built in Debian’s arm/v7 container, which is armhf and runs node-armv6 fine. Nothing ARMv7 reaches the bundle - the container compiles nothing, and node, FerretDB and the MongoDB tools are all downloaded already built for ARMv6 - except the bundled qemu-user, which is copied out of the container and is therefore skipped for that one bundle.

The snap - what the four Launchpad architectures were really failing on.

An optional part was ending every Launchpad build. Thanks to xet7.

armhf, s390x, ppc64el and riscv64 all failed, three attempts each, and the job reported it as a Launchpad problem: “often an OOM in the Meteor npm install, or a transient build-farm reset; re-run”. It was neither. The build log said the same deterministic thing every time:

Staging mongo42
Failed to copy '/build/.../parts/mongo42/install/mongo42': no such file or
directory. Build failed

The mongo42 part downloads MongoDB 4.2 so a database from an old MongoDB snap can still be migrated (#6471), and MongoDB publishes 4.2 for amd64 and arm64 only. Everywhere else the part prints “nothing to migrate from there; skipping” and exits 0 having created nothing - its own comment calls that optional by design. It was not: the part also carries stage: [mongo42], and snapcraft does not skip a filter whose path is missing, it ends the build. So a migration helper no exotic architecture has ever needed took the whole snap down on exactly the four that can only be built on Launchpad. The directory is created before anything can decide to skip; the binary is still downloaded only where it exists.

riscv64 additionally lost its last attempt to npm ERR! code ECONNRESET on one tarball, after half an hour of building - every request there goes through Launchpad’s proxy - so that npm install is retried three times. The ::error:: no longer guesses: it sends the reader to the build log printed above it.

and improves the release tooling:

The Helm chart index - which WeKan releases it lists.

Report the releases the chart index is missing, and repair its duplicates. Thanks to xet7.

A chart entry is written once, during the release it belongs to, so a release whose charts job did not run leaves a hole nothing ever fills. Counted against the live index: 216 of 690 WeKan releases have a chart entry.

releases/backfill-charts.sh answers which releases the index should list - the ones that exist and can be installed. 216 are kept (never repackaged; that would change a digest helm clients have seen), 369 could be built, and 162 are OMITTED because they have no container image on ghcr: a chart is a pointer to an image, so an entry for one of those is an install that fails at the pull. The index is rebuilt from the packages actually present, so omission needs no bookkeeping.

It also found something already wrong: the published index has four entries for 9.36.0 and two for 10.30.0, each with a different digest and the same url, because the release script prepends an entry every time it runs. At most one of those digests can be the one of the package really served, and a helm client that picks another fails the integrity check on a good file. The rebuild keeps the entry whose digest matches the package, falling back to the newest only when there is no package to compare against. Nothing is written without --apply and nothing is pushed without --push; the charts job runs it in plan mode only, into the run summary.

Rebuild the Helm index.yaml from the chart packages it actually serves. Thanks to xet7.

With the charts repository cloned it became clear the index had drifted from its own packages in four ways at once, all from the same habit: an entry was written by COPYING the previous entry and substituting a few fields, so the index was being kept as the record rather than as a description of the .tgz files beside it.

146 packages had no entry at all - 362 packages, 220 entries. They are downloadable by URL but invisible to helm search, to helm install wekan --version 9.63.0 and to Artifact Hub. 9.36.0 had four entries and 10.30.0 two, each copy with a different digest and the same url, so a client could pick a digest matching no file and fail integrity on a good package. appVersion was the CHART version on every entry - 10.79.0 where the package says 10.79, which is the WeKan version a reader is looking for. And every entry claimed the mongodb subchart was 0.7.2, a field nobody substituted, while the packages had long since moved to 0.7.6.

releases/reindex-charts.py derives the index from the packages, reading each one’s Chart.yaml out of the archive, so an entry cannot describe a package wrongly. Nothing is invented: created is preserved exactly on every entry whose digest matches its package, and a package being added takes the date it was committed to gh-pages, which is when it was really published. Two 2023 packaging slips - wekan-1.2.7.tgz containing chart 1.2.6, and wekan-6.96.tgz containing 6.9.6 - are reported and left out rather than making one version mean two files; both files stay on the server.

The index went from 220 entries to 360, and was checked after writing: no repeated version, every digest equal to the sha256 of its file, every file present, and no version that was listed before missing.

Both release workflows publish the chart, and the index is derived rather than edited. Thanks to xet7.

The charts repository keeps the chart SOURCE on main and the published packages plus index.yaml on gh-pages, and its own two scripts move between them: release.sh commits the source, tars wekan/ into wekan-<version>.0.tgz, checks out gh-pages and drops the package there; release2.sh commits and pushes. release-charts.sh drives both and owns the index in between - and that middle part is what changes here.

The index is now rebuilt from the packages instead of being edited. It used to copy the newest entry, substitute a few fields and prepend the result, and all four of the index’s defects came from exactly that. Deriving it makes them impossible rather than fixed: one entry per package, digest computed from the file, fields read out of the archive, and any package that was missed picked up on the next run.

The package is checked against its own filename before it is indexed. release.sh names the tarball from its argument while the version INSIDE comes from the Chart.yaml that was just edited, so when those drift the repository gains a file called one version that declares another - which is how wekan-1.2.7.tgz (containing 1.2.6) and wekan-6.96.tgz (containing 6.9.6) came to exist. Both are now removed, and a package like them stops the release with a message instead of being published.

Release All Missing publishes a chart too. It could rebuild any missing bundle but not a missing chart, so a release that never got one never would - its header even said the charts were out of scope. It has a charts job now, guarded twice: nothing happens without a token that can push to wekan/charts, and nothing happens if the chart for that version is already published, because re-publishing would re-tar the package and change the digest of a chart people have already pulled.

Thanks to above GitHub users for their contributions and translators for their translations.